From d14ac1073cda7ea4f623f312eb469554c3041315 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 3 Sep 2009 11:31:17 +0800 Subject: st/es: Add OpenGL ES state trackers. Signed-off-by: Chia-I Wu --- src/gallium/state_trackers/es/Makefile | 88 ++++++++++++++++++++++++++++++++++ src/gallium/state_trackers/es/st_es1.c | 1 + src/gallium/state_trackers/es/st_es2.c | 1 + 3 files changed, 90 insertions(+) create mode 100644 src/gallium/state_trackers/es/Makefile create mode 100644 src/gallium/state_trackers/es/st_es1.c create mode 100644 src/gallium/state_trackers/es/st_es2.c (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/es/Makefile b/src/gallium/state_trackers/es/Makefile new file mode 100644 index 0000000000..41d4ccb1a6 --- /dev/null +++ b/src/gallium/state_trackers/es/Makefile @@ -0,0 +1,88 @@ +# src/gallium/state_trackers/es/Makefile + +# Build the ES 1/2 state tracker libraries +# This consists of core Mesa ES, plus GL/gallium state tracker. + +TOP = ../../../.. +include $(TOP)/configs/current + +GLES_1_VERSION_MAJOR = 1 +GLES_1_VERSION_MINOR = 1 +GLES_1_VERSION_PATCH = 0 + +GLES_2_VERSION_MAJOR = 2 +GLES_2_VERSION_MINOR = 0 +GLES_2_VERSION_PATCH = 0 + + +# Maybe move these into configs/default: +GLES_1_LIB = GLESv1_CM +GLES_1_LIB_NAME = lib$(GLES_1_LIB).so +GLES_2_LIB = GLESv2 +GLES_2_LIB_NAME = lib$(GLES_2_LIB).so + + +ES1_OBJECTS = st_es1.o +ES2_OBJECTS = st_es2.o + + +# we only need the gallium libs that the state trackers directly use: +GALLIUM_LIBS = \ + $(TOP)/src/gallium/auxiliary/cso_cache/libcso_cache.a \ + $(TOP)/src/gallium/auxiliary/rtasm/librtasm.a \ + $(TOP)/src/gallium/auxiliary/tgsi/libtgsi.a \ + $(TOP)/src/gallium/auxiliary/util/libutil.a + +ES1_LIBS = \ + $(TOP)/src/mesa/es/libes1gallium.a \ + $(TOP)/src/mesa/es/libes1api.a + +ES2_LIBS = \ + $(TOP)/src/mesa/es/libes2gallium.a \ + $(TOP)/src/mesa/es/libes2api.a + +SYS_LIBS = -lm -pthread + + +.c.o: + $(CC) -c $(CFLAGS) $< -o $@ + + +# Default: make both GL ES 1.1 and GL ES 2.0 libraries +default: $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME) + +# Make the shared libs +$(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME): $(ES1_OBJECTS) $(ES1_LIBS) + $(TOP)/bin/mklib -o $(GLES_1_LIB) \ + -major $(GLES_1_VERSION_MAJOR) \ + -minor $(GLES_1_VERSION_MINOR) \ + -patch $(GLES_1_VERSION_PATCH) \ + -install $(TOP)/$(LIB_DIR) \ + $(ES1_OBJECTS) \ + -Wl,--whole-archive $(ES1_LIBS) -Wl,--no-whole-archive \ + -Wl,--start-group $(GALLIUM_LIBS) -Wl,--end-group \ + $(SYS_LIBS) + +$(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME): $(ES2_OBJECTS) $(ES1_LIBS) + $(TOP)/bin/mklib -o $(GLES_2_LIB) \ + -major $(GLES_2_VERSION_MAJOR) \ + -minor $(GLES_2_VERSION_MINOR) \ + -patch $(GLES_2_VERSION_PATCH) \ + -install $(TOP)/$(LIB_DIR) \ + $(ES2_OBJECTS) \ + -Wl,--whole-archive $(ES2_LIBS) -Wl,--no-whole-archive \ + -Wl,--start-group $(GALLIUM_LIBS) -Wl,--end-group \ + $(SYS_LIBS) + +install: default + $(INSTALL) -d $(INSTALL_DIR)/include/GLES + $(INSTALL) -m 644 $(TOP)/include/GLES/*.h $(INSTALL_DIR)/include/GLES + $(INSTALL) -d $(INSTALL_DIR)/include/GLES2 + $(INSTALL) -m 644 $(TOP)/include/GLES2/*.h $(INSTALL_DIR)/include/GLES2 + $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) $(TOP)/$(LIB_DIR)/libGLESv1* $(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) $(TOP)/$(LIB_DIR)/libGLESv2* $(INSTALL_DIR)/$(LIB_DIR) + +clean: + -rm -f *.o *~ + -rm -f $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME)* $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME)* diff --git a/src/gallium/state_trackers/es/st_es1.c b/src/gallium/state_trackers/es/st_es1.c new file mode 100644 index 0000000000..7f0c038957 --- /dev/null +++ b/src/gallium/state_trackers/es/st_es1.c @@ -0,0 +1 @@ +const int st_api_OpenGL_ES1 = 1; diff --git a/src/gallium/state_trackers/es/st_es2.c b/src/gallium/state_trackers/es/st_es2.c new file mode 100644 index 0000000000..78e3791fbe --- /dev/null +++ b/src/gallium/state_trackers/es/st_es2.c @@ -0,0 +1 @@ +const int st_api_OpenGL_ES2 = 1; -- cgit v1.2.3 From 1046f70a7d0592aaf10837ff9d2523de53910a31 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 6 Nov 2009 17:11:43 +0800 Subject: gallium: Allow state trackers to install files. State trackers like es or vega need to install their libraries. Signed-off-by: Chia-I Wu --- src/gallium/state_trackers/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/Makefile b/src/gallium/state_trackers/Makefile index 265ca468c2..0900efc664 100644 --- a/src/gallium/state_trackers/Makefile +++ b/src/gallium/state_trackers/Makefile @@ -21,5 +21,9 @@ clean: rm -f `find . -name depend` -# Dummy install target install: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) $@) || exit 1 ; \ + fi \ + done -- cgit v1.2.3 From 4b9cc50345b5b10bb998ce5ce6f7cb37b72f354f Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 9 Nov 2009 10:54:19 +0800 Subject: st/egl: Allow APIs other than OpenGL. This is done by stopping linking to libmesagallium.a and removing DRI related stuff. The state tracker an application links to decides the API supported. Signed-off-by: Chia-I Wu --- src/gallium/state_trackers/egl/egl_tracker.c | 2 -- src/gallium/winsys/drm/intel/egl/Makefile | 29 ++++++++++++++++++---------- src/gallium/winsys/drm/intel/egl/dummy.c | 1 + src/gallium/winsys/drm/radeon/egl/Makefile | 28 +++++++++++++++++++-------- src/gallium/winsys/drm/radeon/egl/dummy.c | 1 + 5 files changed, 41 insertions(+), 20 deletions(-) create mode 100644 src/gallium/winsys/drm/intel/egl/dummy.c create mode 100644 src/gallium/winsys/drm/radeon/egl/dummy.c (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/egl/egl_tracker.c b/src/gallium/state_trackers/egl/egl_tracker.c index 8d29bf490b..1ad0097786 100644 --- a/src/gallium/state_trackers/egl/egl_tracker.c +++ b/src/gallium/state_trackers/egl/egl_tracker.c @@ -167,8 +167,6 @@ drm_initialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor) goto err_screen; dev->winsys = dev->screen->winsys; - driInitExtensions(NULL, NULL, GL_FALSE); - drm_update_res(dev); res = dev->res; if (res) diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile index 1397e9f729..c9c92b69b6 100644 --- a/src/gallium/winsys/drm/intel/egl/Makefile +++ b/src/gallium/winsys/drm/intel/egl/Makefile @@ -2,7 +2,7 @@ TOP = ../../../../../.. GALLIUMDIR = ../../../.. include $(TOP)/configs/current -LIBNAME = EGL_i915.so +LIBNAME = egl_i915.so PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ @@ -11,19 +11,28 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/i915/libi915.a -DRIVER_SOURCES = +DRIVER_EXTRAS = -lm -lpthread -ldrm_intel -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) +OBJECTS = dummy.o -DRIVER_EXTRAS = -ldrm_intel +default: $(TOP)/$(LIB_DIR)/$(LIBNAME) -ASM_SOURCES = +$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) + @mkdir -p $(TOP)/$(LIB_DIR) + $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) -DRIVER_DEFINES = -I../gem $(shell pkg-config libdrm --atleast-version=2.3.1 \ - && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") +$(LIBNAME): $(OBJECTS) $(GALLIUM_AUXILIARIES) $(PIPE_DRIVERS) Makefile + $(MKLIB) -noprefix -o $@ $(OBJECTS) \ + -Wl,--whole-archive $(PIPE_DRIVERS) -Wl,--no-whole-archive \ + -Wl,--start-group $(GALLIUM_AUXILIARIES) -Wl,--end-group \ + $(DRI_LIB_DEPS) $(DRIVER_EXTRAS) -include ../../Makefile.template +clean: + -rm -f *.o *.so *~ + +depend: symlinks: + +install: $(LIBNAME) + $(MINSTALL) -m 755 $(LIBNAME) $(INSTALL_DIR)/$(LIB_DIR) diff --git a/src/gallium/winsys/drm/intel/egl/dummy.c b/src/gallium/winsys/drm/intel/egl/dummy.c new file mode 100644 index 0000000000..58c7af84e0 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one .o is given */ diff --git a/src/gallium/winsys/drm/radeon/egl/Makefile b/src/gallium/winsys/drm/radeon/egl/Makefile index 6a1448d1b9..2bd05a8175 100644 --- a/src/gallium/winsys/drm/radeon/egl/Makefile +++ b/src/gallium/winsys/drm/radeon/egl/Makefile @@ -2,7 +2,7 @@ TOP = ../../../../../.. GALLIUMDIR = ../../../.. include $(TOP)/configs/current -LIBNAME = EGL_r300.so +LIBNAME = egl_r300.so PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ @@ -11,16 +11,28 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/r300/libr300.a -DRIVER_SOURCES = +DRIVER_EXTRAS = -lm -lpthread -ldrm_radeon -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) +OBJECTS = dummy.o -DRIVER_EXTRAS = -ldrm_radeon +default: $(TOP)/$(LIB_DIR)/$(LIBNAME) -ASM_SOURCES = +$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) + @mkdir -p $(TOP)/$(LIB_DIR) + $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) -include ../../Makefile.template +$(LIBNAME): $(OBJECTS) $(GALLIUM_AUXILIARIES) $(PIPE_DRIVERS) Makefile + $(MKLIB) -noprefix -o $@ $(OBJECTS) \ + -Wl,--whole-archive $(PIPE_DRIVERS) -Wl,--no-whole-archive \ + -Wl,--start-group $(GALLIUM_AUXILIARIES) -Wl,--end-group \ + $(DRI_LIB_DEPS) $(DRIVER_EXTRAS) + +clean: + -rm -f *.o *.so *~ + +depend: symlinks: + +install: $(LIBNAME) + $(MINSTALL) -m 755 $(LIBNAME) $(INSTALL_DIR)/$(LIB_DIR) diff --git a/src/gallium/winsys/drm/radeon/egl/dummy.c b/src/gallium/winsys/drm/radeon/egl/dummy.c new file mode 100644 index 0000000000..58c7af84e0 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one .o is given */ -- cgit v1.2.3 From 182c38281383a3c0798c427b3d1f338dbf1e0533 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 5 Jan 2010 16:15:25 +0800 Subject: st/es: Fix build issue after merge. In c847a13d38d4e8c5f4c386d060dcc8ec09e491a3, auxiliaries becomes a single library; In e388d62b4712bcd75cecad53f5ca20a2bb6f89b1, the default build is changed to have -fvisibility=hidden. Signed-off-by: Chia-I Wu --- src/gallium/state_trackers/es/Makefile | 32 ++++++++++++++------------------ src/gallium/state_trackers/es/st_es1.c | 4 +++- src/gallium/state_trackers/es/st_es2.c | 4 +++- 3 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/es/Makefile b/src/gallium/state_trackers/es/Makefile index 41d4ccb1a6..b8ee0c8387 100644 --- a/src/gallium/state_trackers/es/Makefile +++ b/src/gallium/state_trackers/es/Makefile @@ -26,13 +26,6 @@ ES1_OBJECTS = st_es1.o ES2_OBJECTS = st_es2.o -# we only need the gallium libs that the state trackers directly use: -GALLIUM_LIBS = \ - $(TOP)/src/gallium/auxiliary/cso_cache/libcso_cache.a \ - $(TOP)/src/gallium/auxiliary/rtasm/librtasm.a \ - $(TOP)/src/gallium/auxiliary/tgsi/libtgsi.a \ - $(TOP)/src/gallium/auxiliary/util/libutil.a - ES1_LIBS = \ $(TOP)/src/mesa/es/libes1gallium.a \ $(TOP)/src/mesa/es/libes1api.a @@ -44,35 +37,36 @@ ES2_LIBS = \ SYS_LIBS = -lm -pthread +INCLUDE_DIRS = \ + -I$(TOP)/src/gallium/include + .c.o: - $(CC) -c $(CFLAGS) $< -o $@ + $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@ # Default: make both GL ES 1.1 and GL ES 2.0 libraries default: $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME) # Make the shared libs -$(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME): $(ES1_OBJECTS) $(ES1_LIBS) - $(TOP)/bin/mklib -o $(GLES_1_LIB) \ +$(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME): $(ES1_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXILIARIES) + $(MKLIB) -o $(GLES_1_LIB) \ -major $(GLES_1_VERSION_MAJOR) \ -minor $(GLES_1_VERSION_MINOR) \ -patch $(GLES_1_VERSION_PATCH) \ - -install $(TOP)/$(LIB_DIR) \ + -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ $(ES1_OBJECTS) \ -Wl,--whole-archive $(ES1_LIBS) -Wl,--no-whole-archive \ - -Wl,--start-group $(GALLIUM_LIBS) -Wl,--end-group \ - $(SYS_LIBS) + $(GALLIUM_AUXILIARIES) $(SYS_LIBS) -$(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME): $(ES2_OBJECTS) $(ES1_LIBS) - $(TOP)/bin/mklib -o $(GLES_2_LIB) \ +$(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME): $(ES2_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXILIARIES) + $(MKLIB) -o $(GLES_2_LIB) \ -major $(GLES_2_VERSION_MAJOR) \ -minor $(GLES_2_VERSION_MINOR) \ -patch $(GLES_2_VERSION_PATCH) \ - -install $(TOP)/$(LIB_DIR) \ + -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ $(ES2_OBJECTS) \ -Wl,--whole-archive $(ES2_LIBS) -Wl,--no-whole-archive \ - -Wl,--start-group $(GALLIUM_LIBS) -Wl,--end-group \ - $(SYS_LIBS) + $(GALLIUM_AUXILIARIES) $(SYS_LIBS) install: default $(INSTALL) -d $(INSTALL_DIR)/include/GLES @@ -86,3 +80,5 @@ install: default clean: -rm -f *.o *~ -rm -f $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME)* $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME)* + +depend: diff --git a/src/gallium/state_trackers/es/st_es1.c b/src/gallium/state_trackers/es/st_es1.c index 7f0c038957..25bc53b21e 100644 --- a/src/gallium/state_trackers/es/st_es1.c +++ b/src/gallium/state_trackers/es/st_es1.c @@ -1 +1,3 @@ -const int st_api_OpenGL_ES1 = 1; +#include "pipe/p_compiler.h" + +PUBLIC const int st_api_OpenGL_ES1 = 1; diff --git a/src/gallium/state_trackers/es/st_es2.c b/src/gallium/state_trackers/es/st_es2.c index 78e3791fbe..171ea62b97 100644 --- a/src/gallium/state_trackers/es/st_es2.c +++ b/src/gallium/state_trackers/es/st_es2.c @@ -1 +1,3 @@ -const int st_api_OpenGL_ES2 = 1; +#include "pipe/p_compiler.h" + +PUBLIC const int st_api_OpenGL_ES2 = 1; -- cgit v1.2.3 From 3f3340ca16a07aff26a3bd27a7f5ae161d77b11d Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 11 Jan 2010 17:44:00 +0800 Subject: st/es: Clean up install target. Use DESTDIR and MINSTALL. Signed-off-by: Chia-I Wu --- src/gallium/state_trackers/es/Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/es/Makefile b/src/gallium/state_trackers/es/Makefile index b8ee0c8387..095ffbb938 100644 --- a/src/gallium/state_trackers/es/Makefile +++ b/src/gallium/state_trackers/es/Makefile @@ -69,13 +69,13 @@ $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME): $(ES2_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXIL $(GALLIUM_AUXILIARIES) $(SYS_LIBS) install: default - $(INSTALL) -d $(INSTALL_DIR)/include/GLES - $(INSTALL) -m 644 $(TOP)/include/GLES/*.h $(INSTALL_DIR)/include/GLES - $(INSTALL) -d $(INSTALL_DIR)/include/GLES2 - $(INSTALL) -m 644 $(TOP)/include/GLES2/*.h $(INSTALL_DIR)/include/GLES2 - $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) - $(INSTALL) $(TOP)/$(LIB_DIR)/libGLESv1* $(INSTALL_DIR)/$(LIB_DIR) - $(INSTALL) $(TOP)/$(LIB_DIR)/libGLESv2* $(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES + $(INSTALL) -m 644 $(TOP)/include/GLES/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES2 + $(INSTALL) -m 644 $(TOP)/include/GLES2/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES2 + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/libGLESv1* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/libGLESv2* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) clean: -rm -f *.o *~ -- cgit v1.2.3 From 5f2d60a7154f896bb418231662663465269ce9b8 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 18 Jan 2010 13:33:08 +0100 Subject: st/dri: Don't request a fake front if the server adds one automatically. We use the presence of the getBuffersWithFormat extension function to detect whether the server automatically adds a front. Signed-off-by: Thomas Hellstrom --- src/gallium/state_trackers/dri/dri_drawable.c | 12 +++++++----- src/gallium/state_trackers/dri/dri_screen.c | 5 +++++ src/gallium/state_trackers/dri/dri_screen.h | 1 + 3 files changed, 13 insertions(+), 5 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index 3c17ccde0a..0a8c1cd361 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -123,11 +123,12 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv) struct dri_drawable *drawable = dri_drawable(dPriv); struct pipe_surface *surface = NULL; - struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen; + struct dri_screen *st_screen = dri_screen(drawable->sPriv); + struct pipe_screen *screen = st_screen->pipe_screen; __DRIbuffer *buffers = NULL; __DRIscreen *dri_screen = drawable->sPriv; __DRIdrawable *dri_drawable = drawable->dPriv; - struct drm_api *api = ((struct dri_screen*)(dri_screen->private))->api; + struct drm_api *api = st_screen->api; boolean have_depth = FALSE; int i, count; @@ -180,7 +181,8 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv) switch (buffers[i].attachment) { case __DRI_BUFFER_FRONT_LEFT: - continue; + if (!st_screen->auto_fake_front) + continue; case __DRI_BUFFER_FAKE_FRONT_LEFT: index = ST_SURFACE_FRONT_LEFT; format = drawable->color_format; @@ -365,8 +367,8 @@ dri_create_buffer(__DRIscreenPrivate * sPriv, /* TODO incase of double buffer visual, delay fake creation */ i = 0; drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT; - drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; - + if (!screen->auto_fake_front) + drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; if (visual->doubleBufferMode) drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT; if (visual->depthBits && visual->stencilBits) diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index cb864d45d5..11ea28bcbe 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -289,6 +289,8 @@ dri_init_screen2(__DRIscreenPrivate * sPriv) { struct dri_screen *screen; struct drm_create_screen_arg arg; + const __DRIdri2LoaderExtension *dri2_ext = + sPriv->dri2.loader; screen = CALLOC_STRUCT(dri_screen); if (!screen) @@ -313,6 +315,9 @@ dri_init_screen2(__DRIscreenPrivate * sPriv) driParseOptionInfo(&screen->optionCache, __driConfigOptions, __driNConfigOptions); + screen->auto_fake_front = dri2_ext->base.version >= 3 && + dri2_ext->getBuffersWithFormat != NULL; + return dri_fill_in_modes(screen, 32); fail: return NULL; diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h index f6c56d0f0c..10319f808b 100644 --- a/src/gallium/state_trackers/dri/dri_screen.h +++ b/src/gallium/state_trackers/dri/dri_screen.h @@ -59,6 +59,7 @@ struct dri_screen struct pipe_screen *pipe_screen; boolean d_depth_bits_last; boolean sd_depth_bits_last; + boolean auto_fake_front; }; /** cast wrapper */ -- cgit v1.2.3 From 3e1241d4f872cca96616edcbdcaea5b59d37e78f Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 15 Jan 2010 01:14:55 +0000 Subject: st/xorg: Set enforce version to 1 if not defined --- src/gallium/state_trackers/xorg/xorg_dri2.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 4fa47548a4..4f03dbae74 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -43,9 +43,8 @@ #include "util/u_rect.h" /* Make all the #if cases in the code esier to read */ -/* XXX can it be set to 1? */ #ifndef DRI2INFOREC_VERSION -#define DRI2INFOREC_VERSION 0 +#define DRI2INFOREC_VERSION 1 #endif typedef struct { @@ -370,11 +369,7 @@ xorg_dri2_init(ScreenPtr pScreen) modesettingPtr ms = modesettingPTR(pScrn); DRI2InfoRec dri2info; -#if DRI2INFOREC_VERSION >= 2 dri2info.version = DRI2INFOREC_VERSION; -#else - dri2info.version = 1; -#endif dri2info.fd = ms->fd; dri2info.driverName = pScrn->driverName; -- cgit v1.2.3 From ccc888c39ee8a7c460dca5b1b659d28dbbc4c689 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 15 Jan 2010 01:29:13 +0000 Subject: st/xorg: If dri2 version is 2 support version 1 as well Thanks to X server commit 2e2c5b216cc1c7a9bc26bd2c68226aaed5fc52ca it is possible to be ABI compatible in version 2 with version 1 of the DRI2 interface. --- src/gallium/state_trackers/xorg/xorg_dri2.c | 40 ++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 4f03dbae74..8267da309f 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -47,6 +47,10 @@ #define DRI2INFOREC_VERSION 1 #endif +#if DRI2INFOREC_VERSION == 2 +static Bool set_format_in_do_create_buffer; +#endif + typedef struct { PixmapPtr pPixmap; struct pipe_texture *tex; @@ -146,7 +150,9 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form buffer->driverPrivate = private; buffer->flags = 0; /* not tiled */ #if DRI2INFOREC_VERSION == 2 - ((DRI2Buffer2Ptr)buffer)->format = 0; + /* ABI forwards/backwards compatibility */ + if (set_format_in_do_create_buffer) + ((DRI2Buffer2Ptr)buffer)->format = 0; #elif DRI2INFOREC_VERSION >= 3 buffer->format = 0; #endif @@ -210,7 +216,9 @@ dri2_destroy_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer) xfree(buffer); } -#else /* DRI2INFOREC_VERSION < 2 */ +#endif /* DRI2INFOREC_VERSION >= 2 */ + +#if DRI2INFOREC_VERSION <= 2 static DRI2BufferPtr dri2_create_buffers(DrawablePtr pDraw, unsigned int *attachments, int count) @@ -260,7 +268,7 @@ dri2_destroy_buffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) } } -#endif /* DRI2INFOREC_VERSION >= 2 */ +#endif /* DRI2INFOREC_VERSION <= 2 */ static void dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, @@ -368,6 +376,15 @@ xorg_dri2_init(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); DRI2InfoRec dri2info; + int major, minor; + + if (xf86LoaderCheckSymbol("DRI2Version")) { + DRI2Version(&major, &minor); + } else { + /* Assume version 1.0 */ + major = 1; + minor = 0; + } dri2info.version = DRI2INFOREC_VERSION; dri2info.fd = ms->fd; @@ -378,7 +395,22 @@ xorg_dri2_init(ScreenPtr pScreen) #if DRI2INFOREC_VERSION >= 2 dri2info.CreateBuffer = dri2_create_buffer; dri2info.DestroyBuffer = dri2_destroy_buffer; -#else +#endif + + /* For X servers in the 1.6.x series there where two DRI2 version. + * This allows us to build one binary that works on both servers. + */ +#if DRI2INFOREC_VERSION == 2 + if (minor == 0) { + set_format_in_do_create_buffer = FALSE; + dri2info.CreateBuffers = dri2_create_buffers; + dri2info.DestroyBuffers = dri2_destroy_buffers; + } else + set_format_in_do_create_buffer = FALSE; +#endif + + /* For version 1 set these unconditionaly. */ +#if DRI2INFOREC_VERSION == 1 dri2info.CreateBuffers = dri2_create_buffers; dri2info.DestroyBuffers = dri2_destroy_buffers; #endif -- cgit v1.2.3 From 0e4e2c57d1b5659ba4fce2f9077fb6d4c7fd18d5 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sun, 17 Jan 2010 16:24:53 +0000 Subject: st/xlib: Make glXGetProcAddressARB visible --- src/gallium/state_trackers/glx/xlib/glx_getproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/glx/xlib/glx_getproc.c b/src/gallium/state_trackers/glx/xlib/glx_getproc.c index 84d47b12ed..bd4a85caa0 100644 --- a/src/gallium/state_trackers/glx/xlib/glx_getproc.c +++ b/src/gallium/state_trackers/glx/xlib/glx_getproc.c @@ -193,7 +193,7 @@ _glxapi_get_proc_address(const char *funcName) } -__GLXextFuncPtr +PUBLIC __GLXextFuncPtr glXGetProcAddressARB(const GLubyte *procName) { __GLXextFuncPtr f; -- cgit v1.2.3 From a4bbabf494a127dcffc51f9c4734f2ecf75b3961 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sun, 17 Jan 2010 14:18:26 +0000 Subject: softpipe: Move st/python's malloc winsys to softpipe Users of softpipe can still specify thier own winsys but now there is a default one also that uses malloc. This allows the malloc winsys to be shared with other users of softpipe. --- src/gallium/drivers/softpipe/Makefile | 3 +- src/gallium/drivers/softpipe/SConscript | 1 + src/gallium/drivers/softpipe/sp_winsys.c | 245 +++++++++++++++++++++ src/gallium/drivers/softpipe/sp_winsys.h | 13 +- .../state_trackers/python/st_softpipe_winsys.c | 219 +----------------- 5 files changed, 260 insertions(+), 221 deletions(-) create mode 100644 src/gallium/drivers/softpipe/sp_winsys.c (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index bcb887a0b2..e4ac49fa85 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -32,6 +32,7 @@ C_SOURCES = \ sp_tex_tile_cache.c \ sp_tile_cache.c \ sp_surface.c \ - sp_video_context.c + sp_video_context.c \ + sp_winsys.c include ../../Makefile.template diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index aac9edf44e..3042e556c6 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -34,6 +34,7 @@ softpipe = env.ConvenienceLibrary( 'sp_texture.c', 'sp_tile_cache.c', 'sp_video_context.c', + 'sp_winsys.c' ]) Export('softpipe') diff --git a/src/gallium/drivers/softpipe/sp_winsys.c b/src/gallium/drivers/softpipe/sp_winsys.c new file mode 100644 index 0000000000..8169071dc9 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_winsys.c @@ -0,0 +1,245 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 + * Malloc softpipe winsys. Uses malloc for all memory allocations. + * + * @author Keith Whitwell + * @author Brian Paul + * @author Jose Fonseca + */ + + +#include "pipe/internal/p_winsys_screen.h"/* port to just p_screen */ +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_inlines.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "softpipe/sp_winsys.h" + + +struct st_softpipe_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; +}; + + +/** Cast wrapper */ +static INLINE struct st_softpipe_buffer * +st_softpipe_buffer( struct pipe_buffer *buf ) +{ + return (struct st_softpipe_buffer *)buf; +} + + +static void * +st_softpipe_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags) +{ + struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); + st_softpipe_buf->mapped = st_softpipe_buf->data; + return st_softpipe_buf->mapped; +} + + +static void +st_softpipe_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); + st_softpipe_buf->mapped = NULL; +} + + +static void +st_softpipe_buffer_destroy(struct pipe_buffer *buf) +{ + struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf); + + if (oldBuf->data) { + if (!oldBuf->userBuffer) + align_free(oldBuf->data); + + oldBuf->data = NULL; + } + + FREE(oldBuf); +} + + +static void +st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ +} + + + +static const char * +st_softpipe_get_name(struct pipe_winsys *winsys) +{ + return "softpipe"; +} + + +static struct pipe_buffer * +st_softpipe_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer); + + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + buffer->data = align_malloc(size, alignment); + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +st_softpipe_user_buffer_create(struct pipe_winsys *winsys, + void *ptr, + unsigned bytes) +{ + struct st_softpipe_buffer *buffer; + + buffer = CALLOC_STRUCT(st_softpipe_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 struct pipe_buffer * +st_softpipe_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 +st_softpipe_fence_reference(struct pipe_winsys *winsys, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +st_softpipe_fence_signalled(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +st_softpipe_fence_finish(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static void +st_softpipe_destroy(struct pipe_winsys *winsys) +{ + FREE(winsys); +} + + +struct pipe_screen * +softpipe_create_screen_malloc(void) +{ + static struct pipe_winsys *winsys; + struct pipe_screen *screen; + + winsys = CALLOC_STRUCT(pipe_winsys); + if(!winsys) + return NULL; + + winsys->destroy = st_softpipe_destroy; + + winsys->buffer_create = st_softpipe_buffer_create; + winsys->user_buffer_create = st_softpipe_user_buffer_create; + winsys->buffer_map = st_softpipe_buffer_map; + winsys->buffer_unmap = st_softpipe_buffer_unmap; + winsys->buffer_destroy = st_softpipe_buffer_destroy; + + winsys->surface_buffer_create = st_softpipe_surface_buffer_create; + + winsys->fence_reference = st_softpipe_fence_reference; + winsys->fence_signalled = st_softpipe_fence_signalled; + winsys->fence_finish = st_softpipe_fence_finish; + + winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer; + winsys->get_name = st_softpipe_get_name; + + screen = softpipe_create_screen(winsys); + if(!screen) + st_softpipe_destroy(winsys); + + return screen; +} diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h index f203ded29e..3042e01a05 100644 --- a/src/gallium/drivers/softpipe/sp_winsys.h +++ b/src/gallium/drivers/softpipe/sp_winsys.h @@ -49,10 +49,17 @@ struct pipe_buffer; struct pipe_context *softpipe_create( struct pipe_screen * ); +/** + * Create a softpipe screen that uses the + * given winsys for allocating buffers. + */ +struct pipe_screen *softpipe_create_screen( struct pipe_winsys * ); -struct pipe_screen * -softpipe_create_screen(struct pipe_winsys *); - +/** + * Create a softpipe screen that uses + * regular malloc to create all its buffers. + */ +struct pipe_screen *softpipe_create_screen_malloc(void); boolean softpipe_get_texture_buffer( struct pipe_texture *texture, diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c index a3294e877a..dfe3e465f7 100644 --- a/src/gallium/state_trackers/python/st_softpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c @@ -35,225 +35,10 @@ * @author Jose Fonseca */ - -#include "pipe/internal/p_winsys_screen.h"/* port to just p_screen */ -#include "pipe/p_format.h" -#include "pipe/p_context.h" -#include "pipe/p_inlines.h" -#include "util/u_format.h" -#include "util/u_math.h" -#include "util/u_memory.h" #include "softpipe/sp_winsys.h" #include "st_winsys.h" - -struct st_softpipe_buffer -{ - struct pipe_buffer base; - boolean userBuffer; /** Is this a user-space buffer? */ - void *data; - void *mapped; -}; - - -/** Cast wrapper */ -static INLINE struct st_softpipe_buffer * -st_softpipe_buffer( struct pipe_buffer *buf ) -{ - return (struct st_softpipe_buffer *)buf; -} - - -static void * -st_softpipe_buffer_map(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned flags) -{ - struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); - st_softpipe_buf->mapped = st_softpipe_buf->data; - return st_softpipe_buf->mapped; -} - - -static void -st_softpipe_buffer_unmap(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); - st_softpipe_buf->mapped = NULL; -} - - -static void -st_softpipe_buffer_destroy(struct pipe_buffer *buf) -{ - struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf); - - if (oldBuf->data) { - if (!oldBuf->userBuffer) - align_free(oldBuf->data); - - oldBuf->data = NULL; - } - - FREE(oldBuf); -} - - -static void -st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, - struct pipe_surface *surf, - void *context_private) -{ -} - - - -static const char * -st_softpipe_get_name(struct pipe_winsys *winsys) -{ - return "softpipe"; -} - - -static struct pipe_buffer * -st_softpipe_buffer_create(struct pipe_winsys *winsys, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer); - - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.alignment = alignment; - buffer->base.usage = usage; - buffer->base.size = size; - - buffer->data = align_malloc(size, alignment); - - return &buffer->base; -} - - -/** - * Create buffer which wraps user-space data. - */ -static struct pipe_buffer * -st_softpipe_user_buffer_create(struct pipe_winsys *winsys, - void *ptr, - unsigned bytes) -{ - struct st_softpipe_buffer *buffer; - - buffer = CALLOC_STRUCT(st_softpipe_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 struct pipe_buffer * -st_softpipe_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 -st_softpipe_fence_reference(struct pipe_winsys *winsys, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence) -{ -} - - -static int -st_softpipe_fence_signalled(struct pipe_winsys *winsys, - struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - -static int -st_softpipe_fence_finish(struct pipe_winsys *winsys, - struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - -static void -st_softpipe_destroy(struct pipe_winsys *winsys) -{ - FREE(winsys); -} - - -static struct pipe_screen * -st_softpipe_screen_create(void) -{ - static struct pipe_winsys *winsys; - struct pipe_screen *screen; - - winsys = CALLOC_STRUCT(pipe_winsys); - if(!winsys) - return NULL; - - winsys->destroy = st_softpipe_destroy; - - winsys->buffer_create = st_softpipe_buffer_create; - winsys->user_buffer_create = st_softpipe_user_buffer_create; - winsys->buffer_map = st_softpipe_buffer_map; - winsys->buffer_unmap = st_softpipe_buffer_unmap; - winsys->buffer_destroy = st_softpipe_buffer_destroy; - - winsys->surface_buffer_create = st_softpipe_surface_buffer_create; - - winsys->fence_reference = st_softpipe_fence_reference; - winsys->fence_signalled = st_softpipe_fence_signalled; - winsys->fence_finish = st_softpipe_fence_finish; - - winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer; - winsys->get_name = st_softpipe_get_name; - - screen = softpipe_create_screen(winsys); - if(!screen) - st_softpipe_destroy(winsys); - - return screen; -} - - -static struct pipe_context * -st_softpipe_context_create(struct pipe_screen *screen) -{ - return softpipe_create(screen); -} - - const struct st_winsys st_softpipe_winsys = { - &st_softpipe_screen_create, - &st_softpipe_context_create, + &softpipe_create_screen_malloc, + &softpipe_create, }; -- cgit v1.2.3 From ef517c9385521f6e46a1f56ef6817518434ca349 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 15 Jan 2010 17:52:10 +0800 Subject: st/vega: Call screen->update_buffer instead of winsys->update_buffer. This removes the last reference to winsys and is per mesa/st. --- src/gallium/state_trackers/vega/api_masks.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c index 4f9f3dae17..97cbe69205 100644 --- a/src/gallium/state_trackers/vega/api_masks.c +++ b/src/gallium/state_trackers/vega/api_masks.c @@ -32,7 +32,6 @@ #include "vg_context.h" #include "pipe/p_context.h" #include "pipe/p_inlines.h" -#include "pipe/internal/p_winsys_screen.h" /* for winsys->update_buffer */ #include "util/u_pack_color.h" #include "util/u_draw_quad.h" @@ -116,8 +115,8 @@ clear_with_quad(struct vg_context *st, float x0, float y0, x1, y1); */ - if (st->pipe->winsys && st->pipe->winsys->update_buffer) - st->pipe->winsys->update_buffer( st->pipe->winsys, + if (st->pipe->screen && st->pipe->screen->update_buffer) + st->pipe->screen->update_buffer( st->pipe->screen, st->pipe->priv ); cso_save_blend(st->cso_context); -- cgit v1.2.3 From 1ed63119452396e764a0f5b11db78903a2594df1 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 18 Jan 2010 12:05:25 +0800 Subject: st/vega: Fix window resizing with egl_g3d. egl_g3d calls st_set_framebuffer_surface on window resize. It updates the renderbuffer's geometry and makes st_resize_framebuffer a no-op. This commit improves the no-op check a little bit. It can do better after gallium-fb-dimensions is merged. --- src/gallium/state_trackers/vega/vg_context.h | 2 +- src/gallium/state_trackers/vega/vg_tracker.c | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h index ff8c1a0421..bc88c8d139 100644 --- a/src/gallium/state_trackers/vega/vg_context.h +++ b/src/gallium/state_trackers/vega/vg_context.h @@ -50,7 +50,7 @@ struct st_renderbuffer { }; struct st_framebuffer { - VGint init_width, init_height; + VGint width, height; struct st_renderbuffer *strb; struct st_renderbuffer *dsrb; diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c index ff80aab03a..617c174eb6 100644 --- a/src/gallium/state_trackers/vega/vg_tracker.c +++ b/src/gallium/state_trackers/vega/vg_tracker.c @@ -193,8 +193,8 @@ struct st_framebuffer * st_create_framebuffer(const void *visual, */ stfb->alpha_mask = 0; - stfb->init_width = width; - stfb->init_height = height; + stfb->width = width; + stfb->height = height; stfb->privateData = privateData; } @@ -282,11 +282,14 @@ void st_resize_framebuffer(struct st_framebuffer *stfb, /* If this is a noop, exit early and don't do the clear, etc below. */ - if (strb->width == width && - strb->height == height && + if (stfb->width == width && + stfb->height == height && state->zsbuf) return; + stfb->width = width; + stfb->height = height; + if (strb->width != width || strb->height != height) st_renderbuffer_alloc_storage(ctx, strb, width, height); -- cgit v1.2.3 From fda897ad71738dd76a218280fd2e635d5dcdcee1 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 18 Jan 2010 12:11:15 +0800 Subject: st/egl_g3d: Update validate to use an attachment mask. A validate call asks for the buffers of a native surface. Using a mask to represent the interested buffers is more intuitive. It also rules out corner cases such as a single attachment being listed multiple times. --- .../state_trackers/egl_g3d/common/egl_g3d.c | 51 ++++++------- .../state_trackers/egl_g3d/common/egl_g3d.h | 4 +- src/gallium/state_trackers/egl_g3d/common/native.h | 29 ++++--- .../state_trackers/egl_g3d/kms/native_kms.c | 29 ++++--- .../state_trackers/egl_g3d/x11/native_dri2.c | 89 +++++++++++----------- .../state_trackers/egl_g3d/x11/native_ximage.c | 43 ++++------- 6 files changed, 116 insertions(+), 129 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c index 51da8e19f5..08f796d083 100644 --- a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c @@ -44,8 +44,13 @@ egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx) struct egl_g3d_display *gdpy = egl_g3d_display(dpy); struct pipe_screen *screen = gdpy->native->screen; struct egl_g3d_context *gctx = egl_g3d_context(ctx); - EGLint num_surfaces; - EGLint s, i; + const uint st_att_map[NUM_NATIVE_ATTACHMENTS] = { + ST_SURFACE_FRONT_LEFT, + ST_SURFACE_BACK_LEFT, + ST_SURFACE_FRONT_RIGHT, + ST_SURFACE_BACK_RIGHT, + }; + EGLint num_surfaces, s; /* validate draw and/or read buffers */ num_surfaces = (gctx->base.ReadSurface == gctx->base.DrawSurface) ? 1 : 2; @@ -53,6 +58,7 @@ egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx) struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; struct egl_g3d_surface *gsurf; struct egl_g3d_buffer *gbuf; + EGLint att; if (s == 0) { gsurf = egl_g3d_surface(gctx->base.DrawSurface); @@ -66,30 +72,31 @@ egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx) if (!gctx->force_validate) { unsigned int seq_num; - gsurf->native->validate(gsurf->native, - gbuf->native_atts, gbuf->num_atts, + gsurf->native->validate(gsurf->native, gbuf->attachment_mask, &seq_num, NULL, NULL, NULL); /* skip validation */ if (gsurf->sequence_number == seq_num) continue; } - gsurf->native->validate(gsurf->native, - gbuf->native_atts, gbuf->num_atts, + pipe_surface_reference(&gsurf->render_surface, NULL); + memset(textures, 0, sizeof(textures)); + + gsurf->native->validate(gsurf->native, gbuf->attachment_mask, &gsurf->sequence_number, textures, &gsurf->base.Width, &gsurf->base.Height); - for (i = 0; i < gbuf->num_atts; i++) { - struct pipe_texture *pt = textures[i]; + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + struct pipe_texture *pt = textures[att]; struct pipe_surface *ps; - if (pt) { + if (native_attachment_mask_test(gbuf->attachment_mask, att) && pt) { ps = screen->get_tex_surface(screen, pt, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE); gctx->stapi->st_set_framebuffer_surface(gbuf->st_fb, - gbuf->st_atts[i], ps); + st_att_map[att], ps); - if (gbuf->native_atts[i] == gsurf->render_att) + if (gsurf->render_att == att) pipe_surface_reference(&gsurf->render_surface, ps); pipe_surface_reference(&ps, NULL); @@ -128,13 +135,7 @@ static void egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx) { struct egl_g3d_context *gctx = egl_g3d_context(ctx); - const uint st_att_map[NUM_NATIVE_ATTACHMENTS] = { - ST_SURFACE_FRONT_LEFT, - ST_SURFACE_BACK_LEFT, - ST_SURFACE_FRONT_RIGHT, - ST_SURFACE_BACK_RIGHT, - }; - EGLint s, i; + EGLint s; /* route draw and read buffers' attachments */ for (s = 0; s < 2; s++) { @@ -150,11 +151,7 @@ egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx) gbuf = &gctx->read; } - gbuf->native_atts[0] = gsurf->render_att; - gbuf->num_atts = 1; - - for (i = 0; i < gbuf->num_atts; i++) - gbuf->st_atts[i] = st_att_map[gbuf->native_atts[i]]; + gbuf->attachment_mask = (1 << gsurf->render_att); /* FIXME OpenGL defaults to draw the front or back buffer when the * context is single-buffered or double-buffered respectively. In EGL, @@ -196,19 +193,19 @@ egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx) if (!gdraw || priv != (void *) &gdraw->base) { gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb); gctx->draw.st_fb = NULL; - gctx->draw.num_atts = 0; + gctx->draw.attachment_mask = 0x0; } if (is_equal) { gctx->read.st_fb = NULL; - gctx->draw.num_atts = 0; + gctx->draw.attachment_mask = 0x0; } else { priv = gctx->stapi->st_framebuffer_private(gctx->read.st_fb); if (!gread || priv != (void *) &gread->base) { gctx->stapi->st_unreference_framebuffer(gctx->read.st_fb); gctx->read.st_fb = NULL; - gctx->draw.num_atts = 0; + gctx->draw.attachment_mask = 0x0; } } } @@ -628,7 +625,7 @@ init_surface_geometry(_EGLSurface *surf) { struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - return gsurf->native->validate(gsurf->native, NULL, 0, + return gsurf->native->validate(gsurf->native, 0x0, &gsurf->sequence_number, NULL, &gsurf->base.Width, &gsurf->base.Height); } diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h index 4c8b8dfe9e..1da8af495b 100644 --- a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h +++ b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h @@ -52,9 +52,7 @@ struct egl_g3d_display { struct egl_g3d_buffer { struct st_framebuffer *st_fb; - EGLint num_atts; - enum native_attachment native_atts[NUM_NATIVE_ATTACHMENTS]; - uint st_atts[NUM_NATIVE_ATTACHMENTS]; + uint attachment_mask; }; struct egl_g3d_context { diff --git a/src/gallium/state_trackers/egl_g3d/common/native.h b/src/gallium/state_trackers/egl_g3d/common/native.h index 76f0e0c78a..6cd161bdf6 100644 --- a/src/gallium/state_trackers/egl_g3d/common/native.h +++ b/src/gallium/state_trackers/egl_g3d/common/native.h @@ -64,18 +64,18 @@ struct native_surface { boolean (*flush_frontbuffer)(struct native_surface *nsurf); /** - * Validate the buffers of the surface. The returned textures are owned by - * the caller. A sequence number is also returned. The caller can use it - * to check if anything has changed since the last call. Any of the pointers - * may be NULL and it indicates the caller has no interest in those values. + * Validate the buffers of the surface. textures, if not NULL, points to an + * array of size NUM_NATIVE_ATTACHMENTS and the returned textures are owned + * by the caller. A sequence number is also returned. The caller can use + * it to check if anything has changed since the last call. Any of the + * pointers may be NULL and it indicates the caller has no interest in those + * values. * - * If this function is called multiple times with different attachments, - * those not listed in the latest call might be destroyed. This behavior - * might change in the future. + * If this function is called multiple times with different attachment + * masks, those not listed in the latest call might be destroyed. This + * behavior might change in the future. */ - boolean (*validate)(struct native_surface *nsurf, - const enum native_attachment *natts, - unsigned num_natts, + boolean (*validate)(struct native_surface *nsurf, uint attachment_mask, unsigned int *seq_num, struct pipe_texture **textures, int *width, int *height); @@ -211,6 +211,15 @@ struct native_display_modeset { const struct native_mode *nmode); }; +/** + * Test whether an attachment is set in the mask. + */ +static INLINE boolean +native_attachment_mask_test(uint mask, enum native_attachment att) +{ + return !!(mask & (1 << att)); +} + const char * native_get_name(void); diff --git a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c index 65829fc7b3..dc66436630 100644 --- a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c +++ b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c @@ -33,9 +33,7 @@ #include "native_kms.h" static boolean -kms_surface_validate(struct native_surface *nsurf, - const enum native_attachment *natts, - unsigned num_natts, +kms_surface_validate(struct native_surface *nsurf, uint attachment_mask, unsigned int *seq_num, struct pipe_texture **textures, int *width, int *height) { @@ -43,12 +41,9 @@ kms_surface_validate(struct native_surface *nsurf, struct kms_display *kdpy = ksurf->kdpy; struct pipe_screen *screen = kdpy->base.screen; struct pipe_texture templ, *ptex; - int i; - - if (num_natts) { - if (textures) - memset(textures, 0, sizeof(*textures) * num_natts); + int att; + if (attachment_mask) { memset(&templ, 0, sizeof(templ)); templ.target = PIPE_TEXTURE_2D; templ.last_level = 0; @@ -62,17 +57,21 @@ kms_surface_validate(struct native_surface *nsurf, } /* create textures */ - for (i = 0; i < num_natts; i++) { - enum native_attachment natt = natts[i]; + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + /* delay the allocation */ + if (!native_attachment_mask_test(attachment_mask, att)) + continue; - ptex = ksurf->textures[natt]; + ptex = ksurf->textures[att]; if (!ptex) { ptex = screen->texture_create(screen, &templ); - ksurf->textures[natt] = ptex; + ksurf->textures[att] = ptex; } - if (textures) - pipe_texture_reference(&textures[i], ptex); + if (textures) { + textures[att] = NULL; + pipe_texture_reference(&textures[att], ptex); + } } if (seq_num) @@ -113,7 +112,7 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back) if (!fb->texture) { /* make sure the texture has been allocated */ - kms_surface_validate(&ksurf->base, &natt, 1, NULL, NULL, NULL, NULL); + kms_surface_validate(&ksurf->base, 1 << natt, NULL, NULL, NULL, NULL); if (!ksurf->textures[natt]) return FALSE; diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c b/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c index f497d8c1c7..f675a8e686 100644 --- a/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c +++ b/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c @@ -134,22 +134,18 @@ dri2_surface_swap_buffers(struct native_surface *nsurf) } static boolean -dri2_surface_validate(struct native_surface *nsurf, - const enum native_attachment *natts, - unsigned num_natts, - unsigned int *seq_num, - struct pipe_texture **textures, - int *width, int *height) +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); struct dri2_display *dri2dpy = dri2surf->dri2dpy; unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS]; - EGLint texture_indices[NUM_NATIVE_ATTACHMENTS]; struct pipe_texture templ; struct x11_drawable_buffer *xbufs; - int num_ins, num_outs, i; + int num_ins, num_outs, att, i; - if (num_natts) { + if (attachment_mask) { memset(&templ, 0, sizeof(templ)); templ.target = PIPE_TEXTURE_2D; templ.last_level = 0; @@ -160,24 +156,27 @@ dri2_surface_validate(struct native_surface *nsurf, templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; if (textures) - memset(textures, 0, sizeof(*textures) * num_natts); + 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 (i = 0; i < num_natts; i++) { - enum native_attachment natt = natts[i]; - struct pipe_texture *ptex = dri2surf->pbuffer_textures[natt]; + 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[natt] = ptex; + dri2surf->pbuffer_textures[att] = ptex; } if (textures) - pipe_texture_reference(&textures[i], ptex); + pipe_texture_reference(&textures[att], ptex); } if (seq_num) @@ -190,34 +189,34 @@ dri2_surface_validate(struct native_surface *nsurf, return TRUE; } - for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) - texture_indices[i] = -1; - /* prepare the attachments */ - num_ins = num_natts; - for (i = 0; i < num_natts; i++) { - unsigned int dri2att; + num_ins = 0; + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + if (native_attachment_mask_test(attachment_mask, att)) { + unsigned int dri2att; + + switch (att) { + case NATIVE_ATTACHMENT_FRONT_LEFT: + dri2att = DRI2BufferFrontLeft; + break; + case NATIVE_ATTACHMENT_BACK_LEFT: + dri2att = DRI2BufferBackLeft; + break; + case NATIVE_ATTACHMENT_FRONT_RIGHT: + dri2att = DRI2BufferFrontRight; + break; + case NATIVE_ATTACHMENT_BACK_RIGHT: + dri2att = DRI2BufferBackRight; + break; + default: + assert(0); + dri2att = 0; + break; + } - switch (natts[i]) { - case NATIVE_ATTACHMENT_FRONT_LEFT: - dri2att = DRI2BufferFrontLeft; - break; - case NATIVE_ATTACHMENT_BACK_LEFT: - dri2att = DRI2BufferBackLeft; - break; - case NATIVE_ATTACHMENT_FRONT_RIGHT: - dri2att = DRI2BufferFrontRight; - break; - case NATIVE_ATTACHMENT_BACK_RIGHT: - dri2att = DRI2BufferBackRight; - break; - default: - assert(0); - dri2att = 0; - break; + dri2atts[num_ins] = dri2att; + num_ins++; } - dri2atts[i] = dri2att; - texture_indices[natts[i]] = i; } dri2surf->have_back = FALSE; @@ -266,13 +265,13 @@ dri2_surface_validate(struct native_surface *nsurf, break; } - if (!desc || texture_indices[natt] < 0 || - (textures && textures[texture_indices[natt]])) { + if (!desc || !native_attachment_mask_test(attachment_mask, natt) || + (textures && textures[natt])) { if (!desc) _eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment); - else if (texture_indices[natt] < 0) + else if (!native_attachment_mask_test(attachment_mask, natt)) _eglLog(_EGL_WARNING, "unexpected buffer %d", xbuf->attachment); - else if (textures && textures[texture_indices[natt]]) + else _eglLog(_EGL_WARNING, "both real and fake front buffers are listed"); continue; } @@ -284,7 +283,7 @@ dri2_surface_validate(struct native_surface *nsurf, desc, xbuf->pitch, xbuf->name); if (ptex) { /* the caller owns the textures */ - textures[texture_indices[natt]] = ptex; + textures[natt] = ptex; } } } diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c b/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c index 24a50df7a0..1f136235c0 100644 --- a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c +++ b/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c @@ -289,27 +289,21 @@ ximage_surface_update_geometry(struct native_surface *nsurf) } static boolean -ximage_surface_validate(struct native_surface *nsurf, - const enum native_attachment *natts, - unsigned num_natts, - unsigned int *seq_num, - struct pipe_texture **textures, - int *width, int *height) +ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask, + unsigned int *seq_num, struct pipe_texture **textures, + int *width, int *height) { struct ximage_surface *xsurf = ximage_surface(nsurf); - boolean new_buffers = FALSE, error = FALSE; - unsigned i; + boolean new_buffers = FALSE; + int att; ximage_surface_update_geometry(&xsurf->base); - if (textures) - memset(textures, 0, sizeof(*textures) * num_natts); + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + struct ximage_buffer *xbuf = &xsurf->buffers[att]; - for (i = 0; i < num_natts; i++) { - enum native_attachment natt = natts[i]; - struct ximage_buffer *xbuf = &xsurf->buffers[natt]; - - if (!xbuf) + /* delay the allocation */ + if (!native_attachment_mask_test(attachment_mask, att)) continue; /* reallocate the texture */ @@ -317,7 +311,7 @@ ximage_surface_validate(struct native_surface *nsurf, xsurf->width != xbuf->texture->width0 || xsurf->height != xbuf->texture->height0) { new_buffers = TRUE; - if (ximage_surface_alloc_buffer(&xsurf->base, natt)) { + if (ximage_surface_alloc_buffer(&xsurf->base, att)) { /* update ximage */ if (xbuf->ximage) { xbuf->ximage->width = xbuf->transfer->width; @@ -327,19 +321,10 @@ ximage_surface_validate(struct native_surface *nsurf, } } - /* allocation failed */ - if (!xbuf->texture) { - unsigned j; - for (j = 0; j < i; j++) - pipe_texture_reference(&textures[j], NULL); - for (j = i; j < num_natts; j++) - textures[j] = NULL; - error = TRUE; - break; + if (textures) { + textures[att] = NULL; + pipe_texture_reference(&textures[att], xbuf->texture); } - - if (textures) - pipe_texture_reference(&textures[i], xbuf->texture); } /* increase the sequence number so that caller knows */ @@ -353,7 +338,7 @@ ximage_surface_validate(struct native_surface *nsurf, if (height) *height = xsurf->height; - return !error; + return TRUE; } static void -- cgit v1.2.3 From f8244e294646c1b5127a2bf3e92811300b0e3b9e Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 18 Jan 2010 15:49:20 +0800 Subject: st/egl_g3d: Add is_pixmap_supported to native display interface. The function may be used to support, for example, EGL_MATCH_NATIVE_PIXMAP and EGL_KHR_image_pixmap. --- src/gallium/state_trackers/egl_g3d/common/native.h | 11 +++++++ .../state_trackers/egl_g3d/x11/native_dri2.c | 16 ++++++++++ .../state_trackers/egl_g3d/x11/native_ximage.c | 29 +++++++++++++++++ .../state_trackers/egl_g3d/x11/x11_screen.c | 36 ++++++++++++++++++++++ .../state_trackers/egl_g3d/x11/x11_screen.h | 4 +++ 5 files changed, 96 insertions(+) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/egl_g3d/common/native.h b/src/gallium/state_trackers/egl_g3d/common/native.h index 6cd161bdf6..f374f2e4a6 100644 --- a/src/gallium/state_trackers/egl_g3d/common/native.h +++ b/src/gallium/state_trackers/egl_g3d/common/native.h @@ -135,6 +135,17 @@ struct native_display { const struct native_config **(*get_configs)(struct native_display *ndpy, int *num_configs); + /** + * Test if a pixmap is supported by the given config. Required unless no + * config has GLX_PIXMAP_BIT set. + * + * This function is usually called to find a config that supports a given + * pixmap. Thus, it is usually called with the same pixmap in a row. + */ + boolean (*is_pixmap_supported)(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf); + /** * Create a pipe context. */ diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c b/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c index f675a8e686..07f82d878c 100644 --- a/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c +++ b/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c @@ -588,6 +588,21 @@ dri2_display_get_configs(struct native_display *ndpy, int *num_configs) return configs; } +static boolean +dri2_display_is_pixmap_supported(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + uint depth, nconf_depth; + + depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix); + nconf_depth = util_format_get_blocksizebits(nconf->color_format); + + /* simple depth match for now */ + return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth)); +} + static void dri2_display_destroy(struct native_display *ndpy) { @@ -680,6 +695,7 @@ x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api) dri2dpy->base.destroy = dri2_display_destroy; dri2dpy->base.get_configs = dri2_display_get_configs; + dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported; dri2dpy->base.create_context = dri2_display_create_context; dri2dpy->base.create_window_surface = dri2_display_create_window_surface; dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface; diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c b/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c index 1f136235c0..d76107c47f 100644 --- a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c +++ b/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c @@ -600,6 +600,34 @@ ximage_display_get_configs(struct native_display *ndpy, int *num_configs) return configs; } +static boolean +ximage_display_is_pixmap_supported(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf) +{ + struct ximage_display *xdpy = ximage_display(ndpy); + enum pipe_format fmt; + uint depth; + + depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix); + switch (depth) { + case 32: + fmt = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case 24: + fmt = PIPE_FORMAT_X8R8G8B8_UNORM; + break; + case 16: + fmt = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + fmt = PIPE_FORMAT_NONE; + break; + } + + return (fmt == nconf->color_format); +} + static void ximage_display_destroy(struct native_display *ndpy) { @@ -652,6 +680,7 @@ x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm) xdpy->base.destroy = ximage_display_destroy; xdpy->base.get_configs = ximage_display_get_configs; + xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported; xdpy->base.create_context = ximage_display_create_context; xdpy->base.create_window_surface = ximage_display_create_window_surface; xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface; diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c index 1e98943242..bfff91db8b 100644 --- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c +++ b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c @@ -30,6 +30,7 @@ #include #include "util/u_memory.h" #include "util/u_math.h" +#include "util/u_format.h" #include "xf86drm.h" #include "egllog.h" @@ -50,6 +51,10 @@ struct x11_screen { XVisualInfo *visuals; int num_visuals; + + /* cached values for x11_drawable_get_format */ + Drawable last_drawable; + unsigned int last_depth; }; @@ -350,6 +355,37 @@ x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable, return (struct x11_drawable_buffer *) dri2bufs; } +/** + * Return the depth of a drawable. + * + * Unlike other drawable functions, the drawable needs not be a DRI2 drawable. + */ +uint +x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable) +{ + unsigned int depth; + + if (drawable != xscr->last_drawable) { + Window root; + int x, y; + unsigned int w, h, border; + Status ok; + + ok = XGetGeometry(xscr->dpy, drawable, &root, + &x, &y, &w, &h, &border, &depth); + if (!ok) + depth = 0; + + xscr->last_drawable = drawable; + xscr->last_depth = depth; + } + else { + depth = xscr->last_depth; + } + + return depth; +} + /** * Create a mode list of the given size. */ diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h index 86e8e0501a..ad42bffbe9 100644 --- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h +++ b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h @@ -29,6 +29,7 @@ #include #include #include "pipe/p_compiler.h" +#include "pipe/p_format.h" #include "common/native.h" enum x11_screen_extension { @@ -96,4 +97,7 @@ x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable, int *width, int *height, unsigned int *attachments, boolean with_format, int num_ins, int *num_outs); +uint +x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable); + #endif /* _X11_SCREEN_H_ */ -- cgit v1.2.3 From ede755af4c4a22fd0076f1e18a5356879ac9c7e7 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 18 Jan 2010 15:28:13 +0800 Subject: st/egl_g3d: Add support for eglCopyBuffers. It uses a slow path to copy the render buffer of the surface to the target pixmap. We might be able to create a pipe context for EGLDisplay's use and use a blitter context for the purpose. It is left for a future consideration. --- .../state_trackers/egl_g3d/common/egl_g3d.c | 97 ++++++++++++++++++++++ 1 file changed, 97 insertions(+) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c index 08f796d083..042e9518c2 100644 --- a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c @@ -26,6 +26,7 @@ #include #include "pipe/p_screen.h" #include "util/u_memory.h" +#include "util/u_rect.h" #include "egldriver.h" #include "eglcurrent.h" #include "eglconfigutil.h" @@ -861,6 +862,101 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) return EGL_TRUE; } +/** + * Find a config that supports the pixmap. + */ +static _EGLConfig * +find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_config *gconf; + EGLint i; + + for (i = 0; i < dpy->NumConfigs; i++) { + gconf = egl_g3d_config(dpy->Configs[i]); + if (gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native)) + break; + } + + return (i < dpy->NumConfigs) ? &gconf->base : NULL; +} + +/** + * Get the pipe surface of the given attachment of the native surface. + */ +static struct pipe_surface * +get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf, + enum native_attachment natt) +{ + struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; + struct pipe_surface *psurf; + + textures[natt] = NULL; + nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL); + if (!textures[natt]) + return NULL; + + psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt], + 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE); + pipe_texture_reference(&textures[natt], NULL); + + return psurf; +} + +static EGLBoolean +egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, + NativePixmapType target) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + _EGLContext *ctx = _eglGetCurrentContext(); + struct egl_g3d_config *gconf; + struct native_surface *nsurf; + struct pipe_screen *screen = gdpy->native->screen; + struct pipe_surface *psurf; + + if (!gsurf->render_surface) + return EGL_TRUE; + + gconf = egl_g3d_config(find_pixmap_config(dpy, target)); + if (!gconf) + return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers"); + + nsurf = gdpy->native->create_pixmap_surface(gdpy->native, + target, gconf->native); + if (!nsurf) + return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers"); + + /* flush if the surface is current */ + if (ctx && ctx->DrawSurface == &gsurf->base) { + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + gctx->stapi->st_flush(gctx->st_ctx, + PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + } + + psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); + if (psurf) { + struct pipe_context pipe; + + /** + * XXX This is hacky. If we might allow the EGLDisplay to create a pipe + * context of its own and use the blitter context for this. + */ + memset(&pipe, 0, sizeof(pipe)); + pipe.screen = screen; + + util_surface_copy(&pipe, FALSE, psurf, 0, 0, + gsurf->render_surface, 0, 0, psurf->width, psurf->height); + + pipe_surface_reference(&psurf, NULL); + nsurf->flush_frontbuffer(nsurf); + } + + nsurf->destroy(nsurf); + + return EGL_TRUE; +} + static EGLBoolean egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) { @@ -1114,6 +1210,7 @@ _eglMain(const char *args) gdrv->base.API.DestroySurface = egl_g3d_destroy_surface; gdrv->base.API.MakeCurrent = egl_g3d_make_current; gdrv->base.API.SwapBuffers = egl_g3d_swap_buffers; + gdrv->base.API.CopyBuffers = egl_g3d_copy_buffers; gdrv->base.API.WaitClient = egl_g3d_wait_client; gdrv->base.API.WaitNative = egl_g3d_wait_native; gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address; -- cgit v1.2.3 From c273ab007dc4194b62965c3b1d9c8a90ea573680 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Mon, 18 Jan 2010 00:36:04 -0800 Subject: dri: Properly calculate number of modes for MSAA. Split from the next patch for bisection purposes only. --- src/gallium/state_trackers/dri/dri_screen.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index 793db087ee..d9f1fd4f41 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -158,7 +158,7 @@ dri_fill_in_modes(struct dri_screen *screen, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, back_buffer_factor, - msaa_samples_array, 1); + msaa_samples_array, msaa_samples_factor); } else { __DRIconfig **configs_a8r8g8b8 = NULL; __DRIconfig **configs_x8r8g8b8 = NULL; @@ -170,7 +170,8 @@ dri_fill_in_modes(struct dri_screen *screen, depth_buffer_factor, back_buffer_modes, back_buffer_factor, - msaa_samples_array, 1); + msaa_samples_array, + msaa_samples_factor); if (pf_x8r8g8b8) configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV, depth_bits_array, @@ -178,7 +179,8 @@ dri_fill_in_modes(struct dri_screen *screen, depth_buffer_factor, back_buffer_modes, back_buffer_factor, - msaa_samples_array, 1); + msaa_samples_array, + msaa_samples_factor); if (configs_a8r8g8b8 && configs_x8r8g8b8) configs = driConcatConfigs(configs_x8r8g8b8, configs_a8r8g8b8); -- cgit v1.2.3 From a16d353b5ea0e14887a2cd2db222beb357b37d65 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Mon, 18 Jan 2010 00:37:21 -0800 Subject: dri: Add an MSAA-enabled factor to DRI configs. 4 samples should be enough for GLUT to be satisfied, and I think most of the HW that does any MSAA, can do it. Note that any pipe that doesn't multisample can just ignore the corresponding flag in pipe_rasterizer_state. --- src/gallium/state_trackers/dri/dri_screen.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index d9f1fd4f41..d8c054313b 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -83,7 +83,7 @@ dri_fill_in_modes(struct dri_screen *screen, unsigned num_modes; uint8_t depth_bits_array[5]; uint8_t stencil_bits_array[5]; - uint8_t msaa_samples_array[1]; + uint8_t msaa_samples_array[2]; unsigned depth_buffer_factor; unsigned back_buffer_factor; unsigned msaa_samples_factor; @@ -147,8 +147,9 @@ dri_fill_in_modes(struct dri_screen *screen, } msaa_samples_array[0] = 0; + msaa_samples_array[1] = 4; back_buffer_factor = 3; - msaa_samples_factor = 1; + msaa_samples_factor = 2; num_modes = depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4; -- cgit v1.2.3 From 064eb0a095b1ac56e20459c216c9271bef01cb9f Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 18 Jan 2010 17:12:50 +0800 Subject: st/egl_g3d: Clean up for x11_drawable_get_depth. Fix a wrong comment and remove an unnecessary #include. --- src/gallium/state_trackers/egl_g3d/x11/x11_screen.c | 2 +- src/gallium/state_trackers/egl_g3d/x11/x11_screen.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c index bfff91db8b..4d68a88d2e 100644 --- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c +++ b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c @@ -52,7 +52,7 @@ struct x11_screen { XVisualInfo *visuals; int num_visuals; - /* cached values for x11_drawable_get_format */ + /* cached values for x11_drawable_get_depth */ Drawable last_drawable; unsigned int last_depth; }; diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h index ad42bffbe9..bf48218905 100644 --- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h +++ b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h @@ -29,7 +29,6 @@ #include #include #include "pipe/p_compiler.h" -#include "pipe/p_format.h" #include "common/native.h" enum x11_screen_extension { -- cgit v1.2.3 From e978b24c87be6d7572ed3272e6b186d5c54fb414 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Mon, 18 Jan 2010 10:48:06 -0700 Subject: st/dri: fix optionCache memory leaks Signed-off-by: Brian Paul --- src/gallium/state_trackers/dri/dri_context.c | 6 ++++++ src/gallium/state_trackers/dri/dri_screen.c | 10 ++++++++++ 2 files changed, 16 insertions(+) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index 8819936fca..cd9d8b682e 100644 --- a/src/gallium/state_trackers/dri/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -101,6 +101,12 @@ dri_destroy_context(__DRIcontextPrivate * cPriv) { struct dri_context *ctx = dri_context(cPriv); + /* note: we are freeing values and nothing more because + * driParseConfigFiles allocated values only - the rest + * is owned by screen optionCache. + */ + FREE(ctx->optionCache.values); + /* No particular reason to wait for command completion before * destroying a context, but it is probably worthwhile flushing it * to avoid having to add code elsewhere to cope with flushing a diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index 11ea28bcbe..d95c62745e 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -327,8 +327,18 @@ static void dri_destroy_screen(__DRIscreenPrivate * sPriv) { struct dri_screen *screen = dri_screen(sPriv); + int i; screen->pipe_screen->destroy(screen->pipe_screen); + + for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) { + FREE(screen->optionCache.info[i].name); + FREE(screen->optionCache.info[i].ranges); + } + + FREE(screen->optionCache.info); + FREE(screen->optionCache.values); + FREE(screen); sPriv->private = NULL; } -- cgit v1.2.3 From f8db32acbd03079d4ef30daa1db1339aa35b5cfb Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Mon, 18 Jan 2010 18:14:03 -0800 Subject: st/dri: Add comment for intentional fallthrough in case statement. --- src/gallium/state_trackers/dri/dri_drawable.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index 0a8c1cd361..99dc022549 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -183,6 +183,7 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv) case __DRI_BUFFER_FRONT_LEFT: if (!st_screen->auto_fake_front) continue; + /* fallthrough */ case __DRI_BUFFER_FAKE_FRONT_LEFT: index = ST_SURFACE_FRONT_LEFT; format = drawable->color_format; -- cgit v1.2.3 From 5e870f4fe9e71b7f467f2a0b03934352f90846cc Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Jan 2010 06:12:10 -0800 Subject: wgl: Don't export pure-stencil pixel formats. They cause DCT's conform to always fail. --- src/gallium/state_trackers/wgl/stw_pixelformat.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c index 7abe5d9f7f..c310c78ccf 100644 --- a/src/gallium/state_trackers/wgl/stw_pixelformat.c +++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c @@ -94,8 +94,6 @@ stw_pf_depth_stencil[] = { { PIPE_FORMAT_Z24X8_UNORM, {24, 0} }, { PIPE_FORMAT_X8Z24_UNORM, {24, 0} }, { PIPE_FORMAT_Z16_UNORM, {16, 0} }, - /* pure stencil */ - { PIPE_FORMAT_S8_UNORM, { 0, 8} }, /* combined depth-stencil */ { PIPE_FORMAT_S8Z24_UNORM, {24, 8} }, { PIPE_FORMAT_Z24S8_UNORM, {24, 8} } -- cgit v1.2.3 From 7a39a5c1cb5087a1b8247f9bed59bf9374717cb3 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Jan 2010 06:13:44 -0800 Subject: wgl: Check for PIPE_TEXTURE_USAGE_DISPLAY_TARGET support in exported color pixel formats. Since all formats we export have PFD_DRAW_TO_WINDOW flag. --- src/gallium/state_trackers/wgl/stw_pixelformat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c index c310c78ccf..95e1957e07 100644 --- a/src/gallium/state_trackers/wgl/stw_pixelformat.c +++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c @@ -219,7 +219,8 @@ stw_pixelformat_init( void ) const struct stw_pf_color_info *color = &stw_pf_color[j]; if(!screen->is_format_supported(screen, color->format, PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) + PIPE_TEXTURE_USAGE_RENDER_TARGET | + PIPE_TEXTURE_USAGE_DISPLAY_TARGET, 0)) continue; for(k = 0; k < Elements(stw_pf_doublebuffer); ++k) { -- cgit v1.2.3 From 116a02be2264807dafb5fdfd4e3c913bb728c11f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 11 Jan 2010 11:41:47 +1000 Subject: st/dri: update dri2 drawables when viewport is changed Fixes gnome-shell on nouveau, as well as window resize with various other applications. Signed-off-by: Ben Skeggs --- src/gallium/include/pipe/p_screen.h | 5 +++++ src/gallium/state_trackers/dri/dri_drawable.c | 8 ++++++++ src/gallium/state_trackers/dri/dri_drawable.h | 3 +++ src/gallium/state_trackers/dri/dri_screen.c | 1 + src/mesa/state_tracker/st_cb_viewport.c | 4 ++-- 5 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index f0a4de5df3..b8e001a6b0 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -266,6 +266,11 @@ struct pipe_screen { void (*video_surface_destroy)( struct pipe_video_surface *vsfc ); + /** + * Do any special operations to ensure buffer size is correct + */ + void (*update_buffer)( struct pipe_screen *ws, + void *context_private ); /** * Do any special operations to ensure frontbuffer contents are diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index 99dc022549..c20b71e958 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -271,6 +271,14 @@ void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target, dri2_set_tex_buffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv); } +void +dri_update_buffer(struct pipe_screen *screen, void *context_private) +{ + struct dri_context *ctx = (struct dri_context *)context_private; + + dri_get_buffers(ctx->dPriv); +} + void dri_flush_frontbuffer(struct pipe_screen *screen, struct pipe_surface *surf, void *context_private) diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h index b910930db4..a0fb05d7b2 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.h +++ b/src/gallium/state_trackers/dri/dri_drawable.h @@ -80,6 +80,9 @@ dri_create_buffer(__DRIscreenPrivate * sPriv, __DRIdrawablePrivate * dPriv, const __GLcontextModes * visual, boolean isPixmap); +void +dri_update_buffer(struct pipe_screen *screen, void *context_private); + void dri_flush_frontbuffer(struct pipe_screen *screen, struct pipe_surface *surf, void *context_private); diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index d95c62745e..25c392e849 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -310,6 +310,7 @@ dri_init_screen2(__DRIscreenPrivate * sPriv) } /* We need to hook in here */ + screen->pipe_screen->update_buffer = dri_update_buffer; screen->pipe_screen->flush_frontbuffer = dri_flush_frontbuffer; driParseOptionInfo(&screen->optionCache, diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/mesa/state_tracker/st_cb_viewport.c index 9450b3a45b..d8bd24405c 100644 --- a/src/mesa/state_tracker/st_cb_viewport.c +++ b/src/mesa/state_tracker/st_cb_viewport.c @@ -40,8 +40,8 @@ static void st_viewport(GLcontext * ctx, GLint x, GLint y, { struct st_context *st = ctx->st; - if (st->pipe->winsys && st->pipe->winsys->update_buffer) - st->pipe->winsys->update_buffer( st->pipe->winsys, + if (st->pipe->screen && st->pipe->screen->update_buffer) + st->pipe->screen->update_buffer( st->pipe->screen, st->pipe->priv ); } -- cgit v1.2.3 From 65354a7e3d8fd094837b7a999e8975dcfbd9d9c9 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 19 Jan 2010 17:14:19 +0000 Subject: st/xorg: Pass kernel driver name to drmOpen --- src/gallium/state_trackers/xorg/xorg_driver.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index b02fe68f31..ed185d314f 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -206,10 +206,19 @@ drv_init_drm(ScrnInfoPtr pScrn) ms->PciInfo->dev, ms->PciInfo->func ); - ms->fd = drmOpen(NULL, BusID); - if (ms->fd < 0) - return FALSE; + ms->api = drm_api_create(); + ms->fd = drmOpen(ms->api ? ms->api->driver_name : NULL, BusID); + + if (ms->fd >= 0) + return TRUE; + + if (ms->api->destroy) + ms->api->destroy(ms->api); + + ms->api = NULL; + + return FALSE; } return TRUE; @@ -229,7 +238,6 @@ drv_init_resource_management(ScrnInfoPtr pScrn) if (ms->screen || ms->kms) return TRUE; - ms->api = drm_api_create(); if (ms->api) { ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL); -- cgit v1.2.3 From c78fe6e050c311a3d53ccb091686a65ee6933a90 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 19 Jan 2010 23:29:56 +0100 Subject: st/xorg: Don't leak BusID buffer --- src/gallium/state_trackers/xorg/xorg_driver.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index ed185d314f..b74953e543 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -209,6 +209,7 @@ drv_init_drm(ScrnInfoPtr pScrn) ms->api = drm_api_create(); ms->fd = drmOpen(ms->api ? ms->api->driver_name : NULL, BusID); + xfree(BusID); if (ms->fd >= 0) return TRUE; -- cgit v1.2.3 From f291200a4bbc0b701cfe831bdeeb79f90efd866f Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 20 Jan 2010 13:24:42 +0800 Subject: st/egl_g3d: Do not reuse the pipe transfer in ximage. A pipe transfer is supposed to be temporary. It should be created before X*PutImage and destroyed afterwards. --- .../state_trackers/egl_g3d/x11/native_ximage.c | 40 ++++++++++++---------- 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c b/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c index d76107c47f..dfa8df2223 100644 --- a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c +++ b/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c @@ -66,7 +66,6 @@ struct ximage_buffer { XImage *ximage; struct pipe_texture *texture; - struct pipe_transfer *transfer; XShmSegmentInfo *shm_info; boolean xshm_attached; }; @@ -115,12 +114,7 @@ ximage_surface_free_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; - if (xbuf->transfer) { - screen->tex_transfer_destroy(xbuf->transfer); - xbuf->transfer = NULL; - } pipe_texture_reference(&xbuf->texture, NULL); if (xbuf->shm_info) { @@ -193,13 +187,6 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf, xbuf->texture = screen->texture_create(screen, &templ); } - if (xbuf->texture) { - xbuf->transfer = screen->get_tex_transfer(screen, xbuf->texture, - 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height); - if (!xbuf->transfer) - pipe_texture_reference(&xbuf->texture, NULL); - } - /* clean up the buffer if allocation failed */ if (!xbuf->texture) ximage_surface_free_buffer(&xsurf->base, which); @@ -214,13 +201,25 @@ 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; if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER) return TRUE; assert(xsurf->drawable && xbuf->ximage && xbuf->texture); - xbuf->ximage->data = screen->transfer_map(screen, xbuf->transfer); + transfer = screen->get_tex_transfer(screen, xbuf->texture, + 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height); + if (!transfer) + 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, @@ -230,7 +229,13 @@ ximage_surface_draw_buffer(struct native_surface *nsurf, xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height); xbuf->ximage->data = NULL; - screen->transfer_unmap(screen, xbuf->transfer); + screen->transfer_unmap(screen, transfer); + + /* + * 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); @@ -314,9 +319,8 @@ ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask, if (ximage_surface_alloc_buffer(&xsurf->base, att)) { /* update ximage */ if (xbuf->ximage) { - xbuf->ximage->width = xbuf->transfer->width; - xbuf->ximage->height = xbuf->transfer->height; - xbuf->ximage->bytes_per_line = xbuf->transfer->stride; + xbuf->ximage->width = xsurf->width; + xbuf->ximage->height = xsurf->height; } } } -- cgit v1.2.3 From 11f4360f2e915f236558da22efe5bdabd81446f3 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 20 Jan 2010 15:52:50 +0800 Subject: st/egl_g3d: Add support for probe to native displays. The functions can be used to check if a display is supported without creating a struct native_display. It uses a probe object that can be shared across drivers. --- src/gallium/state_trackers/egl_g3d/common/native.h | 37 +++++++++++ .../state_trackers/egl_g3d/kms/native_kms.c | 12 ++++ .../state_trackers/egl_g3d/x11/native_x11.c | 76 ++++++++++++++++++++++ .../state_trackers/egl_g3d/x11/x11_screen.c | 25 +++++-- .../state_trackers/egl_g3d/x11/x11_screen.h | 3 + 5 files changed, 146 insertions(+), 7 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/egl_g3d/common/native.h b/src/gallium/state_trackers/egl_g3d/common/native.h index f374f2e4a6..72a9cec7ef 100644 --- a/src/gallium/state_trackers/egl_g3d/common/native.h +++ b/src/gallium/state_trackers/egl_g3d/common/native.h @@ -47,6 +47,27 @@ enum native_attachment { NUM_NATIVE_ATTACHMENTS }; +/** + * Enumerations for probe results. + */ +enum native_probe_result { + NATIVE_PROBE_UNKNOWN, + NATIVE_PROBE_FALLBACK, + NATIVE_PROBE_SUPPORTED, + NATIVE_PROBE_EXACT, +}; + +/** + * A probe object for display probe. + */ +struct native_probe { + int magic; + EGLNativeDisplayType display; + void *data; + + void (*destroy)(struct native_probe *nprobe); +}; + struct native_surface { void (*destroy)(struct native_surface *nsurf); @@ -231,6 +252,22 @@ native_attachment_mask_test(uint mask, enum native_attachment att) return !!(mask & (1 << att)); } +/** + * Return a probe object for the given display. + * + * Note that the returned object may be cached and used by different native + * display modules. It allows fast probing when multiple modules probe the + * same display. + */ +struct native_probe * +native_create_probe(EGLNativeDisplayType dpy); + +/** + * Probe the probe object. + */ +enum native_probe_result +native_get_probe_result(struct native_probe *nprobe); + const char * native_get_name(void); diff --git a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c index dc66436630..d5baf2c2f0 100644 --- a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c +++ b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c @@ -820,6 +820,18 @@ kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api) return &kdpy->base; } +struct native_probe * +native_create_probe(EGLNativeDisplayType dpy) +{ + return NULL; +} + +enum native_probe_result +native_get_probe_result(struct native_probe *nprobe) +{ + return NATIVE_PROBE_UNKNOWN; +} + /* the api is destroyed with the native display */ static struct drm_api *drm_api; diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_x11.c b/src/gallium/state_trackers/egl_g3d/x11/native_x11.c index 583ce3d329..695ab88010 100644 --- a/src/gallium/state_trackers/egl_g3d/x11/native_x11.c +++ b/src/gallium/state_trackers/egl_g3d/x11/native_x11.c @@ -24,13 +24,89 @@ #include #include "util/u_debug.h" +#include "util/u_memory.h" #include "state_tracker/drm_api.h" #include "egllog.h" #include "native_x11.h" +#include "x11_screen.h" + +#define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */ static struct drm_api *api; +static void +x11_probe_destroy(struct native_probe *nprobe) +{ + if (nprobe->data) + free(nprobe->data); + free(nprobe); +} + +struct native_probe * +native_create_probe(EGLNativeDisplayType dpy) +{ + struct native_probe *nprobe; + struct x11_screen *xscr; + int scr; + const char *driver_name = NULL; + Display *xdpy; + + nprobe = CALLOC_STRUCT(native_probe); + if (!nprobe) + return NULL; + + xdpy = dpy; + if (!xdpy) { + xdpy = XOpenDisplay(NULL); + if (!xdpy) { + free(nprobe); + return NULL; + } + } + + scr = DefaultScreen(xdpy); + xscr = x11_screen_create(xdpy, scr); + if (xscr) { + if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) { + driver_name = x11_screen_probe_dri2(xscr); + nprobe->data = strdup(driver_name); + } + + x11_screen_destroy(xscr); + } + + if (xdpy != dpy) + XCloseDisplay(xdpy); + + nprobe->magic = X11_PROBE_MAGIC; + nprobe->display = dpy; + + nprobe->destroy = x11_probe_destroy; + + return nprobe; +} + +enum native_probe_result +native_get_probe_result(struct native_probe *nprobe) +{ + if (!nprobe || nprobe->magic != X11_PROBE_MAGIC) + return NATIVE_PROBE_UNKNOWN; + + if (!api) + api = drm_api_create(); + + /* this is a software driver */ + if (!api) + return NATIVE_PROBE_SUPPORTED; + + /* the display does not support DRI2 or the driver mismatches */ + if (!nprobe->data || strcmp(api->name, (const char *) nprobe->data) != 0) + return NATIVE_PROBE_FALLBACK; + + return NATIVE_PROBE_EXACT; +} + const char * native_get_name(void) { diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c index 4d68a88d2e..fef7878ab9 100644 --- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c +++ b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c @@ -249,6 +249,22 @@ 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) +{ + /* 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; + } + + return xscr->dri_driver; +} + /** * Enable DRI2 and returns the file descriptor of the DRM device. The file * descriptor will be closed automatically when the screen is destoryed. @@ -261,13 +277,8 @@ x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver) drm_magic_t magic; /* get the driver name and the device name first */ - 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; - return -1; - } - } + if (!x11_screen_probe_dri2(xscr)) + return -1; if (!x11_screen_is_driver_equal(xscr, driver)) { _eglLog(_EGL_WARNING, "Driver mismatch: %s != %s", diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h index bf48218905..5432858ac3 100644 --- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h +++ b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h @@ -70,6 +70,9 @@ x11_screen_get_glx_configs(struct x11_screen *xscr); const __GLcontextModes * x11_screen_get_glx_visuals(struct x11_screen *xscr); +const char * +x11_screen_probe_dri2(struct x11_screen *xscr); + int x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver); -- cgit v1.2.3 From c8b694b2c2f451235270a3442254379caea3f57d Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 20 Jan 2010 13:55:57 +0800 Subject: st/egl_g3d: Add support for driver probe. Hook the drv->Probe callback to allow the drivers to probe displays. The loading of state trackers is delayed to avoid unnecessary loading. --- .../state_trackers/egl_g3d/common/egl_g3d.c | 117 +++++++++++++++++++-- .../state_trackers/egl_g3d/common/egl_g3d.h | 2 + 2 files changed, 108 insertions(+), 11 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c index 042e9518c2..2ac6215646 100644 --- a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c @@ -294,6 +294,71 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx) return stapi; } +/** + * Initialize the state trackers. + */ +static void +egl_g3d_init_st(_EGLDriver *drv) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + EGLint i; + + /* already initialized */ + if (gdrv->api_mask) + return; + + for (i = 0; i < NUM_EGL_G3D_STS; i++) { + gdrv->stapis[i] = egl_g3d_get_st(i); + if (gdrv->stapis[i]) + gdrv->api_mask |= gdrv->stapis[i]->api_bit; + } + + if (gdrv->api_mask) + _eglLog(_EGL_DEBUG, "Driver API mask: 0x%x", gdrv->api_mask); + else + _eglLog(_EGL_WARNING, "No supported client API"); +} + +/** + * Get the probe object of the display. + * + * Note that this function may be called before the display is initialized. + */ +static struct native_probe * +egl_g3d_get_probe(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + struct native_probe *nprobe; + + nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key); + if (!nprobe || nprobe->display != dpy->NativeDisplay) { + if (nprobe) + nprobe->destroy(nprobe); + nprobe = native_create_probe(dpy->NativeDisplay); + _eglSetProbeCache(gdrv->probe_key, (void *) nprobe); + } + + return nprobe; +} + +/** + * Destroy the probe object of the display. The display may be NULL. + * + * Note that this function may be called before the display is initialized. + */ +static void +egl_g3d_destroy_probe(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + struct native_probe *nprobe; + + nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key); + if (nprobe && (!dpy || nprobe->display == dpy->NativeDisplay)) { + nprobe->destroy(nprobe); + _eglSetProbeCache(gdrv->probe_key, NULL); + } +} + /** * Return an API mask that consists of the state trackers that supports the * given mode. @@ -515,6 +580,9 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); struct egl_g3d_display *gdpy; + /* the probe object is unlikely to be needed again */ + egl_g3d_destroy_probe(drv, dpy); + gdpy = CALLOC_STRUCT(egl_g3d_display); if (!gdpy) { _eglError(EGL_BAD_ALLOC, "eglInitialize"); @@ -531,6 +599,7 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer; 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) { @@ -987,6 +1056,9 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname) _EGLProc proc; EGLint i; + /* in case this is called before a display is initialized */ + egl_g3d_init_st(&gdrv->base); + for (i = 0; i < NUM_EGL_G3D_STS; i++) { const struct egl_g3d_st *stapi = gdrv->stapis[i]; if (stapi) { @@ -1177,10 +1249,41 @@ egl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy, #endif /* EGL_MESA_screen_surface */ +static EGLint +egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct native_probe *nprobe; + enum native_probe_result res; + EGLint score; + + nprobe = egl_g3d_get_probe(drv, dpy); + res = native_get_probe_result(nprobe); + + switch (res) { + case NATIVE_PROBE_UNKNOWN: + default: + score = 0; + break; + case NATIVE_PROBE_FALLBACK: + score = 40; + break; + case NATIVE_PROBE_SUPPORTED: + score = 50; + break; + case NATIVE_PROBE_EXACT: + score = 100; + break; + } + + return score; +} + static void egl_g3d_unload(_EGLDriver *drv) { struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + + egl_g3d_destroy_probe(drv, NULL); free(gdrv); } @@ -1189,7 +1292,6 @@ _eglMain(const char *args) { static char driver_name[64]; struct egl_g3d_driver *gdrv; - EGLint i; snprintf(driver_name, sizeof(driver_name), "Gallium/%s", native_get_name()); @@ -1224,18 +1326,11 @@ _eglMain(const char *args) #endif gdrv->base.Name = driver_name; + gdrv->base.Probe = egl_g3d_probe; gdrv->base.Unload = egl_g3d_unload; - for (i = 0; i < NUM_EGL_G3D_STS; i++) { - gdrv->stapis[i] = egl_g3d_get_st(i); - if (gdrv->stapis[i]) - gdrv->api_mask |= gdrv->stapis[i]->api_bit; - } - - if (gdrv->api_mask) - _eglLog(_EGL_DEBUG, "Driver API mask: 0x%x", gdrv->api_mask); - else - _eglLog(_EGL_WARNING, "No supported client API"); + /* the key is " EGL G3D" */ + gdrv->probe_key = 0x0E61063D; return &gdrv->base; } diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h index 1da8af495b..3dae8c4052 100644 --- a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h +++ b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h @@ -44,6 +44,8 @@ struct egl_g3d_driver { _EGLDriver base; const struct egl_g3d_st *stapis[NUM_EGL_G3D_STS]; EGLint api_mask; + + EGLint probe_key; }; struct egl_g3d_display { -- cgit v1.2.3 From 9f728ed1c9c7255554109299508a78b9fbb1cdb6 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 20 Jan 2010 14:53:38 +0000 Subject: st/xorg: Fic bug and close drm_api at proper place --- src/gallium/state_trackers/xorg/xorg_driver.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index b74953e543..2714fba999 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -214,7 +214,7 @@ drv_init_drm(ScrnInfoPtr pScrn) if (ms->fd >= 0) return TRUE; - if (ms->api->destroy) + if (ms->api && ms->api->destroy) ms->api->destroy(ms->api); ms->api = NULL; @@ -225,6 +225,21 @@ drv_init_drm(ScrnInfoPtr pScrn) return TRUE; } +static Bool +drv_close_drm(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + + if (ms->api && ms->api->destroy) + ms->api->destroy(ms->api); + ms->api = NULL; + + drmClose(ms->fd); + ms->fd = -1; + + return TRUE; +} + static Bool drv_init_resource_management(ScrnInfoPtr pScrn) { @@ -278,10 +293,6 @@ drv_close_resource_management(ScrnInfoPtr pScrn) } ms->screen = NULL; - if (ms->api && ms->api->destroy) - ms->api->destroy(ms->api); - ms->api = NULL; - #ifdef HAVE_LIBKMS if (ms->kms) kms_destroy(&ms->kms); @@ -832,8 +843,7 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen) drv_close_resource_management(pScrn); - drmClose(ms->fd); - ms->fd = -1; + drv_close_drm(pScrn); pScrn->vtSema = FALSE; pScreen->CloseScreen = ms->CloseScreen; -- cgit v1.2.3 From efc08bddb7622e4acfa795b58e1264b64b78ab4f Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Thu, 21 Jan 2010 15:05:21 -0800 Subject: st/xorg: Remove unnecessary headers. --- src/gallium/state_trackers/xorg/xorg_composite.c | 3 --- src/gallium/state_trackers/xorg/xorg_dri2.c | 1 - src/gallium/state_trackers/xorg/xorg_driver.c | 1 - src/gallium/state_trackers/xorg/xorg_exa.c | 1 - src/gallium/state_trackers/xorg/xorg_exa_tgsi.c | 2 -- src/gallium/state_trackers/xorg/xorg_output.c | 2 -- src/gallium/state_trackers/xorg/xorg_xv.c | 1 - 7 files changed, 11 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c index a5975aad51..89d462d9d6 100644 --- a/src/gallium/state_trackers/xorg/xorg_composite.c +++ b/src/gallium/state_trackers/xorg/xorg_composite.c @@ -4,10 +4,7 @@ #include "xorg_exa_tgsi.h" #include "cso_cache/cso_context.h" -#include "util/u_draw_quad.h" -#include "util/u_math.h" -#include "pipe/p_inlines.h" /*XXX also in Xrender.h but the including it here breaks compilition */ #define XFixedToDouble(f) (((double) (f)) / 65536.) diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 8267da309f..468563e34c 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -40,7 +40,6 @@ #include "pipe/p_state.h" #include "pipe/p_inlines.h" -#include "util/u_rect.h" /* Make all the #if cases in the code esier to read */ #ifndef DRI2INFOREC_VERSION diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index 2714fba999..41bfcd0f5e 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -45,7 +45,6 @@ #include "miscstruct.h" #include "dixstruct.h" #include "xf86xv.h" -#include #ifndef XSERVER_LIBPCIACCESS #error "libpciaccess needed" #endif diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 4e7882551d..6d89fcaa9f 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -41,7 +41,6 @@ #include "pipe/p_format.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" #include "util/u_rect.h" #include "util/u_math.h" diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c index bed17caab7..3e5e6bd6a6 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c +++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c @@ -6,11 +6,9 @@ #include "pipe/p_format.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" #include "pipe/p_shader_tokens.h" #include "util/u_memory.h" -#include "util/u_simple_shaders.h" #include "tgsi/tgsi_ureg.h" diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c index 251f331ea7..13c3fb97e3 100644 --- a/src/gallium/state_trackers/xorg/xorg_output.c +++ b/src/gallium/state_trackers/xorg/xorg_output.c @@ -49,8 +49,6 @@ #include #endif -#include "X11/Xatom.h" - #include "xorg_tracker.h" static char *output_enum_list[] = { diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c index a437370525..5f6d74943f 100644 --- a/src/gallium/state_trackers/xorg/xorg_xv.c +++ b/src/gallium/state_trackers/xorg/xorg_xv.c @@ -11,7 +11,6 @@ #include "cso_cache/cso_context.h" #include "pipe/p_screen.h" -#include "pipe/p_inlines.h" /*XXX get these from pipe's texture limits */ #define IMAGE_MAX_WIDTH 2048 -- cgit v1.2.3 From cfb1ed39771c7f3876a8231ab1c8a8d6f7b5deae Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 22 Jan 2010 14:41:00 +0800 Subject: st/egl_g3d: Use glxinit.c from egl_xdri. It is used to fetch the GLX visuals/fbconfigs. Use egl_xdri's version to avoid duplication. It might be better to rewrite that part though. --- src/gallium/state_trackers/egl_g3d/Makefile | 5 +- src/gallium/state_trackers/egl_g3d/x11/glxinit.c | 573 --------------------- src/gallium/state_trackers/egl_g3d/x11/glxinit.h | 14 - .../state_trackers/egl_g3d/x11/x11_screen.c | 8 +- 4 files changed, 10 insertions(+), 590 deletions(-) delete mode 100644 src/gallium/state_trackers/egl_g3d/x11/glxinit.c delete mode 100644 src/gallium/state_trackers/egl_g3d/x11/glxinit.h (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/egl_g3d/Makefile b/src/gallium/state_trackers/egl_g3d/Makefile index 213eb3e815..b696f2fae9 100644 --- a/src/gallium/state_trackers/egl_g3d/Makefile +++ b/src/gallium/state_trackers/egl_g3d/Makefile @@ -15,10 +15,13 @@ 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 +x11_SOURCES = $(wildcard x11/*.c) \ + $(TOP)/src/glx/x11/dri2.c \ + $(TOP)/src/egl/drivers/xdri/glxinit.c x11_OBJECTS = $(x11_SOURCES:.c=.o) diff --git a/src/gallium/state_trackers/egl_g3d/x11/glxinit.c b/src/gallium/state_trackers/egl_g3d/x11/glxinit.c deleted file mode 100644 index c955a908b9..0000000000 --- a/src/gallium/state_trackers/egl_g3d/x11/glxinit.c +++ /dev/null @@ -1,573 +0,0 @@ -/** - * GLX initialization. Code based on glxext.c, glx_query.c, and - * glcontextmodes.c under src/glx/x11/. The major difference is that no DRI - * related code here. - * - */ - -#include -#include -#include -#include -#include -#include - -#include "x11_screen.h" -#include "glxinit.h" - -typedef struct GLXGenericGetString -{ - CARD8 reqType; - CARD8 glxCode; - CARD16 length B16; - CARD32 for_whom B32; - CARD32 name B32; -} xGLXGenericGetStringReq; - -#define sz_xGLXGenericGetStringReq 12 -#define X_GLXGenericGetString 0 - -/* Extension required boiler plate */ - -static char *__glXExtensionName = GLX_EXTENSION_NAME; -static XExtensionInfo *__glXExtensionInfo = NULL; - -static /* const */ XExtensionHooks __glXExtensionHooks = { NULL }; -static -XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, - __glXExtensionName, &__glXExtensionHooks, - __GLX_NUMBER_EVENTS, NULL) - -static GLint -_gl_convert_from_x_visual_type(int visualType) -{ -#define NUM_VISUAL_TYPES 6 - static const int glx_visual_types[NUM_VISUAL_TYPES] = { - GLX_STATIC_GRAY, GLX_GRAY_SCALE, - GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, - GLX_TRUE_COLOR, GLX_DIRECT_COLOR - }; - - return ((unsigned) visualType < NUM_VISUAL_TYPES) - ? glx_visual_types[visualType] : GLX_NONE; -} - -_X_HIDDEN char * -__glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name) -{ - xGLXGenericGetStringReq *req; - xGLXSingleReply reply; - int length; - int numbytes; - char *buf; - CARD32 for_whom = screen; - CARD32 glxCode = X_GLXQueryServerString; - - - LockDisplay(dpy); - - - /* All of the GLX protocol requests for getting a string from the server - * look the same. The exact meaning of the for_whom field is usually - * either the screen number (for glXQueryServerString) or the context tag - * (for GLXSingle). - */ - - GetReq(GLXGenericGetString, req); - req->reqType = opcode; - req->glxCode = glxCode; - req->for_whom = for_whom; - req->name = name; - - _XReply(dpy, (xReply *) & reply, 0, False); - - length = reply.length * 4; - numbytes = reply.size; - - buf = (char *) Xmalloc(numbytes); - if (buf != NULL) { - _XRead(dpy, buf, numbytes); - length -= numbytes; - } - - _XEatData(dpy, length); - - UnlockDisplay(dpy); - SyncHandle(); - - return buf; -} - -/************************************************************************/ -/* -** Free the per screen configs data as well as the array of -** __glXScreenConfigs. -*/ -static void -FreeScreenConfigs(__GLXdisplayPrivate * priv) -{ - __GLXscreenConfigs *psc; - GLint i, screens; - - /* Free screen configuration information */ - psc = priv->screenConfigs; - screens = ScreenCount(priv->dpy); - for (i = 0; i < screens; i++, psc++) { - if (psc->configs) { - x11_context_modes_destroy(psc->configs); - psc->configs = NULL; /* NOTE: just for paranoia */ - } - if (psc->visuals) { - x11_context_modes_destroy(psc->visuals); - psc->visuals = NULL; /* NOTE: just for paranoia */ - } - Xfree((char *) psc->serverGLXexts); - } - XFree((char *) priv->screenConfigs); - priv->screenConfigs = NULL; -} - -/************************************************************************/ - -/* -** Query the version of the GLX extension. This procedure works even if -** the client extension is not completely set up. -*/ -static Bool -QueryVersion(Display * dpy, int opcode, int *major, int *minor) -{ - xGLXQueryVersionReq *req; - xGLXQueryVersionReply reply; - - /* Send the glXQueryVersion request */ - LockDisplay(dpy); - GetReq(GLXQueryVersion, req); - req->reqType = opcode; - req->glxCode = X_GLXQueryVersion; - req->majorVersion = GLX_MAJOR_VERSION; - req->minorVersion = GLX_MINOR_VERSION; - _XReply(dpy, (xReply *) & reply, 0, False); - UnlockDisplay(dpy); - SyncHandle(); - - if (reply.majorVersion != GLX_MAJOR_VERSION) { - /* - ** The server does not support the same major release as this - ** client. - */ - return GL_FALSE; - } - *major = reply.majorVersion; - *minor = min(reply.minorVersion, GLX_MINOR_VERSION); - return GL_TRUE; -} - -_X_HIDDEN void -__glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count, - const INT32 * bp, Bool tagged_only, - Bool fbconfig_style_tags) -{ - int i; - - if (!tagged_only) { - /* Copy in the first set of properties */ - config->visualID = *bp++; - - config->visualType = _gl_convert_from_x_visual_type(*bp++); - - config->rgbMode = *bp++; - - config->redBits = *bp++; - config->greenBits = *bp++; - config->blueBits = *bp++; - config->alphaBits = *bp++; - config->accumRedBits = *bp++; - config->accumGreenBits = *bp++; - config->accumBlueBits = *bp++; - config->accumAlphaBits = *bp++; - - config->doubleBufferMode = *bp++; - config->stereoMode = *bp++; - - config->rgbBits = *bp++; - config->depthBits = *bp++; - config->stencilBits = *bp++; - config->numAuxBuffers = *bp++; - config->level = *bp++; - - count -= __GLX_MIN_CONFIG_PROPS; - } - - /* - ** Additional properties may be in a list at the end - ** of the reply. They are in pairs of property type - ** and property value. - */ - -#define FETCH_OR_SET(tag) \ - config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1 - - for (i = 0; i < count; i += 2) { - switch (*bp++) { - case GLX_RGBA: - FETCH_OR_SET(rgbMode); - break; - case GLX_BUFFER_SIZE: - config->rgbBits = *bp++; - break; - case GLX_LEVEL: - config->level = *bp++; - break; - case GLX_DOUBLEBUFFER: - FETCH_OR_SET(doubleBufferMode); - break; - case GLX_STEREO: - FETCH_OR_SET(stereoMode); - break; - case GLX_AUX_BUFFERS: - config->numAuxBuffers = *bp++; - break; - case GLX_RED_SIZE: - config->redBits = *bp++; - break; - case GLX_GREEN_SIZE: - config->greenBits = *bp++; - break; - case GLX_BLUE_SIZE: - config->blueBits = *bp++; - break; - case GLX_ALPHA_SIZE: - config->alphaBits = *bp++; - break; - case GLX_DEPTH_SIZE: - config->depthBits = *bp++; - break; - case GLX_STENCIL_SIZE: - config->stencilBits = *bp++; - break; - case GLX_ACCUM_RED_SIZE: - config->accumRedBits = *bp++; - break; - case GLX_ACCUM_GREEN_SIZE: - config->accumGreenBits = *bp++; - break; - case GLX_ACCUM_BLUE_SIZE: - config->accumBlueBits = *bp++; - break; - case GLX_ACCUM_ALPHA_SIZE: - config->accumAlphaBits = *bp++; - break; - case GLX_VISUAL_CAVEAT_EXT: - config->visualRating = *bp++; - break; - case GLX_X_VISUAL_TYPE: - config->visualType = *bp++; - break; - case GLX_TRANSPARENT_TYPE: - config->transparentPixel = *bp++; - break; - case GLX_TRANSPARENT_INDEX_VALUE: - config->transparentIndex = *bp++; - break; - case GLX_TRANSPARENT_RED_VALUE: - config->transparentRed = *bp++; - break; - case GLX_TRANSPARENT_GREEN_VALUE: - config->transparentGreen = *bp++; - break; - case GLX_TRANSPARENT_BLUE_VALUE: - config->transparentBlue = *bp++; - break; - case GLX_TRANSPARENT_ALPHA_VALUE: - config->transparentAlpha = *bp++; - break; - case GLX_VISUAL_ID: - config->visualID = *bp++; - break; - case GLX_DRAWABLE_TYPE: - config->drawableType = *bp++; - break; - case GLX_RENDER_TYPE: - config->renderType = *bp++; - break; - case GLX_X_RENDERABLE: - config->xRenderable = *bp++; - break; - case GLX_FBCONFIG_ID: - config->fbconfigID = *bp++; - break; - case GLX_MAX_PBUFFER_WIDTH: - config->maxPbufferWidth = *bp++; - break; - case GLX_MAX_PBUFFER_HEIGHT: - config->maxPbufferHeight = *bp++; - break; - case GLX_MAX_PBUFFER_PIXELS: - config->maxPbufferPixels = *bp++; - break; - case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX: - config->optimalPbufferWidth = *bp++; - break; - case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX: - config->optimalPbufferHeight = *bp++; - break; - case GLX_VISUAL_SELECT_GROUP_SGIX: - config->visualSelectGroup = *bp++; - break; - case GLX_SWAP_METHOD_OML: - config->swapMethod = *bp++; - break; - case GLX_SAMPLE_BUFFERS_SGIS: - config->sampleBuffers = *bp++; - break; - case GLX_SAMPLES_SGIS: - config->samples = *bp++; - break; - case GLX_BIND_TO_TEXTURE_RGB_EXT: - config->bindToTextureRgb = *bp++; - break; - case GLX_BIND_TO_TEXTURE_RGBA_EXT: - config->bindToTextureRgba = *bp++; - break; - case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: - config->bindToMipmapTexture = *bp++; - break; - case GLX_BIND_TO_TEXTURE_TARGETS_EXT: - config->bindToTextureTargets = *bp++; - break; - case GLX_Y_INVERTED_EXT: - config->yInverted = *bp++; - break; - case None: - i = count; - break; - default: - break; - } - } - - config->renderType = - (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; - - config->haveAccumBuffer = ((config->accumRedBits + - config->accumGreenBits + - config->accumBlueBits + - config->accumAlphaBits) > 0); - config->haveDepthBuffer = (config->depthBits > 0); - config->haveStencilBuffer = (config->stencilBits > 0); -} - -static __GLcontextModes * -createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, - int screen, GLboolean tagged_only) -{ - INT32 buf[__GLX_TOTAL_CONFIG], *props; - unsigned prop_size; - __GLcontextModes *modes, *m; - int i; - - if (nprops == 0) - return NULL; - - /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */ - - /* Check number of properties */ - if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS) - return NULL; - - /* Allocate memory for our config structure */ - modes = x11_context_modes_create(nvisuals); - if (!modes) - return NULL; - - prop_size = nprops * __GLX_SIZE_INT32; - if (prop_size <= sizeof(buf)) - props = buf; - else - props = Xmalloc(prop_size); - - /* Read each config structure and convert it into our format */ - m = modes; - for (i = 0; i < nvisuals; i++) { - _XRead(dpy, (char *) props, prop_size); - /* Older X servers don't send this so we default it here. */ - m->drawableType = GLX_WINDOW_BIT; - __glXInitializeVisualConfigFromTags(m, nprops, props, - tagged_only, GL_TRUE); - m->screen = screen; - m = m->next; - } - - if (props != buf) - Xfree(props); - - return modes; -} - -static GLboolean -getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen) -{ - xGLXGetVisualConfigsReq *req; - __GLXscreenConfigs *psc; - xGLXGetVisualConfigsReply reply; - - LockDisplay(dpy); - - psc = priv->screenConfigs + screen; - psc->visuals = NULL; - GetReq(GLXGetVisualConfigs, req); - req->reqType = priv->majorOpcode; - req->glxCode = X_GLXGetVisualConfigs; - req->screen = screen; - - if (!_XReply(dpy, (xReply *) & reply, 0, False)) - goto out; - - psc->visuals = createConfigsFromProperties(dpy, - reply.numVisuals, - reply.numProps, - screen, GL_FALSE); - - out: - UnlockDisplay(dpy); - return psc->visuals != NULL; -} - -static GLboolean -getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen) -{ - xGLXGetFBConfigsReq *fb_req; - xGLXGetFBConfigsSGIXReq *sgi_req; - xGLXVendorPrivateWithReplyReq *vpreq; - xGLXGetFBConfigsReply reply; - __GLXscreenConfigs *psc; - - psc = priv->screenConfigs + screen; - psc->serverGLXexts = - __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS); - - LockDisplay(dpy); - - psc->configs = NULL; - if (atof(priv->serverGLXversion) >= 1.3) { - GetReq(GLXGetFBConfigs, fb_req); - fb_req->reqType = priv->majorOpcode; - fb_req->glxCode = X_GLXGetFBConfigs; - fb_req->screen = screen; - } - else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) { - GetReqExtra(GLXVendorPrivateWithReply, - sz_xGLXGetFBConfigsSGIXReq + - sz_xGLXVendorPrivateWithReplyReq, vpreq); - sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq; - sgi_req->reqType = priv->majorOpcode; - sgi_req->glxCode = X_GLXVendorPrivateWithReply; - sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX; - sgi_req->screen = screen; - } - else - goto out; - - if (!_XReply(dpy, (xReply *) & reply, 0, False)) - goto out; - - psc->configs = createConfigsFromProperties(dpy, - reply.numFBConfigs, - reply.numAttribs * 2, - screen, GL_TRUE); - - out: - UnlockDisplay(dpy); - return psc->configs != NULL; -} - -static GLboolean -AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) -{ - __GLXscreenConfigs *psc; - GLint i, screens; - - /* - ** First allocate memory for the array of per screen configs. - */ - screens = ScreenCount(dpy); - psc = (__GLXscreenConfigs *) Xmalloc(screens * sizeof(__GLXscreenConfigs)); - if (!psc) { - return GL_FALSE; - } - memset(psc, 0, screens * sizeof(__GLXscreenConfigs)); - priv->screenConfigs = psc; - - priv->serverGLXversion = - __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION); - if (priv->serverGLXversion == NULL) { - FreeScreenConfigs(priv); - return GL_FALSE; - } - - for (i = 0; i < screens; i++, psc++) { - getFBConfigs(dpy, priv, i); - getVisualConfigs(dpy, priv, i); - psc->scr = i; - psc->dpy = dpy; - } - - SyncHandle(); - - return GL_TRUE; -} - -_X_HIDDEN void -__glXRelease(__GLXdisplayPrivate *dpyPriv) -{ - FreeScreenConfigs(dpyPriv); - - if (dpyPriv->serverGLXvendor) { - Xfree((char *) dpyPriv->serverGLXvendor); - dpyPriv->serverGLXvendor = NULL; - } - if (dpyPriv->serverGLXversion) { - Xfree((char *) dpyPriv->serverGLXversion); - dpyPriv->serverGLXversion = NULL; - } - - Xfree(dpyPriv); -} - -_X_HIDDEN __GLXdisplayPrivate * -__glXInitialize(Display * dpy) -{ - XExtDisplayInfo *info = __glXFindDisplay(dpy); - __GLXdisplayPrivate *dpyPriv; - int major, minor; - - if (!XextHasExtension(info)) - return NULL; - - /* See if the versions are compatible */ - if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor)) - return NULL; - - dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate)); - if (!dpyPriv) - return NULL; - - /* - ** Init the display private and then read in the screen config - ** structures from the server. - */ - dpyPriv->majorOpcode = info->codes->major_opcode; - dpyPriv->majorVersion = major; - dpyPriv->minorVersion = minor; - dpyPriv->dpy = dpy; - - dpyPriv->serverGLXvendor = NULL; - dpyPriv->serverGLXversion = NULL; - - if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { - Xfree(dpyPriv); - return NULL; - } - - return dpyPriv; -} diff --git a/src/gallium/state_trackers/egl_g3d/x11/glxinit.h b/src/gallium/state_trackers/egl_g3d/x11/glxinit.h deleted file mode 100644 index 515a825222..0000000000 --- a/src/gallium/state_trackers/egl_g3d/x11/glxinit.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef GLXINIT_INCLUDED -#define GLXINIT_INCLUDED - -#include - -#ifndef GLX_DIRECT_RENDERING -#define GLX_DIRECT_RENDERING -#endif -#include "glxclient.h" - -extern void -__glXRelease(__GLXdisplayPrivate *dpyPriv); - -#endif /* GLXINIT_INCLUDED */ diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c index fef7878ab9..76ce45ee57 100644 --- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c +++ b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c @@ -42,6 +42,10 @@ struct x11_screen { Display *dpy; int number; + /* + * This is used to fetch GLX visuals/fbconfigs. It uses code from egl_xdri. + * It might be better to rewrite the part in Xlib or XCB. + */ __GLXdisplayPrivate *glx_dpy; int dri_major, dri_minor; @@ -93,8 +97,8 @@ x11_screen_destroy(struct x11_screen *xscr) if (xscr->dri_device) Xfree(xscr->dri_device); - if (xscr->glx_dpy) - __glXRelease(xscr->glx_dpy); + /* xscr->glx_dpy will be destroyed with the X display */ + if (xscr->visuals) XFree(xscr->visuals); free(xscr); -- cgit v1.2.3 From 52d7b2cedee44fbd9a0e6405b974c62898bed169 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 22 Jan 2010 15:18:45 +0800 Subject: st/egl: Remove the egl state tracker. The egl_g3d state tracker has support for KMS, and the support is based on the egl state tracker. As egl_g3d provides more features, it should be better to keep only egl_g3d to unify the efforts. --- configs/linux-dri | 2 +- configs/linux-opengl-es | 5 +- configure.ac | 6 +- src/gallium/state_trackers/egl/Makefile | 19 -- src/gallium/state_trackers/egl/egl_context.c | 105 ------- src/gallium/state_trackers/egl/egl_surface.c | 443 --------------------------- src/gallium/state_trackers/egl/egl_tracker.c | 272 ---------------- src/gallium/state_trackers/egl/egl_tracker.h | 195 ------------ src/gallium/state_trackers/egl/egl_visual.c | 85 ----- src/gallium/winsys/drm/i965/egl/Makefile | 29 -- src/gallium/winsys/drm/intel/egl/Makefile | 38 --- src/gallium/winsys/drm/intel/egl/dummy.c | 1 - src/gallium/winsys/drm/radeon/egl/Makefile | 38 --- src/gallium/winsys/drm/radeon/egl/dummy.c | 1 - src/gallium/winsys/drm/vmware/egl/Makefile | 18 -- 15 files changed, 8 insertions(+), 1249 deletions(-) delete mode 100644 src/gallium/state_trackers/egl/Makefile delete mode 100644 src/gallium/state_trackers/egl/egl_context.c delete mode 100644 src/gallium/state_trackers/egl/egl_surface.c delete mode 100644 src/gallium/state_trackers/egl/egl_tracker.c delete mode 100644 src/gallium/state_trackers/egl/egl_tracker.h delete mode 100644 src/gallium/state_trackers/egl/egl_visual.c delete mode 100644 src/gallium/winsys/drm/i965/egl/Makefile delete mode 100644 src/gallium/winsys/drm/intel/egl/Makefile delete mode 100644 src/gallium/winsys/drm/intel/egl/dummy.c delete mode 100644 src/gallium/winsys/drm/radeon/egl/Makefile delete mode 100644 src/gallium/winsys/drm/radeon/egl/dummy.c delete mode 100644 src/gallium/winsys/drm/vmware/egl/Makefile (limited to 'src/gallium/state_trackers') diff --git a/configs/linux-dri b/configs/linux-dri index 95f77ade1d..feb2bba3a0 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -61,7 +61,7 @@ DRIVER_DIRS = dri WINDOW_SYSTEM = dri GALLIUM_WINSYS_DIRS = drm GALLIUM_WINSYS_DRM_DIRS = vmware intel i965 -GALLIUM_STATE_TRACKERS_DIRS = egl +GALLIUM_STATE_TRACKERS_DIRS = egl_g3d DRI_DIRS = i810 i915 i965 mach64 mga r128 r200 r300 radeon \ savage sis tdfx unichrome ffb swrast diff --git a/configs/linux-opengl-es b/configs/linux-opengl-es index 566cd758e3..e013658716 100644 --- a/configs/linux-opengl-es +++ b/configs/linux-opengl-es @@ -9,6 +9,9 @@ LIB_DIR = lib SRC_DIRS = egl glsl mesa/es gallium gallium/winsys PROGRAM_DIRS = es1/screen es1/xegl es2/xegl +# egl_g3d needs this +DEFINES += -DGLX_DIRECT_RENDERING + # no mesa or egl drivers DRIVER_DIRS = EGL_DRIVERS_DIRS = @@ -22,6 +25,6 @@ GALLIUM_STATE_TRACKERS_DIRS = es # build egl_i915.so GALLIUM_DRIVERS_DIRS += trace i915 -GALLIUM_STATE_TRACKERS_DIRS += egl +GALLIUM_STATE_TRACKERS_DIRS += egl_g3d GALLIUM_WINSYS_DIRS += drm GALLIUM_WINSYS_DRM_DIRS = intel diff --git a/configure.ac b/configure.ac index e5c2386320..bb011abff2 100644 --- a/configure.ac +++ b/configure.ac @@ -1165,7 +1165,7 @@ yes) dri) GALLIUM_STATE_TRACKERS_DIRS="dri" if test "x$enable_egl" = xyes; then - GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl egl_g3d" + GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl_g3d" fi # Have only tested st/xorg on 1.6.0 servers PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0], @@ -1182,9 +1182,9 @@ yes) AC_MSG_ERROR([state tracker '$tracker' doesn't exist]) case "$tracker" in - egl) + egl_g3d) if test "x$enable_egl" != xyes; then - AC_MSG_ERROR([cannot build egl state tracker without EGL library]) + AC_MSG_ERROR([cannot build egl_g3d state tracker without EGL library]) fi ;; xorg) diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile deleted file mode 100644 index e825aa718b..0000000000 --- a/src/gallium/state_trackers/egl/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -TOP = ../../../.. -include $(TOP)/configs/current - -LIBNAME = egldrm - -LIBRARY_INCLUDES = \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/mesa/drivers/dri/common \ - -I$(TOP)/src/mesa \ - -I$(TOP)/include \ - -I$(TOP)/src/egl/main \ - $(shell pkg-config --cflags-only-I libdrm) - - -C_SOURCES = $(wildcard ./*.c) - - -include ../../Makefile.template diff --git a/src/gallium/state_trackers/egl/egl_context.c b/src/gallium/state_trackers/egl/egl_context.c deleted file mode 100644 index fee186c601..0000000000 --- a/src/gallium/state_trackers/egl/egl_context.c +++ /dev/null @@ -1,105 +0,0 @@ - -#include "utils.h" -#include -#include -#include -#include "egl_tracker.h" - -#include "egllog.h" - - -#include "pipe/p_context.h" -#include "pipe/p_screen.h" - -#include "state_tracker/st_public.h" -#include "state_tracker/drm_api.h" - -#include "GL/internal/glcore.h" - -_EGLContext * -drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list) -{ - struct drm_device *dev = lookup_drm_device(dpy); - struct drm_context *ctx; - struct drm_context *share = NULL; - struct st_context *st_share = NULL; - int i; - __GLcontextModes *visual; - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs defined for now */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); - return EGL_NO_CONTEXT; - } - } - - ctx = (struct drm_context *) calloc(1, sizeof(struct drm_context)); - if (!ctx) - goto err_c; - - _eglInitContext(drv, &ctx->base, conf, attrib_list); - - ctx->pipe = dev->api->create_context(dev->api, dev->screen); - if (!ctx->pipe) - goto err_pipe; - - if (share) - st_share = share->st; - - visual = drm_visual_from_config(conf); - ctx->st = st_create_context(ctx->pipe, visual, st_share); - drm_visual_modes_destroy(visual); - - if (!ctx->st) - goto err_gl; - - return &ctx->base; - -err_gl: - ctx->pipe->destroy(ctx->pipe); -err_pipe: - free(ctx); -err_c: - return NULL; -} - -EGLBoolean -drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context) -{ - struct drm_context *c = lookup_drm_context(context); - if (!_eglIsContextBound(&c->base)) { - st_destroy_context(c->st); - free(c); - } - return EGL_TRUE; -} - -EGLBoolean -drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context) -{ - struct drm_surface *readSurf = lookup_drm_surface(read); - struct drm_surface *drawSurf = lookup_drm_surface(draw); - struct drm_context *ctx = lookup_drm_context(context); - EGLBoolean b; - - b = _eglMakeCurrent(drv, dpy, draw, read, context); - if (!b) - return EGL_FALSE; - - if (ctx) { - if (!drawSurf || !readSurf) - return EGL_FALSE; - - st_make_current(ctx->st, drawSurf->stfb, readSurf->stfb); - - /* st_resize_framebuffer needs a bound context to work */ - st_resize_framebuffer(drawSurf->stfb, drawSurf->w, drawSurf->h); - st_resize_framebuffer(readSurf->stfb, readSurf->w, readSurf->h); - } else { - st_make_current(NULL, NULL, NULL); - } - - return EGL_TRUE; -} diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c deleted file mode 100644 index d55aa51b82..0000000000 --- a/src/gallium/state_trackers/egl/egl_surface.c +++ /dev/null @@ -1,443 +0,0 @@ - -#include -#include -#include -#include "egl_tracker.h" - -#include "egllog.h" - -#include "pipe/p_inlines.h" -#include "pipe/p_screen.h" -#include "pipe/p_context.h" - -#include "state_tracker/drm_api.h" - -#include "util/u_format.h" -#include "util/u_rect.h" - -/* - * Util functions - */ - -static drmModeModeInfoPtr -drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode) -{ - int i; - drmModeModeInfoPtr m = NULL; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) - break; - m = &connector->modes[0]; /* if we can't find one, return first */ - } - - return m; -} - -static struct st_framebuffer * -drm_create_framebuffer(struct pipe_screen *screen, - const __GLcontextModes *visual, - unsigned width, - unsigned height, - void *priv) -{ - enum pipe_format color_format, depth_stencil_format; - boolean d_depth_bits_last; - boolean ds_depth_bits_last; - - d_depth_bits_last = - screen->is_format_supported(screen, PIPE_FORMAT_X8Z24_UNORM, - PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); - ds_depth_bits_last = - screen->is_format_supported(screen, PIPE_FORMAT_S8Z24_UNORM, - PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); - - if (visual->redBits == 8) { - if (visual->alphaBits == 8) - color_format = PIPE_FORMAT_A8R8G8B8_UNORM; - else - color_format = PIPE_FORMAT_X8R8G8B8_UNORM; - } else { - color_format = PIPE_FORMAT_R5G6B5_UNORM; - } - - switch(visual->depthBits) { - default: - case 0: - depth_stencil_format = PIPE_FORMAT_NONE; - break; - case 16: - depth_stencil_format = PIPE_FORMAT_Z16_UNORM; - break; - case 24: - if (visual->stencilBits == 0) { - depth_stencil_format = (d_depth_bits_last) ? - PIPE_FORMAT_X8Z24_UNORM: - PIPE_FORMAT_Z24X8_UNORM; - } else { - depth_stencil_format = (ds_depth_bits_last) ? - PIPE_FORMAT_S8Z24_UNORM: - PIPE_FORMAT_Z24S8_UNORM; - } - break; - case 32: - depth_stencil_format = PIPE_FORMAT_Z32_UNORM; - break; - } - - return st_create_framebuffer(visual, - color_format, - depth_stencil_format, - depth_stencil_format, - width, - height, - priv); -} - -static void -drm_create_texture(_EGLDisplay *dpy, - struct drm_screen *scrn, - unsigned w, unsigned h) -{ - struct drm_device *dev = lookup_drm_device(dpy); - struct pipe_screen *screen = dev->screen; - struct pipe_surface *surface; - struct pipe_texture *texture; - struct pipe_texture templat; - struct pipe_buffer *buf = NULL; - unsigned pitch = 0; - - memset(&templat, 0, sizeof(templat)); - templat.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; - templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; - templat.target = PIPE_TEXTURE_2D; - templat.last_level = 0; - templat.depth0 = 1; - templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; - templat.width0 = w; - templat.height0 = h; - - texture = screen->texture_create(dev->screen, - &templat); - - if (!texture) - goto err_tex; - - surface = screen->get_tex_surface(screen, - texture, - 0, - 0, - 0, - PIPE_BUFFER_USAGE_GPU_WRITE); - - if (!surface) - goto err_surf; - - scrn->tex = texture; - scrn->surface = surface; - scrn->front.width = w; - scrn->front.height = h; - scrn->front.pitch = pitch; - dev->api->local_handle_from_texture(dev->api, screen, texture, - &scrn->front.pitch, &scrn->front.handle); - if (0) - goto err_handle; - - return; - -err_handle: - pipe_surface_reference(&surface, NULL); -err_surf: - pipe_texture_reference(&texture, NULL); -err_tex: - pipe_buffer_reference(&buf, NULL); - return; -} - -/* - * Exported functions - */ - -void -drm_takedown_shown_screen(_EGLDisplay *dpy, struct drm_screen *screen) -{ - struct drm_device *dev = lookup_drm_device(dpy); - - screen->surf = NULL; - - drmModeSetCrtc( - dev->drmFD, - screen->crtcID, - 0, /* FD */ - 0, 0, - NULL, 0, /* List of output ids */ - NULL); - - drmModeRmFB(dev->drmFD, screen->fbID); - drmModeFreeFB(screen->fb); - screen->fb = NULL; - - pipe_surface_reference(&screen->surface, NULL); - pipe_texture_reference(&screen->tex, NULL); - - screen->shown = 0; -} - -/** - * Called by libEGL's eglCreateWindowSurface(). - */ -_EGLSurface * -drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list) -{ - return NULL; -} - - -/** - * Called by libEGL's eglCreatePixmapSurface(). - */ -_EGLSurface * -drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list) -{ - return NULL; -} - - -/** - * Called by libEGL's eglCreatePbufferSurface(). - */ -_EGLSurface * -drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - const EGLint *attrib_list) -{ - struct drm_device *dev = lookup_drm_device(dpy); - int i; - int width = -1; - int height = -1; - struct drm_surface *surf = NULL; - __GLcontextModes *visual; - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - case EGL_WIDTH: - width = attrib_list[++i]; - break; - case EGL_HEIGHT: - height = attrib_list[++i]; - break; - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); - return EGL_NO_SURFACE; - } - } - - if (width < 1 || height < 1) { - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); - return NULL; - } - - surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface)); - if (!surf) - goto err; - - if (!_eglInitSurface(drv, &surf->base, EGL_PBUFFER_BIT, conf, attrib_list)) - goto err_surf; - - surf->w = width; - surf->h = height; - - visual = drm_visual_from_config(conf); - surf->stfb = drm_create_framebuffer(dev->screen, visual, - width, height, - (void*)surf); - drm_visual_modes_destroy(visual); - - return &surf->base; - -err_surf: - free(surf); -err: - return NULL; -} - -/** - * Called by libEGL's eglCreateScreenSurfaceMESA(). - */ -_EGLSurface * -drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *cfg, - const EGLint *attrib_list) -{ - EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list); - - return surf; -} - -/** - * Called by libEGL's eglShowScreenSurfaceMESA(). - */ -EGLBoolean -drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLScreen *screen, - _EGLSurface *surface, _EGLMode *mode) -{ - struct drm_device *dev = lookup_drm_device(dpy); - struct drm_surface *surf = lookup_drm_surface(surface); - struct drm_screen *scrn = lookup_drm_screen(screen); - int ret; - unsigned int i, k; - - if (scrn->shown) - drm_takedown_shown_screen(dpy, scrn); - - - drm_create_texture(dpy, scrn, mode->Width, mode->Height); - if (!scrn->tex) - goto err_tex; - - ret = drmModeAddFB(dev->drmFD, - scrn->front.width, scrn->front.height, - 32, 32, scrn->front.pitch, - scrn->front.handle, - &scrn->fbID); - - if (ret) - goto err_bo; - - scrn->fb = drmModeGetFB(dev->drmFD, scrn->fbID); - if (!scrn->fb) - goto err_bo; - - /* find a fitting crtc */ - { - drmModeConnector *con = scrn->connector; - - scrn->mode = drm_find_mode(con, mode); - if (!scrn->mode) - goto err_fb; - - for (k = 0; k < con->count_encoders; k++) { - drmModeEncoder *enc = drmModeGetEncoder(dev->drmFD, con->encoders[k]); - for (i = 0; i < dev->res->count_crtcs; i++) { - if (enc->possible_crtcs & (1<crtcID = dev->res->crtcs[i]; - - /* skip the rest */ - i = dev->res->count_crtcs; - k = dev->res->count_encoders; - } - } - drmModeFreeEncoder(enc); - } - } - - ret = drmModeSetCrtc(dev->drmFD, - scrn->crtcID, - scrn->fbID, - 0, 0, - &scrn->connectorID, 1, - scrn->mode); - - if (ret) - goto err_crtc; - - - if (scrn->dpms) - drmModeConnectorSetProperty(dev->drmFD, - scrn->connectorID, - scrn->dpms->prop_id, - DRM_MODE_DPMS_ON); - - surf->screen = scrn; - - scrn->surf = surf; - scrn->shown = 1; - - return EGL_TRUE; - -err_crtc: - scrn->crtcID = 0; - -err_fb: - drmModeRmFB(dev->drmFD, scrn->fbID); - drmModeFreeFB(scrn->fb); - scrn->fb = NULL; - -err_bo: - pipe_surface_reference(&scrn->surface, NULL); - pipe_texture_reference(&scrn->tex, NULL); - -err_tex: - return EGL_FALSE; -} - -/** - * Called by libEGL's eglDestroySurface(). - */ -EGLBoolean -drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface) -{ - struct drm_surface *surf = lookup_drm_surface(surface); - if (!_eglIsSurfaceBound(&surf->base)) { - if (surf->screen) - drm_takedown_shown_screen(dpy, surf->screen); - st_unreference_framebuffer(surf->stfb); - free(surf); - } - return EGL_TRUE; -} - -/** - * Called by libEGL's eglSwapBuffers(). - */ -EGLBoolean -drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw) -{ - struct drm_device *dev = lookup_drm_device(dpy); - struct drm_surface *surf = lookup_drm_surface(draw); - struct pipe_surface *back_surf; - - if (!surf) - return EGL_FALSE; - - st_get_framebuffer_surface(surf->stfb, ST_SURFACE_BACK_LEFT, &back_surf); - - if (back_surf) { - struct drm_context *ctx = lookup_drm_context(draw->Binding); - - st_notify_swapbuffers(surf->stfb); - - if (ctx && surf->screen) { - if (ctx->pipe->surface_copy) { - ctx->pipe->surface_copy(ctx->pipe, - surf->screen->surface, - 0, 0, - back_surf, - 0, 0, - surf->w, surf->h); - } else { - util_surface_copy(ctx->pipe, FALSE, - surf->screen->surface, - 0, 0, - back_surf, - 0, 0, - surf->w, surf->h); - } - ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL); - -#ifdef DRM_MODE_FEATURE_DIRTYFB - /* TODO query connector property to see if this is needed */ - drmModeDirtyFB(dev->drmFD, surf->screen->fbID, NULL, 0); -#else - (void)dev; -#endif - - /* TODO more stuff here */ - } - } - - return EGL_TRUE; -} diff --git a/src/gallium/state_trackers/egl/egl_tracker.c b/src/gallium/state_trackers/egl/egl_tracker.c deleted file mode 100644 index 11583ec41c..0000000000 --- a/src/gallium/state_trackers/egl/egl_tracker.c +++ /dev/null @@ -1,272 +0,0 @@ - -#include "utils.h" - -#include -#include -#include -#include "egl_tracker.h" - -#include - -#include "egllog.h" -#include "state_tracker/drm_api.h" - -#include "pipe/p_screen.h" -#include "pipe/internal/p_winsys_screen.h" - -/** HACK */ -void* driDriverAPI; - - -/* - * Exported functions - */ - -/** Called by libEGL just prior to unloading/closing the driver. - */ -static void -drm_unload(_EGLDriver *drv) -{ - free(drv); -} - -/** - * The bootstrap function. Return a new drm_driver object and - * plug in API functions. - * libEGL finds this function with dlopen()/dlsym() and calls it from - * "load driver" function. - */ -_EGLDriver * -_eglMain(const char *args) -{ - _EGLDriver *drv; - - drv = (_EGLDriver *) calloc(1, sizeof(_EGLDriver)); - if (!drv) { - return NULL; - } - - /* First fill in the dispatch table with defaults */ - _eglInitDriverFallbacks(drv); - /* then plug in our Drm-specific functions */ - drv->API.Initialize = drm_initialize; - drv->API.Terminate = drm_terminate; - drv->API.CreateContext = drm_create_context; - drv->API.MakeCurrent = drm_make_current; - drv->API.CreateWindowSurface = drm_create_window_surface; - drv->API.CreatePixmapSurface = drm_create_pixmap_surface; - drv->API.CreatePbufferSurface = drm_create_pbuffer_surface; - drv->API.DestroySurface = drm_destroy_surface; - drv->API.DestroyContext = drm_destroy_context; - drv->API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa; - drv->API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa; - drv->API.SwapBuffers = drm_swap_buffers; - - drv->Name = "DRM/Gallium/Win"; - drv->Unload = drm_unload; - - return drv; -} - -static void -drm_get_device_id(struct drm_device *device) -{ - char path[512]; - FILE *file; - char *ret; - - /* TODO get the real minor */ - int minor = 0; - - device->deviceID = 0; - - snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor); - file = fopen(path, "r"); - if (!file) { - _eglLog(_EGL_WARNING, "Could not retrive device ID\n"); - return; - } - - ret = fgets(path, sizeof( path ), file); - fclose(file); - if (!ret) - return; - - sscanf(path, "%x", &device->deviceID); -} - -static void -drm_update_res(struct drm_device *dev) -{ - drmModeFreeResources(dev->res); - dev->res = drmModeGetResources(dev->drmFD); -} - -static void -drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) -{ - drmModeModeInfoPtr m = NULL; - int i; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name); - } -} - -static void -drm_find_dpms(struct drm_device *dev, struct drm_screen *screen) -{ - drmModeConnectorPtr c = screen->connector; - drmModePropertyPtr p; - int i; - - for (i = 0; i < c->count_props; i++) { - p = drmModeGetProperty(dev->drmFD, c->props[i]); - if (!strcmp(p->name, "DPMS")) - break; - - drmModeFreeProperty(p); - p = NULL; - } - - screen->dpms = p; -} - -static int drm_open_minor(int minor) -{ - char buf[64]; - - sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); - return open(buf, O_RDWR, 0); -} - -EGLBoolean -drm_initialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor) -{ - struct drm_device *dev; - struct drm_screen *screen = NULL; - drmModeConnectorPtr connector = NULL; - drmModeResPtr res = NULL; - unsigned count_connectors = 0; - int num_screens = 0; - EGLint i; - int fd; - _EGLConfig *config; - - dev = (struct drm_device *) calloc(1, sizeof(struct drm_device)); - if (!dev) - return EGL_FALSE; - dev->api = drm_api_create(); - - /* try the first node */ - fd = drm_open_minor(0); - if (fd < 0) - goto err_fd; - - dev->drmFD = fd; - drm_get_device_id(dev); - - dev->screen = dev->api->create_screen(dev->api, dev->drmFD, NULL); - if (!dev->screen) - goto err_screen; - dev->winsys = dev->screen->winsys; - - drm_update_res(dev); - res = dev->res; - if (res) - count_connectors = res->count_connectors; - else - _eglLog(_EGL_WARNING, "Could not retrive kms information\n"); - - for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) { - connector = drmModeGetConnector(fd, res->connectors[i]); - - if (!connector) - continue; - - if (connector->connection != DRM_MODE_CONNECTED) { - drmModeFreeConnector(connector); - continue; - } - - screen = malloc(sizeof(struct drm_screen)); - memset(screen, 0, sizeof(*screen)); - screen->connector = connector; - screen->connectorID = connector->connector_id; - _eglInitScreen(&screen->base); - _eglAddScreen(disp, &screen->base); - drm_add_modes_from_connector(&screen->base, connector); - drm_find_dpms(dev, screen); - dev->screens[num_screens++] = screen; - } - dev->count_screens = num_screens; - - disp->DriverData = dev; - - /* for now we only have one config */ - config = calloc(1, sizeof(*config)); - memset(config, 1, sizeof(*config)); - _eglInitConfig(config, 1); - _eglSetConfigAttrib(config, EGL_RED_SIZE, 8); - _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8); - _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32); - _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24); - _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8); - _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); - _eglAddConfig(disp, config); - - disp->ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; - /* enable supported extensions */ - disp->Extensions.MESA_screen_surface = EGL_TRUE; - disp->Extensions.MESA_copy_context = EGL_TRUE; - - *major = 1; - *minor = 4; - - return EGL_TRUE; - -err_screen: - drmClose(fd); -err_fd: - free(dev); - return EGL_FALSE; -} - -EGLBoolean -drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy) -{ - struct drm_device *dev = lookup_drm_device(dpy); - struct drm_screen *screen; - int i = 0; - - _eglReleaseDisplayResources(drv, dpy); - _eglCleanupDisplay(dpy); - - drmFreeVersion(dev->version); - - for (i = 0; i < dev->count_screens; i++) { - screen = dev->screens[i]; - - if (screen->shown) - drm_takedown_shown_screen(dpy, screen); - - drmModeFreeProperty(screen->dpms); - drmModeFreeConnector(screen->connector); - _eglDestroyScreen(&screen->base); - dev->screens[i] = NULL; - } - - dev->screen->destroy(dev->screen); - dev->winsys = NULL; - - drmClose(dev->drmFD); - - dev->api->destroy(dev->api); - free(dev); - dpy->DriverData = NULL; - - return EGL_TRUE; -} diff --git a/src/gallium/state_trackers/egl/egl_tracker.h b/src/gallium/state_trackers/egl/egl_tracker.h deleted file mode 100644 index 73eb1a1226..0000000000 --- a/src/gallium/state_trackers/egl/egl_tracker.h +++ /dev/null @@ -1,195 +0,0 @@ - -#ifndef _EGL_TRACKER_H_ -#define _EGL_TRACKER_H_ - -#include - -#include "eglconfig.h" -#include "eglcontext.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "eglmode.h" -#include "eglscreen.h" -#include "eglsurface.h" - -#include "xf86drm.h" -#include "xf86drmMode.h" - -#include "pipe/p_compiler.h" - -#include "state_tracker/st_public.h" - -#define MAX_SCREENS 16 - -struct pipe_winsys; -struct pipe_screen; -struct pipe_context; -struct state_tracker; - -struct drm_screen; -struct drm_context; - -struct drm_device -{ - /* - * pipe - */ - - struct drm_api *api; - struct pipe_winsys *winsys; - struct pipe_screen *screen; - - /* - * drm - */ - - int drmFD; - drmVersionPtr version; - int deviceID; - - drmModeResPtr res; - - struct drm_screen *screens[MAX_SCREENS]; - size_t count_screens; -}; - -struct drm_surface -{ - _EGLSurface base; /* base class/object */ - - /* - * pipe - */ - - - struct st_framebuffer *stfb; - - /* - * drm - */ - - struct drm_screen *screen; - - int w; - int h; -}; - -struct drm_context -{ - _EGLContext base; /* base class/object */ - - /* pipe */ - - struct pipe_context *pipe; - struct st_context *st; -}; - -struct drm_screen -{ - _EGLScreen base; - - /* - * pipe - */ - - struct pipe_texture *tex; - struct pipe_surface *surface; - - /* - * drm - */ - - struct { - unsigned height; - unsigned width; - unsigned pitch; - unsigned handle; - } front; - - /* currently only support one connector */ - drmModeConnectorPtr connector; - uint32_t connectorID; - - /* dpms property */ - drmModePropertyPtr dpms; - - /* Has this screen been shown */ - int shown; - - /* Surface that is currently attached to this screen */ - struct drm_surface *surf; - - /* framebuffer */ - drmModeFBPtr fb; - uint32_t fbID; - - /* crtc and mode used */ - /*drmModeCrtcPtr crtc;*/ - uint32_t crtcID; - - drmModeModeInfoPtr mode; -}; - - -static INLINE struct drm_device * -lookup_drm_device(_EGLDisplay *d) -{ - return (struct drm_device *) d->DriverData; -} - - -static INLINE struct drm_context * -lookup_drm_context(_EGLContext *c) -{ - return (struct drm_context *) c; -} - - -static INLINE struct drm_surface * -lookup_drm_surface(_EGLSurface *s) -{ - return (struct drm_surface *) s; -} - -static INLINE struct drm_screen * -lookup_drm_screen(_EGLScreen *s) -{ - return (struct drm_screen *) s; -} - -/** - * egl_visual.h - */ -/*@{*/ -void drm_visual_modes_destroy(__GLcontextModes *modes); -__GLcontextModes* drm_visual_modes_create(unsigned count, size_t minimum_size); -__GLcontextModes* drm_visual_from_config(_EGLConfig *conf); -/*@}*/ - -/** - * egl_surface.h - */ -/*@{*/ -void drm_takedown_shown_screen(_EGLDisplay *dpy, struct drm_screen *screen); -/*@}*/ - -/** - * All function exported to the egl side. - */ -/*@{*/ -EGLBoolean drm_initialize(_EGLDriver *drv, _EGLDisplay *dpy, EGLint *major, EGLint *minor); -EGLBoolean drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy); -_EGLContext *drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list); -EGLBoolean drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context); -_EGLSurface *drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list); -_EGLSurface *drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list); -_EGLSurface *drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list); -_EGLSurface *drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list); -EGLBoolean drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface *surface, _EGLMode *mode); -EGLBoolean drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface); -EGLBoolean drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context); -EGLBoolean drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw); -/*@}*/ - -#endif diff --git a/src/gallium/state_trackers/egl/egl_visual.c b/src/gallium/state_trackers/egl/egl_visual.c deleted file mode 100644 index e59f893851..0000000000 --- a/src/gallium/state_trackers/egl/egl_visual.c +++ /dev/null @@ -1,85 +0,0 @@ - -#include "egl_tracker.h" - -#include "egllog.h" - -void -drm_visual_modes_destroy(__GLcontextModes *modes) -{ - _eglLog(_EGL_DEBUG, "%s", __FUNCTION__); - - while (modes) { - __GLcontextModes * const next = modes->next; - free(modes); - modes = next; - } -} - -__GLcontextModes * -drm_visual_modes_create(unsigned count, size_t minimum_size) -{ - /* This code copied from libGLX, and modified */ - const size_t size = (minimum_size > sizeof(__GLcontextModes)) - ? minimum_size : sizeof(__GLcontextModes); - __GLcontextModes * head = NULL; - __GLcontextModes ** next; - unsigned i; - - _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size); - - next = & head; - for (i = 0 ; i < count ; i++) { - *next = (__GLcontextModes *) calloc(1, size); - if (*next == NULL) { - drm_visual_modes_destroy(head); - head = NULL; - break; - } - - (*next)->doubleBufferMode = 1; - (*next)->visualID = GLX_DONT_CARE; - (*next)->visualType = GLX_DONT_CARE; - (*next)->visualRating = GLX_NONE; - (*next)->transparentPixel = GLX_NONE; - (*next)->transparentRed = GLX_DONT_CARE; - (*next)->transparentGreen = GLX_DONT_CARE; - (*next)->transparentBlue = GLX_DONT_CARE; - (*next)->transparentAlpha = GLX_DONT_CARE; - (*next)->transparentIndex = GLX_DONT_CARE; - (*next)->xRenderable = GLX_DONT_CARE; - (*next)->fbconfigID = GLX_DONT_CARE; - (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; - (*next)->bindToTextureRgb = GLX_DONT_CARE; - (*next)->bindToTextureRgba = GLX_DONT_CARE; - (*next)->bindToMipmapTexture = GLX_DONT_CARE; - (*next)->bindToTextureTargets = 0; - (*next)->yInverted = GLX_DONT_CARE; - - next = & ((*next)->next); - } - - return head; -} - -__GLcontextModes * -drm_visual_from_config(_EGLConfig *conf) -{ - __GLcontextModes *visual; - (void)conf; - - visual = drm_visual_modes_create(1, sizeof(*visual)); - visual->redBits = 8; - visual->greenBits = 8; - visual->blueBits = 8; - visual->alphaBits = 8; - - visual->rgbBits = 32; - visual->doubleBufferMode = 1; - - visual->depthBits = 24; - visual->haveDepthBuffer = visual->depthBits > 0; - visual->stencilBits = 8; - visual->haveStencilBuffer = visual->stencilBits > 0; - - return visual; -} diff --git a/src/gallium/winsys/drm/i965/egl/Makefile b/src/gallium/winsys/drm/i965/egl/Makefile deleted file mode 100644 index a1b32eb2a7..0000000000 --- a/src/gallium/winsys/drm/i965/egl/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -TOP = ../../../../../.. -GALLIUMDIR = ../../../.. -include $(TOP)/configs/current - -LIBNAME = EGL_i965.so - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ - $(GALLIUMDIR)/winsys/drm/i965/gem/libi965drm.a \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/trace/libtrace.a \ - $(TOP)/src/gallium/drivers/i965/libi965.a - -DRIVER_SOURCES = - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) - -DRIVER_EXTRAS = -ldrm_intel - -ASM_SOURCES = - -DRIVER_DEFINES = -I../gem $(shell pkg-config libdrm --atleast-version=2.3.1 \ - && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") - -include ../../Makefile.template - -symlinks: diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile deleted file mode 100644 index c9c92b69b6..0000000000 --- a/src/gallium/winsys/drm/intel/egl/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -TOP = ../../../../../.. -GALLIUMDIR = ../../../.. -include $(TOP)/configs/current - -LIBNAME = egl_i915.so - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ - $(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/trace/libtrace.a \ - $(TOP)/src/gallium/drivers/i915/libi915.a - -DRIVER_EXTRAS = -lm -lpthread -ldrm_intel - -OBJECTS = dummy.o - -default: $(TOP)/$(LIB_DIR)/$(LIBNAME) - -$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) - @mkdir -p $(TOP)/$(LIB_DIR) - $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) - -$(LIBNAME): $(OBJECTS) $(GALLIUM_AUXILIARIES) $(PIPE_DRIVERS) Makefile - $(MKLIB) -noprefix -o $@ $(OBJECTS) \ - -Wl,--whole-archive $(PIPE_DRIVERS) -Wl,--no-whole-archive \ - -Wl,--start-group $(GALLIUM_AUXILIARIES) -Wl,--end-group \ - $(DRI_LIB_DEPS) $(DRIVER_EXTRAS) - -clean: - -rm -f *.o *.so *~ - -depend: - -symlinks: - -install: $(LIBNAME) - $(MINSTALL) -m 755 $(LIBNAME) $(INSTALL_DIR)/$(LIB_DIR) diff --git a/src/gallium/winsys/drm/intel/egl/dummy.c b/src/gallium/winsys/drm/intel/egl/dummy.c deleted file mode 100644 index 58c7af84e0..0000000000 --- a/src/gallium/winsys/drm/intel/egl/dummy.c +++ /dev/null @@ -1 +0,0 @@ -/* mklib expects at least one .o is given */ diff --git a/src/gallium/winsys/drm/radeon/egl/Makefile b/src/gallium/winsys/drm/radeon/egl/Makefile deleted file mode 100644 index fcbfd09786..0000000000 --- a/src/gallium/winsys/drm/radeon/egl/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -TOP = ../../../../../.. -GALLIUMDIR = ../../../.. -include $(TOP)/configs/current - -LIBNAME = egl_radeon.so - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ - $(GALLIUMDIR)/winsys/drm/radeon/core/libradeonwinsys.a \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/trace/libtrace.a \ - $(TOP)/src/gallium/drivers/r300/libr300.a - -DRIVER_EXTRAS = -lm -lpthread -ldrm_radeon - -OBJECTS = dummy.o - -default: $(TOP)/$(LIB_DIR)/$(LIBNAME) - -$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) - @mkdir -p $(TOP)/$(LIB_DIR) - $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) - -$(LIBNAME): $(OBJECTS) $(GALLIUM_AUXILIARIES) $(PIPE_DRIVERS) Makefile - $(MKLIB) -noprefix -o $@ $(OBJECTS) \ - -Wl,--whole-archive $(PIPE_DRIVERS) -Wl,--no-whole-archive \ - -Wl,--start-group $(GALLIUM_AUXILIARIES) -Wl,--end-group \ - $(DRI_LIB_DEPS) $(DRIVER_EXTRAS) - -clean: - -rm -f *.o *.so *~ - -depend: - -symlinks: - -install: $(LIBNAME) - $(MINSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) diff --git a/src/gallium/winsys/drm/radeon/egl/dummy.c b/src/gallium/winsys/drm/radeon/egl/dummy.c deleted file mode 100644 index 58c7af84e0..0000000000 --- a/src/gallium/winsys/drm/radeon/egl/dummy.c +++ /dev/null @@ -1 +0,0 @@ -/* mklib expects at least one .o is given */ diff --git a/src/gallium/winsys/drm/vmware/egl/Makefile b/src/gallium/winsys/drm/vmware/egl/Makefile deleted file mode 100644 index 8e2980c318..0000000000 --- a/src/gallium/winsys/drm/vmware/egl/Makefile +++ /dev/null @@ -1,18 +0,0 @@ - -TOP = ../../../../../.. -include $(TOP)/configs/current - -LIBNAME = EGL_svga.so - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ - $(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \ - $(TOP)/src/gallium/drivers/trace/libtrace.a \ - $(TOP)/src/gallium/drivers/svga/libsvga.a - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) - -include ../../Makefile.template - -symlinks: -- cgit v1.2.3 From 3c967a920718c2a74996ac23b8c1964915db88c2 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 22 Jan 2010 16:31:43 +0800 Subject: st/egl_g3d: Rename to st/egl. Simply the name to egl. --- configs/linux-dri | 2 +- configs/linux-opengl-es | 4 +- configure.ac | 8 +- docs/egl.html | 15 +- docs/opengles.html | 2 +- docs/openvg.html | 2 +- src/gallium/state_trackers/egl/Makefile | 75 ++ src/gallium/state_trackers/egl/common/egl_g3d.c | 1336 ++++++++++++++++++++ src/gallium/state_trackers/egl/common/egl_g3d.h | 127 ++ src/gallium/state_trackers/egl/common/egl_st.c | 131 ++ src/gallium/state_trackers/egl/common/egl_st.h | 73 ++ src/gallium/state_trackers/egl/common/native.h | 277 ++++ .../state_trackers/egl/common/st_public_tmp.h | 20 + src/gallium/state_trackers/egl/kms/native_kms.c | 866 +++++++++++++ src/gallium/state_trackers/egl/kms/native_kms.h | 139 ++ src/gallium/state_trackers/egl/x11/native_dri2.c | 705 +++++++++++ src/gallium/state_trackers/egl/x11/native_x11.c | 148 +++ src/gallium/state_trackers/egl/x11/native_x11.h | 37 + src/gallium/state_trackers/egl/x11/native_ximage.c | 694 ++++++++++ src/gallium/state_trackers/egl/x11/sw_winsys.c | 231 ++++ src/gallium/state_trackers/egl/x11/sw_winsys.h | 40 + src/gallium/state_trackers/egl/x11/x11_screen.c | 453 +++++++ src/gallium/state_trackers/egl/x11/x11_screen.h | 105 ++ src/gallium/state_trackers/egl_g3d/Makefile | 75 -- .../state_trackers/egl_g3d/common/egl_g3d.c | 1336 -------------------- .../state_trackers/egl_g3d/common/egl_g3d.h | 127 -- src/gallium/state_trackers/egl_g3d/common/egl_st.c | 131 -- src/gallium/state_trackers/egl_g3d/common/egl_st.h | 73 -- src/gallium/state_trackers/egl_g3d/common/native.h | 277 ---- .../state_trackers/egl_g3d/common/st_public_tmp.h | 20 - .../state_trackers/egl_g3d/kms/native_kms.c | 866 ------------- .../state_trackers/egl_g3d/kms/native_kms.h | 139 -- .../state_trackers/egl_g3d/x11/native_dri2.c | 705 ----------- .../state_trackers/egl_g3d/x11/native_x11.c | 148 --- .../state_trackers/egl_g3d/x11/native_x11.h | 37 - .../state_trackers/egl_g3d/x11/native_ximage.c | 694 ---------- src/gallium/state_trackers/egl_g3d/x11/sw_winsys.c | 231 ---- src/gallium/state_trackers/egl_g3d/x11/sw_winsys.h | 40 - .../state_trackers/egl_g3d/x11/x11_screen.c | 453 ------- .../state_trackers/egl_g3d/x11/x11_screen.h | 105 -- src/gallium/winsys/drm/Makefile.egl | 65 + src/gallium/winsys/drm/Makefile.egl_g3d | 65 - src/gallium/winsys/drm/i965/egl/Makefile | 14 + src/gallium/winsys/drm/i965/egl/dummy.c | 1 + src/gallium/winsys/drm/i965/egl_g3d/Makefile | 14 - src/gallium/winsys/drm/i965/egl_g3d/dummy.c | 1 - src/gallium/winsys/drm/intel/egl/Makefile | 14 + src/gallium/winsys/drm/intel/egl/dummy.c | 1 + src/gallium/winsys/drm/intel/egl_g3d/Makefile | 14 - src/gallium/winsys/drm/intel/egl_g3d/dummy.c | 1 - src/gallium/winsys/drm/nouveau/egl/Makefile | 19 + src/gallium/winsys/drm/nouveau/egl/dummy.c | 1 + src/gallium/winsys/drm/nouveau/egl_g3d/Makefile | 19 - src/gallium/winsys/drm/nouveau/egl_g3d/dummy.c | 1 - src/gallium/winsys/drm/radeon/egl/Makefile | 14 + src/gallium/winsys/drm/radeon/egl/dummy.c | 1 + src/gallium/winsys/drm/radeon/egl_g3d/Makefile | 14 - src/gallium/winsys/drm/radeon/egl_g3d/dummy.c | 1 - src/gallium/winsys/drm/swrast/egl/Makefile | 12 + src/gallium/winsys/drm/swrast/egl/dummy.c | 1 + src/gallium/winsys/drm/swrast/egl_g3d/Makefile | 12 - src/gallium/winsys/drm/swrast/egl_g3d/dummy.c | 1 - src/gallium/winsys/drm/vmware/egl/Makefile | 14 + src/gallium/winsys/drm/vmware/egl/dummy.c | 1 + src/gallium/winsys/drm/vmware/egl_g3d/Makefile | 14 - src/gallium/winsys/drm/vmware/egl_g3d/dummy.c | 1 - 66 files changed, 5631 insertions(+), 5632 deletions(-) create mode 100644 src/gallium/state_trackers/egl/Makefile create mode 100644 src/gallium/state_trackers/egl/common/egl_g3d.c create mode 100644 src/gallium/state_trackers/egl/common/egl_g3d.h create mode 100644 src/gallium/state_trackers/egl/common/egl_st.c create mode 100644 src/gallium/state_trackers/egl/common/egl_st.h create mode 100644 src/gallium/state_trackers/egl/common/native.h create mode 100644 src/gallium/state_trackers/egl/common/st_public_tmp.h create mode 100644 src/gallium/state_trackers/egl/kms/native_kms.c create mode 100644 src/gallium/state_trackers/egl/kms/native_kms.h create mode 100644 src/gallium/state_trackers/egl/x11/native_dri2.c create mode 100644 src/gallium/state_trackers/egl/x11/native_x11.c create mode 100644 src/gallium/state_trackers/egl/x11/native_x11.h create mode 100644 src/gallium/state_trackers/egl/x11/native_ximage.c create mode 100644 src/gallium/state_trackers/egl/x11/sw_winsys.c create mode 100644 src/gallium/state_trackers/egl/x11/sw_winsys.h create mode 100644 src/gallium/state_trackers/egl/x11/x11_screen.c create mode 100644 src/gallium/state_trackers/egl/x11/x11_screen.h delete mode 100644 src/gallium/state_trackers/egl_g3d/Makefile delete mode 100644 src/gallium/state_trackers/egl_g3d/common/egl_g3d.c delete mode 100644 src/gallium/state_trackers/egl_g3d/common/egl_g3d.h delete mode 100644 src/gallium/state_trackers/egl_g3d/common/egl_st.c delete mode 100644 src/gallium/state_trackers/egl_g3d/common/egl_st.h delete mode 100644 src/gallium/state_trackers/egl_g3d/common/native.h delete mode 100644 src/gallium/state_trackers/egl_g3d/common/st_public_tmp.h delete mode 100644 src/gallium/state_trackers/egl_g3d/kms/native_kms.c delete mode 100644 src/gallium/state_trackers/egl_g3d/kms/native_kms.h delete mode 100644 src/gallium/state_trackers/egl_g3d/x11/native_dri2.c delete mode 100644 src/gallium/state_trackers/egl_g3d/x11/native_x11.c delete mode 100644 src/gallium/state_trackers/egl_g3d/x11/native_x11.h delete mode 100644 src/gallium/state_trackers/egl_g3d/x11/native_ximage.c delete mode 100644 src/gallium/state_trackers/egl_g3d/x11/sw_winsys.c delete mode 100644 src/gallium/state_trackers/egl_g3d/x11/sw_winsys.h delete mode 100644 src/gallium/state_trackers/egl_g3d/x11/x11_screen.c delete mode 100644 src/gallium/state_trackers/egl_g3d/x11/x11_screen.h create mode 100644 src/gallium/winsys/drm/Makefile.egl delete mode 100644 src/gallium/winsys/drm/Makefile.egl_g3d create mode 100644 src/gallium/winsys/drm/i965/egl/Makefile create mode 100644 src/gallium/winsys/drm/i965/egl/dummy.c delete mode 100644 src/gallium/winsys/drm/i965/egl_g3d/Makefile delete mode 100644 src/gallium/winsys/drm/i965/egl_g3d/dummy.c create mode 100644 src/gallium/winsys/drm/intel/egl/Makefile create mode 100644 src/gallium/winsys/drm/intel/egl/dummy.c delete mode 100644 src/gallium/winsys/drm/intel/egl_g3d/Makefile delete mode 100644 src/gallium/winsys/drm/intel/egl_g3d/dummy.c create mode 100644 src/gallium/winsys/drm/nouveau/egl/Makefile create mode 100644 src/gallium/winsys/drm/nouveau/egl/dummy.c delete mode 100644 src/gallium/winsys/drm/nouveau/egl_g3d/Makefile delete mode 100644 src/gallium/winsys/drm/nouveau/egl_g3d/dummy.c create mode 100644 src/gallium/winsys/drm/radeon/egl/Makefile create mode 100644 src/gallium/winsys/drm/radeon/egl/dummy.c delete mode 100644 src/gallium/winsys/drm/radeon/egl_g3d/Makefile delete mode 100644 src/gallium/winsys/drm/radeon/egl_g3d/dummy.c create mode 100644 src/gallium/winsys/drm/swrast/egl/Makefile create mode 100644 src/gallium/winsys/drm/swrast/egl/dummy.c delete mode 100644 src/gallium/winsys/drm/swrast/egl_g3d/Makefile delete mode 100644 src/gallium/winsys/drm/swrast/egl_g3d/dummy.c create mode 100644 src/gallium/winsys/drm/vmware/egl/Makefile create mode 100644 src/gallium/winsys/drm/vmware/egl/dummy.c delete mode 100644 src/gallium/winsys/drm/vmware/egl_g3d/Makefile delete mode 100644 src/gallium/winsys/drm/vmware/egl_g3d/dummy.c (limited to 'src/gallium/state_trackers') diff --git a/configs/linux-dri b/configs/linux-dri index feb2bba3a0..95f77ade1d 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -61,7 +61,7 @@ DRIVER_DIRS = dri WINDOW_SYSTEM = dri GALLIUM_WINSYS_DIRS = drm GALLIUM_WINSYS_DRM_DIRS = vmware intel i965 -GALLIUM_STATE_TRACKERS_DIRS = egl_g3d +GALLIUM_STATE_TRACKERS_DIRS = egl DRI_DIRS = i810 i915 i965 mach64 mga r128 r200 r300 radeon \ savage sis tdfx unichrome ffb swrast diff --git a/configs/linux-opengl-es b/configs/linux-opengl-es index af784551a7..259c26a931 100644 --- a/configs/linux-opengl-es +++ b/configs/linux-opengl-es @@ -9,7 +9,7 @@ LIB_DIR = lib SRC_DIRS = egl glsl mesa/es gallium gallium/winsys PROGRAM_DIRS = es1/screen es1/xegl es2/xegl -# egl_g3d needs this +# egl st needs this DEFINES += -DGLX_DIRECT_RENDERING # no mesa or egl drivers @@ -23,6 +23,6 @@ GALLIUM_STATE_TRACKERS_DIRS = es # build egl_x11_{swrast,i915}.so GALLIUM_DRIVERS_DIRS += trace i915 -GALLIUM_STATE_TRACKERS_DIRS += egl_g3d +GALLIUM_STATE_TRACKERS_DIRS += egl GALLIUM_WINSYS_DIRS += drm GALLIUM_WINSYS_DRM_DIRS += intel swrast diff --git a/configure.ac b/configure.ac index d6e32f590a..370bd1b9b7 100644 --- a/configure.ac +++ b/configure.ac @@ -1165,7 +1165,7 @@ yes) dri) GALLIUM_STATE_TRACKERS_DIRS="dri" if test "x$enable_egl" = xyes; then - GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl_g3d" + GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl" fi # Have only tested st/xorg on 1.6.0 servers PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0], @@ -1182,9 +1182,9 @@ yes) AC_MSG_ERROR([state tracker '$tracker' doesn't exist]) case "$tracker" in - egl_g3d) + egl) if test "x$enable_egl" != xyes; then - AC_MSG_ERROR([cannot build egl_g3d state tracker without EGL library]) + AC_MSG_ERROR([cannot build egl state tracker without EGL library]) fi ;; xorg) @@ -1223,7 +1223,7 @@ yes) # verify the requested driver directories exist egl_displays=`IFS=', '; echo $with_egl_displays` for dpy in $egl_displays; do - test -d "$srcdir/src/gallium/state_trackers/egl_g3d/$dpy" || \ + test -d "$srcdir/src/gallium/state_trackers/egl/$dpy" || \ AC_MSG_ERROR([EGL display '$dpy' does't exist]) done EGL_DISPLAYS="$egl_displays" diff --git a/docs/egl.html b/docs/egl.html index efc7b1ed3a..0882598966 100644 --- a/docs/egl.html +++ b/docs/egl.html @@ -32,10 +32,10 @@ cards.

the Gallium driver for your hardware. For example

-  $ ./configure --with-state-trackers=egl_g3d,es,vega --enable-gallium-intel
+  $ ./configure --with-state-trackers=egl,es,vega --enable-gallium-intel
 
-

The main library will be enabled by default. The egl_g3d state +

The main library will be enabled by default. The egl state tracker is needed by a number of EGL drivers. EGL drivers will be covered later. The es state tracker provides OpenGL ES 1.x and 2.x and the vega state tracker provides OpenVG @@ -77,9 +77,8 @@ bare KMS (kernel modesetting).

The argument is a comma separated string. It is usually used to specify the rendering APIs, like OpenGL ES or OpenVG, to build. But it should be noted -that a number of EGL drivers depend on the egl_g3d state tracker. -They will not be built without the egl_g3d state -tracker.

+that a number of EGL drivers depend on the egl state tracker. +They will not be built without the egl state tracker.

@@ -160,7 +159,7 @@ variable to true forces the use of software rendering.

Gallium EGL drivers supports all rendering APIs specified in EGL 1.4. The support for optional EGL functions and EGL extensions is usually more complete -than the classic ones. These drivers depend on the egl_g3d state +than the classic ones. These drivers depend on the egl state tracker to build. The available drivers are

    @@ -218,8 +217,8 @@ runtime.

    Developers

    The sources of the main library and the classic drivers can be found at -src/egl/. The sources of the egl_g3d state tracker -can be found at src/gallium/state_trackers/egl_g3d/. +src/egl/. The sources of the egl state tracker can +be found at src/gallium/state_trackers/egl/.

    TODOs

    diff --git a/docs/opengles.html b/docs/opengles.html index a871e85d0b..fc41e6771c 100644 --- a/docs/opengles.html +++ b/docs/opengles.html @@ -20,7 +20,7 @@ for more information about EGL.

    Build the Libraries

      -
    1. Run configure with --with-state-trackers=egl_g3d,es and enable the Gallium driver for your hardware.
    2. +
    3. Run configure with --with-state-trackers=egl,es and enable the Gallium driver for your hardware.
    4. Build and install Mesa as usual.
    diff --git a/docs/openvg.html b/docs/openvg.html index cd39b133c4..cdf6b57e0f 100644 --- a/docs/openvg.html +++ b/docs/openvg.html @@ -34,7 +34,7 @@ Please refer to Mesa EGL for more information about EGL.

    Sample build

    A sample build looks as follows:
    -  $ ./configure --with-state-trackers=egl_g3d,vega --enable-gallium-intel
    +  $ ./configure --with-state-trackers=egl,vega --enable-gallium-intel
       $ make
       $ make install
     
    diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile new file mode 100644 index 0000000000..b696f2fae9 --- /dev/null +++ b/src/gallium/state_trackers/egl/Makefile @@ -0,0 +1,75 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +common_INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/egl/main \ + -I$(TOP)/include + +common_SOURCES = $(wildcard common/*.c) +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 +x11_OBJECTS = $(x11_SOURCES:.c=.o) + + +kms_INCLUDES = $(shell pkg-config --cflags-only-I libdrm) +kms_SOURCES = $(wildcard kms/*.c) +kms_OBJECTS = $(kms_SOURCES:.c=.o) + + +ALL_INCLUDES = $(common_INCLUDES) $(x11_INCLUDES) $(kms_INCLUDES) +ALL_SOURCES = $(common_SOURCES) $(x11_SOURCES) $(kms_SOURCES) +ALL_OBJECTS = $(common_OBJECTS) $(x11_OBJECTS) $(kms_OBJECTS) + +##### TARGETS ##### + +EGL_DISPLAYS_MODS = $(foreach dpy, $(EGL_DISPLAYS), libegl$(dpy).a) + +default: depend $(EGL_DISPLAYS_MODS) + + +libeglx11.a: $(x11_OBJECTS) $(common_OBJECTS) Makefile + $(MKLIB) -o eglx11 -static $(x11_OBJECTS) $(common_OBJECTS) + +libeglkms.a: $(kms_OBJECTS) $(common_OBJECTS) Makefile + $(MKLIB) -o eglkms -static $(kms_OBJECTS) $(common_OBJECTS) + +depend: + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(ALL_INCLUDES) $(ALL_SOURCES) 2> /dev/null + +clean: + rm -f $(ALL_OBJECTS) + rm -f $(EGL_DISPLAYS_MODS) + rm -f depend depend.bak + +# Dummy target +install: + @echo -n "" + +##### RULES ##### + +$(common_OBJECTS): %.o: %.c + $(CC) -c $(common_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@ + +$(x11_OBJECTS): %.o: %.c + $(CC) -c $(common_INCLUDES) $(x11_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@ + +$(kms_OBJECTS): %.o: %.c + $(CC) -c $(common_INCLUDES) $(kms_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@ + +sinclude depend diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c new file mode 100644 index 0000000000..2ac6215646 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -0,0 +1,1336 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu + * + * 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. + */ + +#include +#include +#include "pipe/p_screen.h" +#include "util/u_memory.h" +#include "util/u_rect.h" +#include "egldriver.h" +#include "eglcurrent.h" +#include "eglconfigutil.h" +#include "egllog.h" + +#include "native.h" +#include "egl_g3d.h" +#include "egl_st.h" + +/** + * Validate the draw/read surfaces of the context. + */ +static void +egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct pipe_screen *screen = gdpy->native->screen; + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + const uint st_att_map[NUM_NATIVE_ATTACHMENTS] = { + ST_SURFACE_FRONT_LEFT, + ST_SURFACE_BACK_LEFT, + ST_SURFACE_FRONT_RIGHT, + ST_SURFACE_BACK_RIGHT, + }; + EGLint num_surfaces, s; + + /* validate draw and/or read buffers */ + num_surfaces = (gctx->base.ReadSurface == gctx->base.DrawSurface) ? 1 : 2; + for (s = 0; s < num_surfaces; s++) { + struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; + struct egl_g3d_surface *gsurf; + struct egl_g3d_buffer *gbuf; + EGLint att; + + if (s == 0) { + gsurf = egl_g3d_surface(gctx->base.DrawSurface); + gbuf = &gctx->draw; + } + else { + gsurf = egl_g3d_surface(gctx->base.ReadSurface); + gbuf = &gctx->read; + } + + if (!gctx->force_validate) { + unsigned int seq_num; + + gsurf->native->validate(gsurf->native, gbuf->attachment_mask, + &seq_num, NULL, NULL, NULL); + /* skip validation */ + if (gsurf->sequence_number == seq_num) + continue; + } + + pipe_surface_reference(&gsurf->render_surface, NULL); + memset(textures, 0, sizeof(textures)); + + gsurf->native->validate(gsurf->native, gbuf->attachment_mask, + &gsurf->sequence_number, textures, + &gsurf->base.Width, &gsurf->base.Height); + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + struct pipe_texture *pt = textures[att]; + struct pipe_surface *ps; + + if (native_attachment_mask_test(gbuf->attachment_mask, att) && pt) { + ps = screen->get_tex_surface(screen, pt, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + gctx->stapi->st_set_framebuffer_surface(gbuf->st_fb, + st_att_map[att], ps); + + if (gsurf->render_att == att) + pipe_surface_reference(&gsurf->render_surface, ps); + + pipe_surface_reference(&ps, NULL); + pipe_texture_reference(&pt, NULL); + } + } + + gctx->stapi->st_resize_framebuffer(gbuf->st_fb, + gsurf->base.Width, gsurf->base.Height); + } + + gctx->force_validate = EGL_FALSE; + +} + +/** + * Create a st_framebuffer. + */ +static struct st_framebuffer * +create_framebuffer(_EGLContext *ctx, _EGLSurface *surf) +{ + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config); + + return gctx->stapi->st_create_framebuffer(&gconf->native->mode, + gconf->native->color_format, gconf->native->depth_format, + gconf->native->stencil_format, + gsurf->base.Width, gsurf->base.Height, &gsurf->base); +} + +/** + * Update the attachments of draw/read surfaces. + */ +static void +egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx) +{ + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + EGLint s; + + /* route draw and read buffers' attachments */ + for (s = 0; s < 2; s++) { + struct egl_g3d_surface *gsurf; + struct egl_g3d_buffer *gbuf; + + if (s == 0) { + gsurf = egl_g3d_surface(gctx->base.DrawSurface); + gbuf = &gctx->draw; + } + else { + gsurf = egl_g3d_surface(gctx->base.ReadSurface); + gbuf = &gctx->read; + } + + gbuf->attachment_mask = (1 << gsurf->render_att); + + /* FIXME OpenGL defaults to draw the front or back buffer when the + * context is single-buffered or double-buffered respectively. In EGL, + * however, the buffer to be drawn is determined by the surface, instead + * of the context. As a result, rendering to a pixmap surface with a + * double-buffered context does not work as expected. + * + * gctx->stapi->st_draw_front_buffer(gctx->st_ctx, natt == + * NATIVE_ATTACHMENT_FRONT_LEFT); + */ + + /* + * FIXME If the back buffer is asked for here, and the front buffer is + * later needed by the client API (e.g. glDrawBuffer is called to draw + * the front buffer), it will create a new pipe texture and draw there. + * One fix is to ask for both buffers here, but it would be a waste if + * the front buffer is never used. A better fix is to add a callback to + * the pipe screen with context private (just like flush_frontbuffer). + */ + } +} + +/** + * Reallocate the context's framebuffers after draw/read surfaces change. + */ +static EGLBoolean +egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx) +{ + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + struct egl_g3d_surface *gdraw = egl_g3d_surface(gctx->base.DrawSurface); + struct egl_g3d_surface *gread = egl_g3d_surface(gctx->base.ReadSurface); + + /* unreference the old framebuffers */ + if (gctx->draw.st_fb) { + EGLBoolean is_equal = (gctx->draw.st_fb == gctx->read.st_fb); + void *priv; + + priv = gctx->stapi->st_framebuffer_private(gctx->draw.st_fb); + if (!gdraw || priv != (void *) &gdraw->base) { + gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb); + gctx->draw.st_fb = NULL; + gctx->draw.attachment_mask = 0x0; + } + + if (is_equal) { + gctx->read.st_fb = NULL; + gctx->draw.attachment_mask = 0x0; + } + else { + priv = gctx->stapi->st_framebuffer_private(gctx->read.st_fb); + if (!gread || priv != (void *) &gread->base) { + gctx->stapi->st_unreference_framebuffer(gctx->read.st_fb); + gctx->read.st_fb = NULL; + gctx->draw.attachment_mask = 0x0; + } + } + } + + if (!gdraw) + return EGL_TRUE; + + /* create the draw fb */ + if (!gctx->draw.st_fb) { + gctx->draw.st_fb = create_framebuffer(&gctx->base, &gdraw->base); + if (!gctx->draw.st_fb) + return EGL_FALSE; + } + + /* create the read fb */ + if (!gctx->read.st_fb) { + if (gread != gdraw) { + gctx->read.st_fb = create_framebuffer(&gctx->base, &gread->base); + if (!gctx->read.st_fb) { + gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb); + gctx->draw.st_fb = NULL; + return EGL_FALSE; + } + } + else { + /* there is no st_reference_framebuffer... */ + gctx->read.st_fb = gctx->draw.st_fb; + } + } + + egl_g3d_route_context(dpy, &gctx->base); + gctx->force_validate = EGL_TRUE; + + return EGL_TRUE; +} + +/** + * Return the current context of the given API. + */ +static struct egl_g3d_context * +egl_g3d_get_current_context(EGLint api) +{ + _EGLThreadInfo *t = _eglGetCurrentThread(); + EGLint api_index = _eglConvertApiToIndex(api); + return egl_g3d_context(t->CurrentContexts[api_index]); +} + +/** + * Return the state tracker for the given context. + */ +static const struct egl_g3d_st * +egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + const struct egl_g3d_st *stapi; + EGLint idx = -1; + + switch (ctx->ClientAPI) { + case EGL_OPENGL_ES_API: + switch (ctx->ClientVersion) { + case 1: + idx = EGL_G3D_ST_OPENGL_ES; + break; + case 2: + idx = EGL_G3D_ST_OPENGL_ES2; + break; + default: + _eglLog(_EGL_WARNING, "unknown client version %d", + ctx->ClientVersion); + break; + } + break; + case EGL_OPENVG_API: + idx = EGL_G3D_ST_OPENVG; + break; + case EGL_OPENGL_API: + idx = EGL_G3D_ST_OPENGL; + break; + default: + _eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI); + break; + } + + stapi = (idx >= 0) ? gdrv->stapis[idx] : NULL; + return stapi; +} + +/** + * Initialize the state trackers. + */ +static void +egl_g3d_init_st(_EGLDriver *drv) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + EGLint i; + + /* already initialized */ + if (gdrv->api_mask) + return; + + for (i = 0; i < NUM_EGL_G3D_STS; i++) { + gdrv->stapis[i] = egl_g3d_get_st(i); + if (gdrv->stapis[i]) + gdrv->api_mask |= gdrv->stapis[i]->api_bit; + } + + if (gdrv->api_mask) + _eglLog(_EGL_DEBUG, "Driver API mask: 0x%x", gdrv->api_mask); + else + _eglLog(_EGL_WARNING, "No supported client API"); +} + +/** + * Get the probe object of the display. + * + * Note that this function may be called before the display is initialized. + */ +static struct native_probe * +egl_g3d_get_probe(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + struct native_probe *nprobe; + + nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key); + if (!nprobe || nprobe->display != dpy->NativeDisplay) { + if (nprobe) + nprobe->destroy(nprobe); + nprobe = native_create_probe(dpy->NativeDisplay); + _eglSetProbeCache(gdrv->probe_key, (void *) nprobe); + } + + return nprobe; +} + +/** + * Destroy the probe object of the display. The display may be NULL. + * + * Note that this function may be called before the display is initialized. + */ +static void +egl_g3d_destroy_probe(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + struct native_probe *nprobe; + + nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key); + if (nprobe && (!dpy || nprobe->display == dpy->NativeDisplay)) { + nprobe->destroy(nprobe); + _eglSetProbeCache(gdrv->probe_key, NULL); + } +} + +/** + * Return an API mask that consists of the state trackers that supports the + * given mode. + * + * FIXME add st_is_mode_supported()? + */ +static EGLint +get_mode_api_mask(const __GLcontextModes *mode, EGLint api_mask) +{ + EGLint check; + + /* OpenGL ES 1.x and 2.x are checked together */ + check = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT; + if (api_mask & check) { + /* this is required by EGL, not by OpenGL ES */ + if (mode->drawableType & GLX_WINDOW_BIT && !mode->doubleBufferMode) + api_mask &= ~check; + } + + check = EGL_OPENVG_BIT; + if (api_mask & check) { + /* vega st needs the depth/stencil rb */ + if (!mode->depthBits && !mode->stencilBits) + api_mask &= ~check; + } + + return api_mask; +} + +#ifdef EGL_MESA_screen_surface + +static void +egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + const struct native_connector **native_connectors; + EGLint num_connectors, i; + + native_connectors = + gdpy->native->modeset->get_connectors(gdpy->native, &num_connectors, NULL); + if (!num_connectors) { + if (native_connectors) + free(native_connectors); + return; + } + + for (i = 0; i < num_connectors; i++) { + const struct native_connector *nconn = native_connectors[i]; + struct egl_g3d_screen *gscr; + const struct native_mode **native_modes; + EGLint num_modes, j; + + /* TODO support for hotplug */ + native_modes = + gdpy->native->modeset->get_modes(gdpy->native, nconn, &num_modes); + if (!num_modes) { + if (native_modes) + free(native_modes); + continue; + } + + gscr = CALLOC_STRUCT(egl_g3d_screen); + if (!gscr) { + free(native_modes); + continue; + } + + _eglInitScreen(&gscr->base); + + for (j = 0; j < num_modes; j++) { + const struct native_mode *nmode = native_modes[j]; + _EGLMode *mode; + + mode = _eglAddNewMode(&gscr->base, nmode->width, nmode->height, + nmode->refresh_rate, nmode->desc); + if (!mode) + break; + /* gscr->native_modes and gscr->base.Modes should be consistent */ + assert(mode == &gscr->base.Modes[j]); + } + + gscr->native = nconn; + gscr->native_modes = native_modes; + + _eglAddScreen(dpy, &gscr->base); + } + + free(native_connectors); +} + +#endif /* EGL_MESA_screen_surface */ + +/** + * Add configs to display and return the next config ID. + */ +static EGLint +egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + const struct native_config **native_configs; + int num_configs, i; + + native_configs = gdpy->native->get_configs(gdpy->native, + &num_configs); + if (!num_configs) { + if (native_configs) + free(native_configs); + return id; + } + + for (i = 0; i < num_configs; i++) { + EGLint api_mask; + struct egl_g3d_config *gconf; + EGLBoolean valid; + + api_mask = get_mode_api_mask(&native_configs[i]->mode, gdrv->api_mask); + if (!api_mask) { + _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x", + native_configs[i]->mode.visualID); + continue; + } + + gconf = CALLOC_STRUCT(egl_g3d_config); + if (!gconf) + continue; + + _eglInitConfig(&gconf->base, id); + valid = _eglConfigFromContextModesRec(&gconf->base, + &native_configs[i]->mode, api_mask, api_mask); + if (valid) { +#ifdef EGL_MESA_screen_surface + /* check if scanout surface bit is set */ + if (native_configs[i]->scanout_bit) { + EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE); + val |= EGL_SCREEN_BIT_MESA; + SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val); + } +#endif + valid = _eglValidateConfig(&gconf->base, EGL_FALSE); + } + if (!valid) { + _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", + native_configs[i]->mode.visualID); + free(gconf); + continue; + } + + gconf->native = native_configs[i]; + _eglAddConfig(dpy, &gconf->base); + id++; + } + + free(native_configs); + return id; +} + +/** + * Flush the front buffer of the context's draw surface. + */ +static void +egl_g3d_flush_frontbuffer(struct pipe_screen *screen, + struct pipe_surface *surf, 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); +} + +/** + * Re-validate the context. + */ +static void +egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private) +{ + struct egl_g3d_context *gctx = egl_g3d_context(context_private); + + /** + * 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.Display, &gctx->base); +} + +static EGLBoolean +egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + EGLint i; + + _eglReleaseDisplayResources(drv, dpy); + _eglCleanupDisplay(dpy); + + if (dpy->Screens) { + for (i = 0; i < dpy->NumScreens; i++) { + struct egl_g3d_screen *gscr = egl_g3d_screen(dpy->Screens[i]); + free(gscr->native_modes); + free(gscr); + } + free(dpy->Screens); + } + + if (gdpy->native) + gdpy->native->destroy(gdpy->native); + + free(gdpy); + dpy->DriverData = NULL; + + return EGL_TRUE; +} + +static EGLBoolean +egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, + EGLint *major, EGLint *minor) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + struct egl_g3d_display *gdpy; + + /* the probe object is unlikely to be needed again */ + egl_g3d_destroy_probe(drv, dpy); + + gdpy = CALLOC_STRUCT(egl_g3d_display); + if (!gdpy) { + _eglError(EGL_BAD_ALLOC, "eglInitialize"); + goto fail; + } + dpy->DriverData = gdpy; + + gdpy->native = native_create_display(dpy->NativeDisplay); + if (!gdpy->native) { + _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)"); + goto fail; + } + + gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer; + 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 */ + if (gdpy->native->modeset) { + dpy->Extensions.MESA_screen_surface = EGL_TRUE; + egl_g3d_add_screens(drv, dpy); + } +#endif + + *major = 1; + *minor = 4; + + return EGL_TRUE; + +fail: + if (gdpy) + egl_g3d_terminate(drv, dpy); + return EGL_FALSE; +} + +static _EGLContext * +egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, + _EGLContext *share, const EGLint *attribs) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_context *gshare = egl_g3d_context(share); + struct egl_g3d_config *gconf = egl_g3d_config(conf); + struct egl_g3d_context *gctx; + const __GLcontextModes *mode; + + gctx = CALLOC_STRUCT(egl_g3d_context); + if (!gctx) { + _eglError(EGL_BAD_ALLOC, "eglCreateContext"); + return NULL; + } + + if (!_eglInitContext(drv, &gctx->base, conf, attribs)) { + free(gctx); + return NULL; + } + + gctx->stapi = egl_g3d_choose_st(drv, &gctx->base); + if (!gctx->stapi) { + free(gctx); + return NULL; + } + + mode = &gconf->native->mode; + gctx->pipe = + gdpy->native->create_context(gdpy->native, (void *) &gctx->base); + if (!gctx->pipe) { + free(gctx); + return NULL; + } + + gctx->st_ctx = gctx->stapi->st_create_context(gctx->pipe, mode, + (gshare) ? gshare->st_ctx : NULL); + if (!gctx->st_ctx) { + gctx->pipe->destroy(gctx->pipe); + free(gctx); + return NULL; + } + + return &gctx->base; +} + +static EGLBoolean +egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) +{ + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + + if (_eglIsContextBound(&gctx->base)) + return EGL_TRUE; + + egl_g3d_realloc_context(dpy, &gctx->base); + + /* it will destroy pipe context */ + gctx->stapi->st_destroy_context(gctx->st_ctx); + + free(gctx); + + 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); +} + +static _EGLSurface * +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; + + gsurf = CALLOC_STRUCT(egl_g3d_surface); + if (!gsurf) { + _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface"); + return NULL; + } + + if (!_eglInitSurface(drv, &gsurf->base, EGL_WINDOW_BIT, conf, attribs)) { + free(gsurf); + return NULL; + } + + gsurf->native = + gdpy->native->create_window_surface(gdpy->native, win, gconf->native); + if (!gsurf->native) { + free(gsurf); + return NULL; + } + + if (!init_surface_geometry(&gsurf->base)) { + gsurf->native->destroy(gsurf->native); + free(gsurf); + return NULL; + } + + gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER || + !gconf->native->mode.doubleBufferMode) ? + NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT; + + return &gsurf->base; +} + +static _EGLSurface * +egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLConfig *conf, EGLNativePixmapType pix, + 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, "eglCreatePixmapSurface"); + return NULL; + } + + if (!_eglInitSurface(drv, &gsurf->base, 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; + } + + if (!init_surface_geometry(&gsurf->base)) { + gsurf->native->destroy(gsurf->native); + free(gsurf); + return NULL; + } + + gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT; + + return &gsurf->base; +} + +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(drv, &gsurf->base, 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; + } + + 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; + + return &gsurf->base; +} + +static EGLBoolean +egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) +{ + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + + if (_eglIsSurfaceBound(&gsurf->base)) + return EGL_TRUE; + + pipe_surface_reference(&gsurf->render_surface, NULL); + gsurf->native->destroy(gsurf->native); + free(gsurf); + return EGL_TRUE; +} + +static EGLBoolean +egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx) +{ + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + struct egl_g3d_context *old_gctx; + EGLint api; + EGLBoolean ok = EGL_TRUE; + + /* find the old context */ + api = (gctx) ? gctx->base.ClientAPI : eglQueryAPI(); + old_gctx = egl_g3d_get_current_context(api); + if (old_gctx && !_eglIsContextLinked(&old_gctx->base)) + old_gctx = NULL; + + if (!_eglMakeCurrent(drv, dpy, draw, read, ctx)) + return EGL_FALSE; + + if (old_gctx) { + /* flush old context */ + old_gctx->stapi->st_flush(old_gctx->st_ctx, + PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + + /* + * The old context is no longer current, and egl_g3d_realloc_context() + * should be called to destroy the framebuffers. However, it is possible + * that it will be made current again with the same draw/read surfaces. + * It might be better to keep it around. + */ + } + + if (gctx) { + struct egl_g3d_surface *gdraw = egl_g3d_surface(draw); + + ok = egl_g3d_realloc_context(dpy, &gctx->base); + if (ok) { + ok = gctx->stapi->st_make_current(gctx->st_ctx, + gctx->draw.st_fb, gctx->read.st_fb); + if (ok) { + egl_g3d_validate_context(dpy, &gctx->base); + if (gdraw->base.Type == EGL_WINDOW_BIT) { + gctx->base.WindowRenderBuffer = + (gdraw->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) ? + EGL_SINGLE_BUFFER : EGL_BACK_BUFFER; + } + } + } + } + else if (old_gctx) { + ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL); + old_gctx->base.WindowRenderBuffer = EGL_NONE; + } + + return ok; +} + +static EGLBoolean +egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) +{ + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + _EGLContext *ctx = _eglGetCurrentContext(); + struct egl_g3d_context *gctx = NULL; + + /* no-op for pixmap or pbuffer surface */ + if (gsurf->base.Type == EGL_PIXMAP_BIT || + gsurf->base.Type == EGL_PBUFFER_BIT) + return EGL_TRUE; + + /* or when the surface is single-buffered */ + if (gsurf->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) + return EGL_TRUE; + + if (ctx && ctx->DrawSurface == surf) + gctx = egl_g3d_context(ctx); + + /* flush if the surface is current */ + 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; +} + +/** + * Find a config that supports the pixmap. + */ +static _EGLConfig * +find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_config *gconf; + EGLint i; + + for (i = 0; i < dpy->NumConfigs; i++) { + gconf = egl_g3d_config(dpy->Configs[i]); + if (gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native)) + break; + } + + return (i < dpy->NumConfigs) ? &gconf->base : NULL; +} + +/** + * Get the pipe surface of the given attachment of the native surface. + */ +static struct pipe_surface * +get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf, + enum native_attachment natt) +{ + struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; + struct pipe_surface *psurf; + + textures[natt] = NULL; + nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL); + if (!textures[natt]) + return NULL; + + psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt], + 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE); + pipe_texture_reference(&textures[natt], NULL); + + return psurf; +} + +static EGLBoolean +egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, + NativePixmapType target) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + _EGLContext *ctx = _eglGetCurrentContext(); + struct egl_g3d_config *gconf; + struct native_surface *nsurf; + struct pipe_screen *screen = gdpy->native->screen; + struct pipe_surface *psurf; + + if (!gsurf->render_surface) + return EGL_TRUE; + + gconf = egl_g3d_config(find_pixmap_config(dpy, target)); + if (!gconf) + return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers"); + + nsurf = gdpy->native->create_pixmap_surface(gdpy->native, + target, gconf->native); + if (!nsurf) + return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers"); + + /* flush if the surface is current */ + if (ctx && ctx->DrawSurface == &gsurf->base) { + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + gctx->stapi->st_flush(gctx->st_ctx, + PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + } + + psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); + if (psurf) { + struct pipe_context pipe; + + /** + * XXX This is hacky. If we might allow the EGLDisplay to create a pipe + * context of its own and use the blitter context for this. + */ + memset(&pipe, 0, sizeof(pipe)); + pipe.screen = screen; + + util_surface_copy(&pipe, FALSE, psurf, 0, 0, + gsurf->render_surface, 0, 0, psurf->width, psurf->height); + + pipe_surface_reference(&psurf, NULL); + nsurf->flush_frontbuffer(nsurf); + } + + nsurf->destroy(nsurf); + + return EGL_TRUE; +} + +static EGLBoolean +egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) +{ + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + gctx->stapi->st_finish(gctx->st_ctx); + return EGL_TRUE; +} + +static EGLBoolean +egl_g3d_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine) +{ + _EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW); + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + + if (engine != EGL_CORE_NATIVE_ENGINE) + return _eglError(EGL_BAD_PARAMETER, "eglWaitNative"); + + if (gsurf) + gsurf->native->wait(gsurf->native); + + return EGL_TRUE; +} + +static _EGLProc +egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + _EGLProc proc; + EGLint i; + + /* in case this is called before a display is initialized */ + egl_g3d_init_st(&gdrv->base); + + for (i = 0; i < NUM_EGL_G3D_STS; i++) { + const struct egl_g3d_st *stapi = gdrv->stapis[i]; + if (stapi) { + proc = (_EGLProc) stapi->st_get_proc_address(procname); + if (proc) + return proc; + } + } + + return (_EGLProc) NULL; +} + +static EGLBoolean +egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLSurface *surf, EGLint buffer) +{ + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + struct egl_g3d_context *gctx; + enum pipe_format target_format; + int target; + + if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT) + return _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); + if (buffer != EGL_BACK_BUFFER) + return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage"); + if (gsurf->base.BoundToTexture) + return _eglError(EGL_BAD_ACCESS, "eglBindTexImage"); + + switch (gsurf->base.TextureFormat) { + case EGL_TEXTURE_RGB: + target_format = PIPE_FORMAT_R8G8B8_UNORM; + break; + case EGL_TEXTURE_RGBA: + target_format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + default: + return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); + } + + switch (gsurf->base.TextureTarget) { + case EGL_TEXTURE_2D: + target = ST_TEXTURE_2D; + break; + default: + return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); + } + + /* flush properly if the surface is bound */ + if (gsurf->base.Binding) { + gctx = egl_g3d_context(gsurf->base.Binding); + gctx->stapi->st_flush(gctx->st_ctx, + PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + } + + /* XXX change to EGL_OPENGL_ES_API once OpenGL ES is merged */ + gctx = egl_g3d_get_current_context(EGL_OPENGL_API); + if (gctx) { + if (!gsurf->render_surface) + return EGL_FALSE; + + gctx->stapi->st_bind_texture_surface(gsurf->render_surface, + target, gsurf->base.MipmapLevel, target_format); + gsurf->base.BoundToTexture = EGL_TRUE; + } + + return EGL_TRUE; +} + +static EGLBoolean +egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLSurface *surf, EGLint buffer) +{ + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + + if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT || + !gsurf->base.BoundToTexture) + return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage"); + if (buffer != EGL_BACK_BUFFER) + return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage"); + + if (gsurf->render_surface) { + _EGLThreadInfo *t = _eglGetCurrentThread(); + /* XXX change to EGL_OPENGL_ES_API once OpenGL ES is merged */ + struct egl_g3d_context *gctx = egl_g3d_context( + t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_API)]); + + /* what if the context the surface binds to is no longer current? */ + if (gctx) + gctx->stapi->st_unbind_texture_surface(gsurf->render_surface, + ST_TEXTURE_2D, gsurf->base.MipmapLevel); + } + + gsurf->base.BoundToTexture = EGL_FALSE; + + return EGL_TRUE; +} + +#ifdef EGL_MESA_screen_surface + +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; + + gsurf = CALLOC_STRUCT(egl_g3d_surface); + if (!gsurf) { + _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface"); + return NULL; + } + + if (!_eglInitSurface(drv, &gsurf->base, + 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; +} + +static EGLBoolean +egl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLScreen *scr, _EGLSurface *surf, + _EGLMode *mode) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_screen *gscr = egl_g3d_screen(scr); + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + struct native_surface *nsurf; + const struct native_mode *nmode; + EGLBoolean changed; + + if (gsurf) { + EGLint idx; + + if (!mode) + return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA"); + if (gsurf->base.Type != EGL_SCREEN_BIT_MESA) + return _eglError(EGL_BAD_SURFACE, "eglShowScreenSurfaceMESA"); + if (gsurf->base.Width < mode->Width || gsurf->base.Height < mode->Height) + return _eglError(EGL_BAD_MATCH, + "eglShowSurfaceMESA(surface smaller than mode size)"); + + /* find the index of the mode */ + for (idx = 0; idx < gscr->base.NumModes; idx++) + if (mode == &gscr->base.Modes[idx]) + break; + if (idx >= gscr->base.NumModes) { + return _eglError(EGL_BAD_MODE_MESA, + "eglShowSurfaceMESA(unknown mode)"); + } + + nsurf = gsurf->native; + nmode = gscr->native_modes[idx]; + } + else { + if (mode) + return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA"); + + /* disable the screen */ + nsurf = NULL; + nmode = NULL; + } + + /* TODO surface panning by CRTC choosing */ + changed = gdpy->native->modeset->program(gdpy->native, 0, nsurf, + gscr->base.OriginX, gscr->base.OriginY, &gscr->native, 1, nmode); + if (changed) { + gscr->base.CurrentSurface = &gsurf->base; + gscr->base.CurrentMode = mode; + } + + return changed; +} + +#endif /* EGL_MESA_screen_surface */ + +static EGLint +egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct native_probe *nprobe; + enum native_probe_result res; + EGLint score; + + nprobe = egl_g3d_get_probe(drv, dpy); + res = native_get_probe_result(nprobe); + + switch (res) { + case NATIVE_PROBE_UNKNOWN: + default: + score = 0; + break; + case NATIVE_PROBE_FALLBACK: + score = 40; + break; + case NATIVE_PROBE_SUPPORTED: + score = 50; + break; + case NATIVE_PROBE_EXACT: + score = 100; + break; + } + + return score; +} + +static void +egl_g3d_unload(_EGLDriver *drv) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + + egl_g3d_destroy_probe(drv, NULL); + free(gdrv); +} + +_EGLDriver * +_eglMain(const char *args) +{ + static char driver_name[64]; + struct egl_g3d_driver *gdrv; + + snprintf(driver_name, sizeof(driver_name), + "Gallium/%s", native_get_name()); + + gdrv = CALLOC_STRUCT(egl_g3d_driver); + if (!gdrv) + return NULL; + + _eglInitDriverFallbacks(&gdrv->base); + + gdrv->base.API.Initialize = egl_g3d_initialize; + gdrv->base.API.Terminate = egl_g3d_terminate; + gdrv->base.API.CreateContext = egl_g3d_create_context; + gdrv->base.API.DestroyContext = egl_g3d_destroy_context; + gdrv->base.API.CreateWindowSurface = egl_g3d_create_window_surface; + gdrv->base.API.CreatePixmapSurface = egl_g3d_create_pixmap_surface; + gdrv->base.API.CreatePbufferSurface = egl_g3d_create_pbuffer_surface; + gdrv->base.API.DestroySurface = egl_g3d_destroy_surface; + gdrv->base.API.MakeCurrent = egl_g3d_make_current; + gdrv->base.API.SwapBuffers = egl_g3d_swap_buffers; + gdrv->base.API.CopyBuffers = egl_g3d_copy_buffers; + gdrv->base.API.WaitClient = egl_g3d_wait_client; + gdrv->base.API.WaitNative = egl_g3d_wait_native; + gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address; + + gdrv->base.API.BindTexImage = egl_g3d_bind_tex_image; + gdrv->base.API.ReleaseTexImage = egl_g3d_release_tex_image; + +#ifdef EGL_MESA_screen_surface + gdrv->base.API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface; + gdrv->base.API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface; +#endif + + gdrv->base.Name = driver_name; + gdrv->base.Probe = egl_g3d_probe; + gdrv->base.Unload = egl_g3d_unload; + + /* the key is " EGL G3D" */ + gdrv->probe_key = 0x0E61063D; + + return &gdrv->base; +} diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h new file mode 100644 index 0000000000..3dae8c4052 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/egl_g3d.h @@ -0,0 +1,127 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu + * + * 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 _EGL_G3D_H_ +#define _EGL_G3D_H_ + +#include "pipe/p_compiler.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_format.h" +#include "egldriver.h" +#include "egldisplay.h" +#include "eglcontext.h" +#include "eglsurface.h" +#include "eglconfig.h" +#include "eglscreen.h" +#include "eglmode.h" + +#include "native.h" +#include "egl_st.h" + +struct egl_g3d_driver { + _EGLDriver base; + const struct egl_g3d_st *stapis[NUM_EGL_G3D_STS]; + EGLint api_mask; + + EGLint probe_key; +}; + +struct egl_g3d_display { + struct native_display *native; +}; + +struct egl_g3d_buffer { + struct st_framebuffer *st_fb; + uint attachment_mask; +}; + +struct egl_g3d_context { + _EGLContext base; + + const struct egl_g3d_st *stapi; + struct pipe_context *pipe; + + struct st_context *st_ctx; + EGLBoolean force_validate; + struct egl_g3d_buffer draw, read; +}; + +struct egl_g3d_surface { + _EGLSurface base; + struct native_surface *native; + enum native_attachment render_att; + struct pipe_surface *render_surface; + unsigned int sequence_number; +}; + +struct egl_g3d_config { + _EGLConfig base; + const struct native_config *native; +}; + +struct egl_g3d_screen { + _EGLScreen base; + const struct native_connector *native; + const struct native_mode **native_modes; +}; + +static INLINE struct egl_g3d_driver * +egl_g3d_driver(_EGLDriver *drv) +{ + return (struct egl_g3d_driver *) drv; +} + +static INLINE struct egl_g3d_display * +egl_g3d_display(_EGLDisplay *dpy) +{ + /* note that it is not direct casting */ + return (struct egl_g3d_display *) dpy->DriverData; +} + +static INLINE struct egl_g3d_context * +egl_g3d_context(_EGLContext *ctx) +{ + return (struct egl_g3d_context *) ctx; +} + +static INLINE struct egl_g3d_surface * +egl_g3d_surface(_EGLSurface *surf) +{ + return (struct egl_g3d_surface *) surf; +} + +static INLINE struct egl_g3d_config * +egl_g3d_config(_EGLConfig *conf) +{ + return (struct egl_g3d_config *) conf; +} + +static INLINE struct egl_g3d_screen * +egl_g3d_screen(_EGLScreen *scr) +{ + return (struct egl_g3d_screen *) scr; +} + +#endif /* _EGL_G3D_H_ */ diff --git a/src/gallium/state_trackers/egl/common/egl_st.c b/src/gallium/state_trackers/egl/common/egl_st.c new file mode 100644 index 0000000000..a88ff911cd --- /dev/null +++ b/src/gallium/state_trackers/egl/common/egl_st.c @@ -0,0 +1,131 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu + * + * 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. + */ + +#include +#include "pipe/p_compiler.h" +#include "util/u_memory.h" +#include "egllog.h" +#include "EGL/egl.h" /* for EGL_api_BIT */ + +#include "egl_st.h" + +#ifndef HAVE_DLADDR +#define HAVE_DLADDR 1 +#endif + +#if HAVE_DLADDR + +static const char * +egl_g3d_st_names[] = { +#define ST_PUBLIC(name, ...) #name, +#include "st_public_tmp.h" + NULL +}; + +static boolean +egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym) +{ + st_proc *procs = (st_proc *) stapi; + void *handle; + Dl_info info; + const char **name; + + if (!dladdr(sym, &info)) + return FALSE; + handle = dlopen(info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE); + if (!handle) + return FALSE; + + for (name = egl_g3d_st_names; *name; name++) { + st_proc proc = (st_proc) dlsym(handle, *name); + if (!proc) { + _eglLog(_EGL_WARNING, "%s is missing in %s", *name, info.dli_fname); + memset(stapi, 0, sizeof(*stapi)); + dlclose(handle); + return FALSE; + } + *procs++ = proc; + } + + dlclose(handle); + return TRUE; +} + +#else /* HAVE_DLADDR */ + +static boolean +egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym) +{ +#define ST_PUBLIC(name, ...) stapi->name = name; +#include "st_public_tmp.h" + return TRUE; +} + +#endif /* HAVE_DLADDR */ + +static boolean +egl_g3d_init_st(struct egl_g3d_st *stapi, const char *api) +{ + void *handle, *sym; + boolean res = FALSE; + + /* already initialized */ + if (stapi->st_notify_swapbuffers != NULL) + return TRUE; + + handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL); + if (!handle) + return FALSE; + + sym = dlsym(handle, api); + if (sym && egl_g3d_fill_st(stapi, sym)) + res = TRUE; + + dlclose(handle); + return res; +} + +static struct { + const char *symbol; + EGLint api_bit; +} egl_g3d_st_info[NUM_EGL_G3D_STS] = { + { "st_api_OpenGL_ES1", EGL_OPENGL_ES_BIT }, + { "st_api_OpenVG", EGL_OPENVG_BIT }, + { "st_api_OpenGL_ES2", EGL_OPENGL_ES2_BIT }, + { "st_api_OpenGL", EGL_OPENGL_BIT }, +}; + +const struct egl_g3d_st * +egl_g3d_get_st(enum egl_g3d_st_api api) +{ + static struct egl_g3d_st all_trackers[NUM_EGL_G3D_STS]; + + if (egl_g3d_init_st(&all_trackers[api], egl_g3d_st_info[api].symbol)) { + all_trackers[api].api_bit = egl_g3d_st_info[api].api_bit; + return &all_trackers[api]; + } + else { + return NULL; + } +} diff --git a/src/gallium/state_trackers/egl/common/egl_st.h b/src/gallium/state_trackers/egl/common/egl_st.h new file mode 100644 index 0000000000..8fb464bd3d --- /dev/null +++ b/src/gallium/state_trackers/egl/common/egl_st.h @@ -0,0 +1,73 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu + * + * 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 _EGL_ST_H_ +#define _EGL_ST_H_ + +#include "GL/gl.h" /* for GL types */ +#include "GL/internal/glcore.h" /* for __GLcontextModes */ + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" + +/* avoid calling st functions directly */ +#if 1 + +#define ST_SURFACE_FRONT_LEFT 0 +#define ST_SURFACE_BACK_LEFT 1 +#define ST_SURFACE_FRONT_RIGHT 2 +#define ST_SURFACE_BACK_RIGHT 3 + +#define ST_TEXTURE_2D 0x2 + +struct st_context; +struct st_framebuffer; +typedef void (*st_proc)(); + +#else +#include "state_tracker/st_public.h" +#endif + +/* remember to update egl_g3d_get_st() when update the enums */ +enum egl_g3d_st_api { + EGL_G3D_ST_OPENGL_ES = 0, + EGL_G3D_ST_OPENVG, + EGL_G3D_ST_OPENGL_ES2, + EGL_G3D_ST_OPENGL, + + NUM_EGL_G3D_STS +}; + +struct egl_g3d_st { +#define ST_PUBLIC(name, ret, ...) ret (*name)(__VA_ARGS__); +#include "st_public_tmp.h" + /* fields must be added here */ + EGLint api_bit; +}; + +const struct egl_g3d_st * +egl_g3d_get_st(enum egl_g3d_st_api api); + +#endif /* _EGL_ST_H_ */ diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h new file mode 100644 index 0000000000..72a9cec7ef --- /dev/null +++ b/src/gallium/state_trackers/egl/common/native.h @@ -0,0 +1,277 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu + * + * 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_H_ +#define _NATIVE_H_ + +#include "EGL/egl.h" /* for EGL native types */ +#include "GL/gl.h" /* for GL types needed by __GLcontextModes */ +#include "GL/internal/glcore.h" /* for __GLcontextModes */ + +#include "pipe/p_compiler.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" + +/** + * Only color buffers are listed. The others are allocated privately through, + * for example, st_renderbuffer_alloc_storage(). + */ +enum native_attachment { + NATIVE_ATTACHMENT_FRONT_LEFT, + NATIVE_ATTACHMENT_BACK_LEFT, + NATIVE_ATTACHMENT_FRONT_RIGHT, + NATIVE_ATTACHMENT_BACK_RIGHT, + + NUM_NATIVE_ATTACHMENTS +}; + +/** + * Enumerations for probe results. + */ +enum native_probe_result { + NATIVE_PROBE_UNKNOWN, + NATIVE_PROBE_FALLBACK, + NATIVE_PROBE_SUPPORTED, + NATIVE_PROBE_EXACT, +}; + +/** + * A probe object for display probe. + */ +struct native_probe { + int magic; + EGLNativeDisplayType display; + void *data; + + void (*destroy)(struct native_probe *nprobe); +}; + +struct native_surface { + void (*destroy)(struct native_surface *nsurf); + + /** + * Swap the front and back buffers so that the back buffer is visible. It + * is no-op if the surface is single-buffered. The contents of the back + * buffer after swapping may or may not be preserved. + */ + boolean (*swap_buffers)(struct native_surface *nsurf); + + /** + * Make the front buffer visible. In some native displays, changes to the + * front buffer might not be visible immediately and require manual flush. + */ + boolean (*flush_frontbuffer)(struct native_surface *nsurf); + + /** + * Validate the buffers of the surface. textures, if not NULL, points to an + * array of size NUM_NATIVE_ATTACHMENTS and the returned textures are owned + * by the caller. A sequence number is also returned. The caller can use + * it to check if anything has changed since the last call. Any of the + * pointers may be NULL and it indicates the caller has no interest in those + * values. + * + * If this function is called multiple times with different attachment + * masks, those not listed in the latest call might be destroyed. This + * behavior might change in the future. + */ + boolean (*validate)(struct native_surface *nsurf, uint attachment_mask, + unsigned int *seq_num, struct pipe_texture **textures, + int *width, int *height); + + /** + * Wait until all native commands affecting the surface has been executed. + */ + void (*wait)(struct native_surface *nsurf); +}; + +struct native_config { + /* __GLcontextModes should go away some day */ + __GLcontextModes mode; + enum pipe_format color_format; + enum pipe_format depth_format; + enum pipe_format stencil_format; + + /* treat it as an additional flag to mode.drawableType */ + 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 + * the native display server. + */ +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; + + void (*destroy)(struct native_display *ndpy); + + /** + * Get the supported configs. The configs are owned by the display, but + * the returned array should be free()ed. + * + * The configs will be converted to EGL config by + * _eglConfigFromContextModesRec and validated by _eglValidateConfig. + * Those failing to pass the test will be skipped. + */ + const struct native_config **(*get_configs)(struct native_display *ndpy, + int *num_configs); + + /** + * Test if a pixmap is supported by the given config. Required unless no + * config has GLX_PIXMAP_BIT set. + * + * This function is usually called to find a config that supports a given + * pixmap. Thus, it is usually called with the same pixmap in a row. + */ + boolean (*is_pixmap_supported)(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf); + + /** + * Create a pipe context. + */ + struct pipe_context *(*create_context)(struct native_display *ndpy, + void *context_private); + + /** + * Create a window surface. Required unless no config has GLX_WINDOW_BIT + * set. + */ + struct native_surface *(*create_window_surface)(struct native_display *ndpy, + EGLNativeWindowType win, + const struct native_config *nconf); + + /** + * Create a pixmap surface. Required unless no config has GLX_PIXMAP_BIT + * set. + */ + struct native_surface *(*create_pixmap_surface)(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf); + + /** + * Create a pbuffer surface. Required unless no config has GLX_PBUFFER_BIT + * set. + */ + struct native_surface *(*create_pbuffer_surface)(struct native_display *ndpy, + const struct native_config *nconf, + uint width, uint height); + + const struct native_display_modeset *modeset; +}; + +/** + * 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); +}; + +/** + * Test whether an attachment is set in the mask. + */ +static INLINE boolean +native_attachment_mask_test(uint mask, enum native_attachment att) +{ + return !!(mask & (1 << att)); +} + +/** + * Return a probe object for the given display. + * + * Note that the returned object may be cached and used by different native + * display modules. It allows fast probing when multiple modules probe the + * same display. + */ +struct native_probe * +native_create_probe(EGLNativeDisplayType dpy); + +/** + * Probe the probe object. + */ +enum native_probe_result +native_get_probe_result(struct native_probe *nprobe); + +const char * +native_get_name(void); + +struct native_display * +native_create_display(EGLNativeDisplayType dpy); + +#endif /* _NATIVE_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 new file mode 100644 index 0000000000..507a0ec402 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/st_public_tmp.h @@ -0,0 +1,20 @@ +ST_PUBLIC(st_create_context, struct st_context *, struct pipe_context *pipe, const __GLcontextModes *visual, struct st_context *share) +ST_PUBLIC(st_destroy_context, void, struct st_context *st) +ST_PUBLIC(st_copy_context_state, void, struct st_context *dst, struct st_context *src, uint mask) +ST_PUBLIC(st_create_framebuffer, struct st_framebuffer *, const __GLcontextModes *visual, enum pipe_format colorFormat, enum pipe_format depthFormat, enum pipe_format stencilFormat, uint width, uint height, void *privateData) +ST_PUBLIC(st_resize_framebuffer, void, struct st_framebuffer *stfb, uint width, uint height) +ST_PUBLIC(st_set_framebuffer_surface, void, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface *surf) +ST_PUBLIC(st_get_framebuffer_dimensions, void, struct st_framebuffer *stfb, uint *width, uint *height) +ST_PUBLIC(st_get_framebuffer_surface, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface **surface) +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_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) +ST_PUBLIC(st_notify_swapbuffers, void, struct st_framebuffer *stfb) +ST_PUBLIC(st_bind_texture_surface, int, struct pipe_surface *ps, int target, int level, enum pipe_format format) +ST_PUBLIC(st_unbind_texture_surface, int, struct pipe_surface *ps, int target, int level) +ST_PUBLIC(st_get_proc_address, st_proc, const char *procname) +#undef ST_PUBLIC diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c new file mode 100644 index 0000000000..d5baf2c2f0 --- /dev/null +++ b/src/gallium/state_trackers/egl/kms/native_kms.c @@ -0,0 +1,866 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2010 Chia-I Wu + * + * 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. + */ + +#include + +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "util/u_debug.h" +#include "util/u_memory.h" +#include "egllog.h" + +#include "native_kms.h" + +static boolean +kms_surface_validate(struct native_surface *nsurf, uint attachment_mask, + unsigned int *seq_num, struct pipe_texture **textures, + int *width, int *height) +{ + struct kms_surface *ksurf = kms_surface(nsurf); + struct kms_display *kdpy = ksurf->kdpy; + struct pipe_screen *screen = kdpy->base.screen; + struct pipe_texture templ, *ptex; + int att; + + if (attachment_mask) { + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; + templ.width0 = ksurf->width; + templ.height0 = ksurf->height; + templ.depth0 = 1; + 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; + } + + /* create textures */ + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + /* delay the allocation */ + if (!native_attachment_mask_test(attachment_mask, att)) + continue; + + ptex = ksurf->textures[att]; + if (!ptex) { + ptex = screen->texture_create(screen, &templ); + ksurf->textures[att] = ptex; + } + + if (textures) { + textures[att] = NULL; + pipe_texture_reference(&textures[att], ptex); + } + } + + if (seq_num) + *seq_num = ksurf->sequence_number; + if (width) + *width = ksurf->width; + if (height) + *height = ksurf->height; + + return TRUE; +} + +/** + * Add textures as DRM framebuffers. + */ +static boolean +kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back) +{ + struct kms_surface *ksurf = kms_surface(nsurf); + struct kms_display *kdpy = ksurf->kdpy; + int num_framebuffers = (need_back) ? 2 : 1; + int i, err; + + for (i = 0; i < num_framebuffers; i++) { + struct kms_framebuffer *fb; + enum native_attachment natt; + unsigned int handle, stride; + uint block_bits; + + if (i == 0) { + fb = &ksurf->front_fb; + natt = NATIVE_ATTACHMENT_FRONT_LEFT; + } + else { + fb = &ksurf->back_fb; + natt = NATIVE_ATTACHMENT_BACK_LEFT; + } + + if (!fb->texture) { + /* make sure the texture has been allocated */ + kms_surface_validate(&ksurf->base, 1 << natt, NULL, NULL, NULL, NULL); + if (!ksurf->textures[natt]) + return FALSE; + + pipe_texture_reference(&fb->texture, ksurf->textures[natt]); + } + + /* already initialized */ + if (fb->buffer_id) + continue; + + /* 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)) + 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); + if (err) { + fb->buffer_id = 0; + return FALSE; + } + } + + return TRUE; +} + +static boolean +kms_surface_flush_frontbuffer(struct native_surface *nsurf) +{ +#ifdef DRM_MODE_FEATURE_DIRTYFB + struct kms_surface *ksurf = kms_surface(nsurf); + struct kms_display *kdpy = ksurf->kdpy; + + /* pbuffer is private */ + if (ksurf->type == KMS_SURFACE_TYPE_PBUFFER) + return TRUE; + + if (ksurf->front_fb.is_passive) + drmModeDirtyFB(kdpy->fd, ksurf->front_fb.buffer_id, NULL, 0); +#endif + + return TRUE; +} + +static boolean +kms_surface_swap_buffers(struct native_surface *nsurf) +{ + struct kms_surface *ksurf = kms_surface(nsurf); + struct kms_crtc *kcrtc = &ksurf->current_crtc; + struct kms_display *kdpy = ksurf->kdpy; + struct kms_framebuffer tmp_fb; + struct pipe_texture *tmp_texture; + int err; + + /* pbuffer is private */ + if (ksurf->type == KMS_SURFACE_TYPE_PBUFFER) + return TRUE; + + if (!ksurf->back_fb.buffer_id) { + if (!kms_surface_init_framebuffers(&ksurf->base, TRUE)) + return FALSE; + } + + if (ksurf->is_shown && kcrtc->crtc) { + err = drmModeSetCrtc(kdpy->fd, kcrtc->crtc->crtc_id, + ksurf->back_fb.buffer_id, kcrtc->crtc->x, kcrtc->crtc->y, + kcrtc->connectors, kcrtc->num_connectors, &kcrtc->crtc->mode); + if (err) + return FALSE; + } + + /* swap the buffers */ + tmp_fb = ksurf->front_fb; + ksurf->front_fb = ksurf->back_fb; + ksurf->back_fb = tmp_fb; + + tmp_texture = ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT]; + ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT] = + ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT]; + ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT] = tmp_texture; + + /* the front/back textures are swapped */ + ksurf->sequence_number++; + + return TRUE; +} + +static void +kms_surface_wait(struct native_surface *nsurf) +{ + /* no-op */ +} + +static void +kms_surface_destroy(struct native_surface *nsurf) +{ + struct kms_surface *ksurf = kms_surface(nsurf); + int i; + + if (ksurf->current_crtc.crtc) + drmModeFreeCrtc(ksurf->current_crtc.crtc); + + if (ksurf->front_fb.buffer_id) + drmModeRmFB(ksurf->kdpy->fd, ksurf->front_fb.buffer_id); + pipe_texture_reference(&ksurf->front_fb.texture, NULL); + + if (ksurf->back_fb.buffer_id) + drmModeRmFB(ksurf->kdpy->fd, ksurf->back_fb.buffer_id); + pipe_texture_reference(&ksurf->back_fb.texture, NULL); + + for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { + struct pipe_texture *ptex = ksurf->textures[i]; + pipe_texture_reference(&ptex, NULL); + } + + free(ksurf); +} + +static struct kms_surface * +kms_display_create_surface(struct native_display *ndpy, + enum kms_surface_type type, + const struct native_config *nconf, + uint width, uint height) +{ + struct kms_display *kdpy = kms_display(ndpy); + struct kms_config *kconf = kms_config(nconf); + struct kms_surface *ksurf; + + ksurf = CALLOC_STRUCT(kms_surface); + if (!ksurf) + return NULL; + + ksurf->kdpy = kdpy; + ksurf->type = type; + ksurf->color_format = kconf->base.color_format; + ksurf->width = width; + ksurf->height = height; + + ksurf->base.destroy = kms_surface_destroy; + ksurf->base.swap_buffers = kms_surface_swap_buffers; + ksurf->base.flush_frontbuffer = kms_surface_flush_frontbuffer; + ksurf->base.validate = kms_surface_validate; + ksurf->base.wait = kms_surface_wait; + + return ksurf; +} + +/** + * Choose a CRTC that supports all given connectors. + */ +static uint32_t +kms_display_choose_crtc(struct native_display *ndpy, + uint32_t *connectors, int num_connectors) +{ + struct kms_display *kdpy = kms_display(ndpy); + int idx; + + for (idx = 0; idx < kdpy->resources->count_crtcs; idx++) { + boolean found_crtc = TRUE; + int i, j; + + for (i = 0; i < num_connectors; i++) { + drmModeConnectorPtr connector; + int encoder_idx = -1; + + connector = drmModeGetConnector(kdpy->fd, connectors[i]); + if (!connector) { + found_crtc = FALSE; + break; + } + + /* find an encoder the CRTC supports */ + for (j = 0; j < connector->count_encoders; j++) { + drmModeEncoderPtr encoder = + drmModeGetEncoder(kdpy->fd, connector->encoders[j]); + if (encoder->possible_crtcs & (1 << idx)) { + encoder_idx = j; + break; + } + drmModeFreeEncoder(encoder); + } + + drmModeFreeConnector(connector); + if (encoder_idx < 0) { + found_crtc = FALSE; + break; + } + } + + if (found_crtc) + break; + } + + if (idx >= kdpy->resources->count_crtcs) { + _eglLog(_EGL_WARNING, + "failed to find a CRTC that supports the given %d connectors", + num_connectors); + return 0; + } + + return kdpy->resources->crtcs[idx]; +} + +/** + * Remember the original CRTC status and set the CRTC + */ +static boolean +kms_display_set_crtc(struct native_display *ndpy, int crtc_idx, + uint32_t buffer_id, uint32_t x, uint32_t y, + uint32_t *connectors, int num_connectors, + drmModeModeInfoPtr mode) +{ + struct kms_display *kdpy = kms_display(ndpy); + struct kms_crtc *kcrtc = &kdpy->saved_crtcs[crtc_idx]; + uint32_t crtc_id; + int err; + + if (kcrtc->crtc) { + crtc_id = kcrtc->crtc->crtc_id; + } + else { + int count = 0, i; + + /* + * Choose the CRTC once. It could be more dynamic, but let's keep it + * simple for now. + */ + crtc_id = kms_display_choose_crtc(&kdpy->base, + connectors, num_connectors); + + /* save the original CRTC status */ + kcrtc->crtc = drmModeGetCrtc(kdpy->fd, crtc_id); + if (!kcrtc->crtc) + return FALSE; + + for (i = 0; i < kdpy->num_connectors; i++) { + struct kms_connector *kconn = &kdpy->connectors[i]; + drmModeConnectorPtr connector = kconn->connector; + drmModeEncoderPtr encoder; + + encoder = drmModeGetEncoder(kdpy->fd, connector->encoder_id); + if (encoder) { + if (encoder->crtc_id == crtc_id) { + kcrtc->connectors[count++] = connector->connector_id; + if (count >= Elements(kcrtc->connectors)) + break; + } + drmModeFreeEncoder(encoder); + } + } + + kcrtc->num_connectors = count; + } + + err = drmModeSetCrtc(kdpy->fd, crtc_id, buffer_id, x, y, + connectors, num_connectors, mode); + if (err) { + drmModeFreeCrtc(kcrtc->crtc); + kcrtc->crtc = NULL; + kcrtc->num_connectors = 0; + + return FALSE; + } + + return TRUE; +} + +static boolean +kms_display_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) +{ + struct kms_display *kdpy = kms_display(ndpy); + struct kms_surface *ksurf = kms_surface(nsurf); + const struct kms_mode *kmode = kms_mode(nmode); + uint32_t connector_ids[32]; + uint32_t buffer_id; + drmModeModeInfo mode_tmp, *mode; + int i; + + if (num_nconns > Elements(connector_ids)) { + _eglLog(_EGL_WARNING, "too many connectors (%d)", num_nconns); + num_nconns = Elements(connector_ids); + } + + if (ksurf) { + if (!kms_surface_init_framebuffers(&ksurf->base, FALSE)) + return FALSE; + + buffer_id = ksurf->front_fb.buffer_id; + /* the mode argument of drmModeSetCrtc is not constified */ + mode_tmp = kmode->mode; + mode = &mode_tmp; + } + else { + /* disable the CRTC */ + buffer_id = 0; + mode = NULL; + num_nconns = 0; + } + + for (i = 0; i < num_nconns; i++) { + struct kms_connector *kconn = kms_connector(nconns[i]); + connector_ids[i] = kconn->connector->connector_id; + } + + if (!kms_display_set_crtc(&kdpy->base, crtc_idx, buffer_id, x, y, + connector_ids, num_nconns, mode)) { + _eglLog(_EGL_WARNING, "failed to set CRTC %d", crtc_idx); + + return FALSE; + } + + if (kdpy->shown_surfaces[crtc_idx]) + kdpy->shown_surfaces[crtc_idx]->is_shown = FALSE; + kdpy->shown_surfaces[crtc_idx] = ksurf; + + /* remember the settings for buffer swapping */ + if (ksurf) { + uint32_t crtc_id = kdpy->saved_crtcs[crtc_idx].crtc->crtc_id; + struct kms_crtc *kcrtc = &ksurf->current_crtc; + + if (kcrtc->crtc) + drmModeFreeCrtc(kcrtc->crtc); + kcrtc->crtc = drmModeGetCrtc(kdpy->fd, crtc_id); + + assert(num_nconns < Elements(kcrtc->connectors)); + memcpy(kcrtc->connectors, connector_ids, + sizeof(*connector_ids) * num_nconns); + kcrtc->num_connectors = num_nconns; + + ksurf->is_shown = TRUE; + } + + return TRUE; +} + +static const struct native_mode ** +kms_display_get_modes(struct native_display *ndpy, + const struct native_connector *nconn, + int *num_modes) +{ + struct kms_display *kdpy = kms_display(ndpy); + struct kms_connector *kconn = kms_connector(nconn); + const struct native_mode **nmodes_return; + int count, i; + + /* delete old data */ + if (kconn->connector) { + drmModeFreeConnector(kconn->connector); + free(kconn->kms_modes); + + kconn->connector = NULL; + kconn->kms_modes = NULL; + kconn->num_modes = 0; + } + + /* detect again */ + kconn->connector = drmModeGetConnector(kdpy->fd, kconn->connector_id); + if (!kconn->connector) + return NULL; + + count = kconn->connector->count_modes; + kconn->kms_modes = calloc(count, sizeof(*kconn->kms_modes)); + if (!kconn->kms_modes) { + drmModeFreeConnector(kconn->connector); + kconn->connector = NULL; + + return NULL; + } + + for (i = 0; i < count; i++) { + struct kms_mode *kmode = &kconn->kms_modes[i]; + drmModeModeInfoPtr mode = &kconn->connector->modes[i]; + + kmode->mode = *mode; + + 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; + } + + nmodes_return = malloc(count * sizeof(*nmodes_return)); + if (nmodes_return) { + for (i = 0; i < count; i++) + nmodes_return[i] = &kconn->kms_modes[i].base; + if (num_modes) + *num_modes = count; + } + + return nmodes_return; +} + +static const struct native_connector ** +kms_display_get_connectors(struct native_display *ndpy, int *num_connectors, + int *num_crtc) +{ + struct kms_display *kdpy = kms_display(ndpy); + const struct native_connector **connectors; + int i; + + if (!kdpy->connectors) { + kdpy->connectors = + calloc(kdpy->resources->count_connectors, sizeof(*kdpy->connectors)); + if (!kdpy->connectors) + return NULL; + + for (i = 0; i < kdpy->resources->count_connectors; i++) { + struct kms_connector *kconn = &kdpy->connectors[i]; + + kconn->connector_id = kdpy->resources->connectors[i]; + /* kconn->connector is allocated when the modes are asked */ + } + + kdpy->num_connectors = kdpy->resources->count_connectors; + } + + connectors = malloc(kdpy->num_connectors * sizeof(*connectors)); + if (connectors) { + for (i = 0; i < kdpy->num_connectors; i++) + connectors[i] = &kdpy->connectors[i].base; + if (num_connectors) + *num_connectors = kdpy->num_connectors; + } + + if (num_crtc) + *num_crtc = kdpy->resources->count_crtcs; + + return connectors; +} + +static struct native_surface * +kms_display_create_scanout_surface(struct native_display *ndpy, + const struct native_config *nconf, + uint width, uint height) +{ + struct kms_surface *ksurf; + + ksurf = kms_display_create_surface(ndpy, + KMS_SURFACE_TYPE_SCANOUT, nconf, width, height); + return &ksurf->base; +} + +static struct native_surface * +kms_display_create_pbuffer_surface(struct native_display *ndpy, + const struct native_config *nconf, + uint width, uint height) +{ + struct kms_surface *ksurf; + + ksurf = kms_display_create_surface(ndpy, + KMS_SURFACE_TYPE_PBUFFER, nconf, width, height); + return &ksurf->base; +} + +static struct pipe_context * +kms_display_create_context(struct native_display *ndpy, void *context_private) +{ + struct kms_display *kdpy = kms_display(ndpy); + struct pipe_context *pctx; + + pctx = kdpy->api->create_context(kdpy->api, kdpy->base.screen); + if (pctx) + pctx->priv = context_private; + return pctx; +} + +static boolean +kms_display_is_format_supported(struct native_display *ndpy, + enum pipe_format fmt, boolean is_color) +{ + return ndpy->screen->is_format_supported(ndpy->screen, + fmt, PIPE_TEXTURE_2D, + (is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET : + PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); +} + +static const struct native_config ** +kms_display_get_configs(struct native_display *ndpy, int *num_configs) +{ + struct kms_display *kdpy = kms_display(ndpy); + const struct native_config **configs; + + /* first time */ + if (!kdpy->config) { + struct native_config *nconf; + enum pipe_format format; + + kdpy->config = calloc(1, sizeof(*kdpy->config)); + if (!kdpy->config) + return NULL; + + nconf = &kdpy->config->base; + + /* always double-buffered */ + nconf->mode.doubleBufferMode = TRUE; + + format = PIPE_FORMAT_A8R8G8B8_UNORM; + if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) { + format = PIPE_FORMAT_B8G8R8A8_UNORM; + if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) + format = PIPE_FORMAT_NONE; + } + if (format == PIPE_FORMAT_NONE) + return NULL; + + nconf->color_format = format; + nconf->mode.redBits = 8; + nconf->mode.greenBits = 8; + nconf->mode.blueBits = 8; + nconf->mode.alphaBits = 8; + nconf->mode.rgbBits = 32; + + format = PIPE_FORMAT_S8Z24_UNORM; + if (!kms_display_is_format_supported(&kdpy->base, format, FALSE)) { + format = PIPE_FORMAT_Z24S8_UNORM; + if (!kms_display_is_format_supported(&kdpy->base, format, FALSE)) + format = PIPE_FORMAT_NONE; + } + if (format != PIPE_FORMAT_NONE) { + nconf->depth_format = format; + nconf->stencil_format = format; + + nconf->mode.depthBits = 24; + nconf->mode.stencilBits = 8; + nconf->mode.haveDepthBuffer = TRUE; + nconf->mode.haveStencilBuffer = TRUE; + } + + nconf->scanout_bit = TRUE; + nconf->mode.drawableType = GLX_PBUFFER_BIT; + nconf->mode.swapMethod = GLX_SWAP_EXCHANGE_OML; + + nconf->mode.visualID = 0; + nconf->mode.visualType = EGL_NONE; + + nconf->mode.renderType = GLX_RGBA_BIT; + nconf->mode.rgbMode = TRUE; + nconf->mode.xRenderable = FALSE; + } + + configs = malloc(sizeof(*configs)); + if (configs) { + configs[0] = &kdpy->config->base; + if (num_configs) + *num_configs = 1; + } + + return configs; +} + +static void +kms_display_destroy(struct native_display *ndpy) +{ + struct kms_display *kdpy = kms_display(ndpy); + int i; + + if (kdpy->config) + free(kdpy->config); + + if (kdpy->connectors) { + for (i = 0; i < kdpy->num_connectors; i++) { + struct kms_connector *kconn = &kdpy->connectors[i]; + if (kconn->connector) { + drmModeFreeConnector(kconn->connector); + free(kconn->kms_modes); + } + } + free(kdpy->connectors); + } + + if (kdpy->shown_surfaces) + free(kdpy->shown_surfaces); + + if (kdpy->saved_crtcs) { + for (i = 0; i < kdpy->resources->count_crtcs; i++) { + struct kms_crtc *kcrtc = &kdpy->saved_crtcs[i]; + + if (kcrtc->crtc) { + /* restore crtc */ + drmModeSetCrtc(kdpy->fd, kcrtc->crtc->crtc_id, + kcrtc->crtc->buffer_id, kcrtc->crtc->x, kcrtc->crtc->y, + kcrtc->connectors, kcrtc->num_connectors, + &kcrtc->crtc->mode); + + drmModeFreeCrtc(kcrtc->crtc); + } + } + free(kdpy->saved_crtcs); + } + + if (kdpy->resources) + drmModeFreeResources(kdpy->resources); + + if (kdpy->base.screen) + kdpy->base.screen->destroy(kdpy->base.screen); + + if (kdpy->fd >= 0) + drmClose(kdpy->fd); + + if (kdpy->api) + kdpy->api->destroy(kdpy->api); + free(kdpy); +} + +/** + * Initialize KMS and pipe screen. + */ +static boolean +kms_display_init_screen(struct native_display *ndpy) +{ + struct kms_display *kdpy = kms_display(ndpy); + struct drm_create_screen_arg arg; + int fd; + + fd = drmOpen(kdpy->api->name, NULL); + if (fd < 0) { + _eglLog(_EGL_WARNING, "failed to open DRM device"); + return FALSE; + } + +#if 0 + if (drmSetMaster(fd)) { + _eglLog(_EGL_WARNING, "failed to become DRM master"); + return FALSE; + } +#endif + + memset(&arg, 0, sizeof(arg)); + arg.mode = DRM_CREATE_NORMAL; + kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd, &arg); + if (!kdpy->base.screen) { + _eglLog(_EGL_WARNING, "failed to create DRM screen"); + drmClose(fd); + return FALSE; + } + + kdpy->fd = fd; + + return TRUE; +} + +static struct native_display_modeset kms_display_modeset = { + .get_connectors = kms_display_get_connectors, + .get_modes = kms_display_get_modes, + .create_scanout_surface = kms_display_create_scanout_surface, + .program = kms_display_program +}; + +static struct native_display * +kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api) +{ + struct kms_display *kdpy; + + kdpy = CALLOC_STRUCT(kms_display); + if (!kdpy) + return NULL; + + kdpy->api = api; + if (!kdpy->api) { + _eglLog(_EGL_WARNING, "failed to create DRM API"); + free(kdpy); + return NULL; + } + + kdpy->fd = -1; + if (!kms_display_init_screen(&kdpy->base)) { + kms_display_destroy(&kdpy->base); + return NULL; + } + + /* resources are fixed, unlike crtc, connector, or encoder */ + kdpy->resources = drmModeGetResources(kdpy->fd); + if (!kdpy->resources) { + kms_display_destroy(&kdpy->base); + return NULL; + } + + kdpy->saved_crtcs = + calloc(kdpy->resources->count_crtcs, sizeof(*kdpy->saved_crtcs)); + if (!kdpy->saved_crtcs) { + kms_display_destroy(&kdpy->base); + return NULL; + } + + kdpy->shown_surfaces = + calloc(kdpy->resources->count_crtcs, sizeof(*kdpy->shown_surfaces)); + if (!kdpy->shown_surfaces) { + kms_display_destroy(&kdpy->base); + return NULL; + } + + kdpy->base.destroy = kms_display_destroy; + kdpy->base.get_configs = kms_display_get_configs; + kdpy->base.create_context = kms_display_create_context; + kdpy->base.create_pbuffer_surface = kms_display_create_pbuffer_surface; + + kdpy->base.modeset = &kms_display_modeset; + + return &kdpy->base; +} + +struct native_probe * +native_create_probe(EGLNativeDisplayType dpy) +{ + return NULL; +} + +enum native_probe_result +native_get_probe_result(struct native_probe *nprobe) +{ + return NATIVE_PROBE_UNKNOWN; +} + +/* the api is destroyed with the native display */ +static struct drm_api *drm_api; + +const char * +native_get_name(void) +{ + static char kms_name[32]; + + if (!drm_api) + drm_api = drm_api_create(); + + if (drm_api) + snprintf(kms_name, sizeof(kms_name), "KMS/%s", drm_api->name); + else + snprintf(kms_name, sizeof(kms_name), "KMS"); + + return kms_name; +} + +struct native_display * +native_create_display(EGLNativeDisplayType dpy) +{ + struct native_display *ndpy = NULL; + + if (!drm_api) + drm_api = drm_api_create(); + + if (drm_api) + ndpy = kms_create_display(dpy, 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 new file mode 100644 index 0000000000..095186e3cf --- /dev/null +++ b/src/gallium/state_trackers/egl/kms/native_kms.h @@ -0,0 +1,139 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2010 Chia-I Wu + * + * 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_KMS_H_ +#define _NATIVE_KMS_H_ + +#include +#include + +#include "pipe/p_compiler.h" +#include "util/u_format.h" +#include "pipe/p_state.h" +#include "state_tracker/drm_api.h" + +#include "common/native.h" + +enum kms_surface_type { + KMS_SURFACE_TYPE_PBUFFER, + KMS_SURFACE_TYPE_SCANOUT +}; + +struct kms_config; +struct kms_connector; +struct kms_mode; + +struct kms_crtc { + drmModeCrtcPtr crtc; + uint32_t connectors[32]; + int num_connectors; +}; + +struct kms_display { + struct native_display base; + + int fd; + struct drm_api *api; + drmModeResPtr resources; + struct kms_config *config; + + struct kms_connector *connectors; + int num_connectors; + + struct kms_surface **shown_surfaces; + /* save the original settings of the CRTCs */ + struct kms_crtc *saved_crtcs; +}; + +struct kms_framebuffer { + struct pipe_texture *texture; + boolean is_passive; + + uint32_t buffer_id; +}; + +struct kms_surface { + struct native_surface base; + enum kms_surface_type type; + enum pipe_format color_format; + struct kms_display *kdpy; + int width, height; + + struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; + unsigned int sequence_number; + struct kms_framebuffer front_fb, back_fb; + + boolean is_shown; + struct kms_crtc current_crtc; +}; + +struct kms_config { + struct native_config base; +}; + +struct kms_connector { + struct native_connector base; + + uint32_t connector_id; + drmModeConnectorPtr connector; + struct kms_mode *kms_modes; + int num_modes; +}; + +struct kms_mode { + struct native_mode base; + drmModeModeInfo mode; +}; + +static INLINE struct kms_display * +kms_display(const struct native_display *ndpy) +{ + return (struct kms_display *) ndpy; +} + +static INLINE struct kms_surface * +kms_surface(const struct native_surface *nsurf) +{ + return (struct kms_surface *) nsurf; +} + +static INLINE struct kms_config * +kms_config(const struct native_config *nconf) +{ + return (struct kms_config *) nconf; +} + +static INLINE struct kms_connector * +kms_connector(const struct native_connector *nconn) +{ + return (struct kms_connector *) nconn; +} + +static INLINE struct kms_mode * +kms_mode(const struct native_mode *nmode) +{ + return (struct kms_mode *) nmode; +} + +#endif /* _NATIVE_KMS_H_ */ diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c new file mode 100644 index 0000000000..07f82d878c --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/native_dri2.c @@ -0,0 +1,705 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu + * + * 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. + */ + +#include "util/u_memory.h" +#include "util/u_math.h" +#include "util/u_format.h" +#include "pipe/p_compiler.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "state_tracker/drm_api.h" +#include "egllog.h" + +#include "native_x11.h" +#include "x11_screen.h" + +enum dri2_surface_type { + DRI2_SURFACE_TYPE_WINDOW, + DRI2_SURFACE_TYPE_PIXMAP, + DRI2_SURFACE_TYPE_PBUFFER +}; + +struct dri2_display { + struct native_display base; + Display *dpy; + boolean own_dpy; + + struct drm_api *api; + struct x11_screen *xscr; + int xscr_number; + + struct dri2_config *configs; + int num_configs; +}; + +struct dri2_surface { + struct native_surface base; + Drawable drawable; + enum dri2_surface_type type; + enum pipe_format color_format; + struct dri2_display *dri2dpy; + + struct pipe_texture *pbuffer_textures[NUM_NATIVE_ATTACHMENTS]; + boolean have_back, have_fake; + int width, height; + unsigned int sequence_number; +}; + +struct dri2_config { + struct native_config base; +}; + +static INLINE struct dri2_display * +dri2_display(const struct native_display *ndpy) +{ + return (struct dri2_display *) ndpy; +} + +static INLINE struct dri2_surface * +dri2_surface(const struct native_surface *nsurf) +{ + return (struct dri2_surface *) nsurf; +} + +static INLINE struct dri2_config * +dri2_config(const struct native_config *nconf) +{ + return (struct dri2_config *) nconf; +} + +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); + + 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); + + 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); + struct dri2_display *dri2dpy = dri2surf->dri2dpy; + unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS]; + struct pipe_texture templ; + 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)) { + unsigned int dri2att; + + switch (att) { + case NATIVE_ATTACHMENT_FRONT_LEFT: + dri2att = DRI2BufferFrontLeft; + break; + case NATIVE_ATTACHMENT_BACK_LEFT: + dri2att = DRI2BufferBackLeft; + break; + case NATIVE_ATTACHMENT_FRONT_RIGHT: + dri2att = DRI2BufferFrontRight; + break; + case NATIVE_ATTACHMENT_BACK_RIGHT: + dri2att = DRI2BufferBackRight; + break; + default: + assert(0); + dri2att = 0; + break; + } + + dri2atts[num_ins] = dri2att; + num_ins++; + } + } + + 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++; + + 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; + + 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; + } + + 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; + } + + 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; + } + } + } + + free(xbufs); + + if (seq_num) + *seq_num = dri2surf->sequence_number; + if (width) + *width = dri2surf->width; + if (height) + *height = dri2surf->height; + + return TRUE; +} + +static void +dri2_surface_wait(struct native_surface *nsurf) +{ + struct dri2_surface *dri2surf = dri2_surface(nsurf); + struct dri2_display *dri2dpy = dri2surf->dri2dpy; + + if (dri2surf->have_fake) { + x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable, + 0, 0, dri2surf->width, dri2surf->height, + DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); + } +} + +static void +dri2_surface_destroy(struct native_surface *nsurf) +{ + struct dri2_surface *dri2surf = dri2_surface(nsurf); + int i; + + for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { + struct pipe_texture *ptex = dri2surf->pbuffer_textures[i]; + pipe_texture_reference(&ptex, NULL); + } + + if (dri2surf->drawable) + x11_drawable_enable_dri2(dri2surf->dri2dpy->xscr, + dri2surf->drawable, FALSE); + free(dri2surf); +} + +static struct dri2_surface * +dri2_display_create_surface(struct native_display *ndpy, + enum dri2_surface_type type, + Drawable drawable, + const struct native_config *nconf) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + struct dri2_config *dri2conf = dri2_config(nconf); + struct dri2_surface *dri2surf; + + dri2surf = CALLOC_STRUCT(dri2_surface); + if (!dri2surf) + return NULL; + + if (drawable) + x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE); + + dri2surf->dri2dpy = dri2dpy; + dri2surf->type = type; + dri2surf->drawable = drawable; + dri2surf->color_format = dri2conf->base.color_format; + + dri2surf->base.destroy = dri2_surface_destroy; + dri2surf->base.swap_buffers = dri2_surface_swap_buffers; + dri2surf->base.flush_frontbuffer = dri2_surface_flush_frontbuffer; + dri2surf->base.validate = dri2_surface_validate; + dri2surf->base.wait = dri2_surface_wait; + + return dri2surf; +} + +static struct native_surface * +dri2_display_create_window_surface(struct native_display *ndpy, + EGLNativeWindowType win, + const struct native_config *nconf) +{ + struct dri2_surface *dri2surf; + + dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_WINDOW, + (Drawable) win, nconf); + return (dri2surf) ? &dri2surf->base : NULL; +} + +static struct native_surface * +dri2_display_create_pixmap_surface(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf) +{ + struct dri2_surface *dri2surf; + + dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PIXMAP, + (Drawable) pix, nconf); + return (dri2surf) ? &dri2surf->base : NULL; +} + +static struct native_surface * +dri2_display_create_pbuffer_surface(struct native_display *ndpy, + const struct native_config *nconf, + uint width, uint height) +{ + struct dri2_surface *dri2surf; + + dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PBUFFER, + (Drawable) None, nconf); + if (dri2surf) { + dri2surf->width = width; + dri2surf->height = height; + } + return (dri2surf) ? &dri2surf->base : NULL; +} + +static struct pipe_context * +dri2_display_create_context(struct native_display *ndpy, void *context_private) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + struct pipe_context *pctx; + + pctx = dri2dpy->api->create_context(dri2dpy->api, dri2dpy->base.screen); + if (pctx) + pctx->priv = context_private; + return pctx; +} + +static int +choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32]) +{ + int count = 0; + + switch (mode->rgbBits) { + case 32: + formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM; + formats[count++] = PIPE_FORMAT_B8G8R8A8_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_B8G8R8A8_UNORM; + break; + case 16: + formats[count++] = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + break; + } + + return count; +} + +static int +choose_depth_stencil_format(const __GLcontextModes *mode, + enum pipe_format formats[32]) +{ + int count = 0; + + switch (mode->depthBits) { + case 32: + formats[count++] = PIPE_FORMAT_Z32_UNORM; + break; + case 24: + if (mode->stencilBits) { + formats[count++] = PIPE_FORMAT_S8Z24_UNORM; + formats[count++] = PIPE_FORMAT_Z24S8_UNORM; + } + else { + formats[count++] = PIPE_FORMAT_X8Z24_UNORM; + formats[count++] = PIPE_FORMAT_Z24X8_UNORM; + } + break; + case 16: + formats[count++] = PIPE_FORMAT_Z16_UNORM; + break; + default: + break; + } + + return count; +} + +static boolean +is_format_supported(struct pipe_screen *screen, + enum pipe_format fmt, boolean is_color) +{ + return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, + (is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET : + PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); +} + +static boolean +dri2_display_convert_config(struct native_display *ndpy, + const __GLcontextModes *mode, + struct native_config *nconf) +{ + enum pipe_format formats[32]; + int num_formats, i; + + if (!(mode->renderType & GLX_RGBA_BIT) || !mode->rgbMode) + return FALSE; + + /* skip single-buffered configs */ + if (!mode->doubleBufferMode) + return FALSE; + + nconf->mode = *mode; + nconf->mode.renderType = GLX_RGBA_BIT; + nconf->mode.rgbMode = TRUE; + /* pbuffer is allocated locally and is always supported */ + nconf->mode.drawableType |= GLX_PBUFFER_BIT; + /* the swap method is always copy */ + nconf->mode.swapMethod = GLX_SWAP_COPY_OML; + + /* fix up */ + nconf->mode.rgbBits = + nconf->mode.redBits + nconf->mode.greenBits + + nconf->mode.blueBits + nconf->mode.alphaBits; + if (!(nconf->mode.drawableType & GLX_WINDOW_BIT)) { + nconf->mode.visualID = 0; + nconf->mode.visualType = GLX_NONE; + } + if (!(nconf->mode.drawableType & GLX_PBUFFER_BIT)) { + nconf->mode.bindToTextureRgb = FALSE; + nconf->mode.bindToTextureRgba = FALSE; + } + + nconf->color_format = PIPE_FORMAT_NONE; + nconf->depth_format = PIPE_FORMAT_NONE; + nconf->stencil_format = PIPE_FORMAT_NONE; + + /* choose color format */ + num_formats = choose_color_format(mode, formats); + for (i = 0; i < num_formats; i++) { + if (is_format_supported(ndpy->screen, formats[i], TRUE)) { + nconf->color_format = formats[i]; + break; + } + } + if (nconf->color_format == PIPE_FORMAT_NONE) + return FALSE; + + /* choose depth/stencil format */ + num_formats = choose_depth_stencil_format(mode, formats); + for (i = 0; i < num_formats; i++) { + if (is_format_supported(ndpy->screen, formats[i], FALSE)) { + nconf->depth_format = formats[i]; + nconf->stencil_format = formats[i]; + break; + } + } + if ((nconf->mode.depthBits && nconf->depth_format == PIPE_FORMAT_NONE) || + (nconf->mode.stencilBits && nconf->stencil_format == PIPE_FORMAT_NONE)) + return FALSE; + + return TRUE; +} + +static const struct native_config ** +dri2_display_get_configs(struct native_display *ndpy, int *num_configs) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + const struct native_config **configs; + int i; + + /* first time */ + if (!dri2dpy->configs) { + const __GLcontextModes *modes; + int num_modes, count; + + modes = x11_screen_get_glx_configs(dri2dpy->xscr); + if (!modes) + return NULL; + num_modes = x11_context_modes_count(modes); + + dri2dpy->configs = calloc(num_modes, sizeof(*dri2dpy->configs)); + if (!dri2dpy->configs) + return NULL; + + count = 0; + for (i = 0; i < num_modes; i++) { + struct native_config *nconf = &dri2dpy->configs[count].base; + if (dri2_display_convert_config(&dri2dpy->base, modes, nconf)) + count++; + modes = modes->next; + } + + dri2dpy->num_configs = count; + } + + configs = malloc(dri2dpy->num_configs * sizeof(*configs)); + if (configs) { + for (i = 0; i < dri2dpy->num_configs; i++) + configs[i] = (const struct native_config *) &dri2dpy->configs[i]; + if (num_configs) + *num_configs = dri2dpy->num_configs; + } + + return configs; +} + +static boolean +dri2_display_is_pixmap_supported(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + uint depth, nconf_depth; + + depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix); + nconf_depth = util_format_get_blocksizebits(nconf->color_format); + + /* simple depth match for now */ + return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth)); +} + +static void +dri2_display_destroy(struct native_display *ndpy) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + + if (dri2dpy->configs) + free(dri2dpy->configs); + + if (dri2dpy->base.screen) + dri2dpy->base.screen->destroy(dri2dpy->base.screen); + + if (dri2dpy->xscr) + x11_screen_destroy(dri2dpy->xscr); + if (dri2dpy->own_dpy) + XCloseDisplay(dri2dpy->dpy); + if (dri2dpy->api && dri2dpy->api->destroy) + dri2dpy->api->destroy(dri2dpy->api); + free(dri2dpy); +} + +/** + * Initialize DRI2 and pipe screen. + */ +static boolean +dri2_display_init_screen(struct native_display *ndpy) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + const char *driver = dri2dpy->api->name; + struct drm_create_screen_arg arg; + int fd; + + if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) || + !x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_GLX)) { + _eglLog(_EGL_WARNING, "GLX/DRI2 is not supported"); + return FALSE; + } + + fd = x11_screen_enable_dri2(dri2dpy->xscr, driver); + if (fd < 0) + return FALSE; + + memset(&arg, 0, sizeof(arg)); + arg.mode = DRM_CREATE_NORMAL; + dri2dpy->base.screen = dri2dpy->api->create_screen(dri2dpy->api, fd, &arg); + if (!dri2dpy->base.screen) { + _eglLog(_EGL_WARNING, "failed to create DRM screen"); + return FALSE; + } + + return TRUE; +} + +struct native_display * +x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api) +{ + struct dri2_display *dri2dpy; + + dri2dpy = CALLOC_STRUCT(dri2_display); + if (!dri2dpy) + return NULL; + + dri2dpy->api = api; + if (!dri2dpy->api) { + _eglLog(_EGL_WARNING, "failed to create DRM API"); + free(dri2dpy); + return NULL; + } + + dri2dpy->dpy = dpy; + if (!dri2dpy->dpy) { + dri2dpy->dpy = XOpenDisplay(NULL); + if (!dri2dpy->dpy) { + dri2_display_destroy(&dri2dpy->base); + return NULL; + } + dri2dpy->own_dpy = TRUE; + } + + dri2dpy->xscr_number = DefaultScreen(dri2dpy->dpy); + dri2dpy->xscr = x11_screen_create(dri2dpy->dpy, dri2dpy->xscr_number); + if (!dri2dpy->xscr) { + dri2_display_destroy(&dri2dpy->base); + return NULL; + } + + if (!dri2_display_init_screen(&dri2dpy->base)) { + dri2_display_destroy(&dri2dpy->base); + return NULL; + } + + dri2dpy->base.destroy = dri2_display_destroy; + dri2dpy->base.get_configs = dri2_display_get_configs; + dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported; + dri2dpy->base.create_context = dri2_display_create_context; + dri2dpy->base.create_window_surface = dri2_display_create_window_surface; + dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface; + dri2dpy->base.create_pbuffer_surface = dri2_display_create_pbuffer_surface; + + return &dri2dpy->base; +} diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c new file mode 100644 index 0000000000..695ab88010 --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/native_x11.c @@ -0,0 +1,148 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu + * + * 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. + */ + +#include +#include "util/u_debug.h" +#include "util/u_memory.h" +#include "state_tracker/drm_api.h" +#include "egllog.h" + +#include "native_x11.h" +#include "x11_screen.h" + +#define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */ + +static struct drm_api *api; + +static void +x11_probe_destroy(struct native_probe *nprobe) +{ + if (nprobe->data) + free(nprobe->data); + free(nprobe); +} + +struct native_probe * +native_create_probe(EGLNativeDisplayType dpy) +{ + struct native_probe *nprobe; + struct x11_screen *xscr; + int scr; + const char *driver_name = NULL; + Display *xdpy; + + nprobe = CALLOC_STRUCT(native_probe); + if (!nprobe) + return NULL; + + xdpy = dpy; + if (!xdpy) { + xdpy = XOpenDisplay(NULL); + if (!xdpy) { + free(nprobe); + return NULL; + } + } + + scr = DefaultScreen(xdpy); + xscr = x11_screen_create(xdpy, scr); + if (xscr) { + if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) { + driver_name = x11_screen_probe_dri2(xscr); + nprobe->data = strdup(driver_name); + } + + x11_screen_destroy(xscr); + } + + if (xdpy != dpy) + XCloseDisplay(xdpy); + + nprobe->magic = X11_PROBE_MAGIC; + nprobe->display = dpy; + + nprobe->destroy = x11_probe_destroy; + + return nprobe; +} + +enum native_probe_result +native_get_probe_result(struct native_probe *nprobe) +{ + if (!nprobe || nprobe->magic != X11_PROBE_MAGIC) + return NATIVE_PROBE_UNKNOWN; + + if (!api) + api = drm_api_create(); + + /* this is a software driver */ + if (!api) + return NATIVE_PROBE_SUPPORTED; + + /* the display does not support DRI2 or the driver mismatches */ + if (!nprobe->data || strcmp(api->name, (const char *) nprobe->data) != 0) + return NATIVE_PROBE_FALLBACK; + + return NATIVE_PROBE_EXACT; +} + +const char * +native_get_name(void) +{ + static char x11_name[32]; + + if (!api) + api = drm_api_create(); + + if (api) + snprintf(x11_name, sizeof(x11_name), "X11/%s", api->name); + else + snprintf(x11_name, sizeof(x11_name), "X11"); + + return x11_name; +} + +struct native_display * +native_create_display(EGLNativeDisplayType dpy) +{ + struct native_display *ndpy = NULL; + boolean force_sw; + + if (!api) + api = drm_api_create(); + + force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE); + if (api && !force_sw) { + ndpy = x11_create_dri2_display(dpy, api); + } + + if (!ndpy) { + EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING; + + _eglLog(level, "use software fallback"); + ndpy = x11_create_ximage_display(dpy, TRUE); + } + + return ndpy; +} diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h new file mode 100644 index 0000000000..622ddac5df --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/native_x11.h @@ -0,0 +1,37 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu + * + * 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_X11_H_ +#define _NATIVE_X11_H_ + +#include "state_tracker/drm_api.h" +#include "common/native.h" + +struct native_display * +x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm); + +struct native_display * +x11_create_dri2_display(EGLNativeDisplayType dpy, 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 new file mode 100644 index 0000000000..dfa8df2223 --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/native_ximage.c @@ -0,0 +1,694 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "util/u_memory.h" +#include "util/u_math.h" +#include "util/u_format.h" +#include "pipe/p_compiler.h" +#include "pipe/internal/p_winsys_screen.h" +#include "softpipe/sp_winsys.h" +#include "egllog.h" + +#include "sw_winsys.h" +#include "native_x11.h" +#include "x11_screen.h" + +enum ximage_surface_type { + XIMAGE_SURFACE_TYPE_WINDOW, + XIMAGE_SURFACE_TYPE_PIXMAP, + XIMAGE_SURFACE_TYPE_PBUFFER +}; + +struct ximage_display { + struct native_display base; + Display *dpy; + boolean own_dpy; + + 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 ximage_surface { + struct native_surface base; + Drawable drawable; + enum ximage_surface_type type; + enum pipe_format color_format; + XVisualInfo visual; + struct ximage_display *xdpy; + + int width, height; + GC gc; + + struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS]; + unsigned int sequence_number; +}; + +struct ximage_config { + struct native_config base; + const XVisualInfo *visual; +}; + +static INLINE struct ximage_display * +ximage_display(const struct native_display *ndpy) +{ + return (struct ximage_display *) ndpy; +} + +static INLINE struct ximage_surface * +ximage_surface(const struct native_surface *nsurf) +{ + return (struct ximage_surface *) nsurf; +} + +static INLINE struct ximage_config * +ximage_config(const struct native_config *nconf) +{ + return (struct ximage_config *) nconf; +} + +static void +ximage_surface_free_buffer(struct native_surface *nsurf, + enum native_attachment which) +{ + struct ximage_surface *xsurf = ximage_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 +ximage_surface_alloc_buffer(struct native_surface *nsurf, + enum native_attachment which) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + struct ximage_buffer *xbuf = &xsurf->buffers[which]; + struct pipe_screen *screen = xsurf->xdpy->base.screen; + struct pipe_texture templ; + + /* free old data */ + if (xbuf->texture) + ximage_surface_free_buffer(&xsurf->base, which); + + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.format = xsurf->color_format; + templ.width0 = xsurf->width; + templ.height0 = xsurf->height; + 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); + } + } + } + else { + xbuf->texture = screen->texture_create(screen, &templ); + } + + /* clean up the buffer if allocation failed */ + if (!xbuf->texture) + ximage_surface_free_buffer(&xsurf->base, which); + + return (xbuf->texture != NULL); +} + +static boolean +ximage_surface_draw_buffer(struct native_surface *nsurf, + enum native_attachment which) +{ + 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; + + if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER) + return TRUE; + + assert(xsurf->drawable && xbuf->ximage && xbuf->texture); + + transfer = screen->get_tex_transfer(screen, xbuf->texture, + 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height); + if (!transfer) + 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); + + /* + * 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); + + return TRUE; +} + +static boolean +ximage_surface_flush_frontbuffer(struct native_surface *nsurf) +{ + return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); +} + +static boolean +ximage_surface_swap_buffers(struct native_surface *nsurf) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + struct ximage_buffer *xfront, *xback, xtmp; + + 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; + } +} + +static boolean +ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask, + unsigned int *seq_num, struct pipe_texture **textures, + int *width, int *height) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + boolean new_buffers = FALSE; + int att; + + ximage_surface_update_geometry(&xsurf->base); + + 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 (textures) { + 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) + *height = xsurf->height; + + return TRUE; +} + +static void +ximage_surface_wait(struct native_surface *nsurf) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + XSync(xsurf->xdpy->dpy, FALSE); + /* TODO XGetImage and update the front texture */ +} + +static void +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]; + 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); +} + +static struct ximage_surface * +ximage_display_create_surface(struct native_display *ndpy, + enum ximage_surface_type type, + Drawable drawable, + const struct native_config *nconf) +{ + 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) + return NULL; + + xsurf->xdpy = xdpy; + xsurf->type = type; + xsurf->color_format = xconf->base.color_format; + xsurf->drawable = drawable; + + 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; + } + } + } + + xsurf->base.destroy = ximage_surface_destroy; + xsurf->base.swap_buffers = ximage_surface_swap_buffers; + xsurf->base.flush_frontbuffer = ximage_surface_flush_frontbuffer; + xsurf->base.validate = ximage_surface_validate; + xsurf->base.wait = ximage_surface_wait; + + return xsurf; +} + +static struct native_surface * +ximage_display_create_window_surface(struct native_display *ndpy, + EGLNativeWindowType win, + const struct native_config *nconf) +{ + struct ximage_surface *xsurf; + + xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_WINDOW, + (Drawable) win, nconf); + return (xsurf) ? &xsurf->base : NULL; +} + +static struct native_surface * +ximage_display_create_pixmap_surface(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf) +{ + struct ximage_surface *xsurf; + + xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PIXMAP, + (Drawable) pix, nconf); + return (xsurf) ? &xsurf->base : NULL; +} + +static struct native_surface * +ximage_display_create_pbuffer_surface(struct native_display *ndpy, + const struct native_config *nconf, + uint width, uint height) +{ + struct ximage_surface *xsurf; + + xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PBUFFER, + (Drawable) None, nconf); + if (xsurf) { + xsurf->width = width; + xsurf->height = height; + } + return (xsurf) ? &xsurf->base : NULL; +} + +static struct pipe_context * +ximage_display_create_context(struct native_display *ndpy, + void *context_private) +{ + struct pipe_context *pctx = softpipe_create(ndpy->screen); + if (pctx) + pctx->priv = context_private; + return pctx; +} + +static enum pipe_format +choose_format(const XVisualInfo *vinfo) +{ + enum pipe_format fmt; + /* TODO elaborate the formats */ + switch (vinfo->depth) { + case 32: + fmt = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case 24: + fmt = PIPE_FORMAT_X8R8G8B8_UNORM; + break; + case 16: + fmt = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + fmt = PIPE_FORMAT_NONE; + break; + } + + return fmt; +} + +static const struct native_config ** +ximage_display_get_configs(struct native_display *ndpy, int *num_configs) +{ + struct ximage_display *xdpy = ximage_display(ndpy); + const struct native_config **configs; + int i; + + /* first time */ + if (!xdpy->configs) { + const XVisualInfo *visuals; + int num_visuals, count, j; + + visuals = x11_screen_get_visuals(xdpy->xscr, &num_visuals); + if (!visuals) + return NULL; + + /* + * Create two configs for each visual. + * One with depth/stencil buffer; one without + */ + xdpy->configs = calloc(num_visuals * 2, sizeof(*xdpy->configs)); + if (!xdpy->configs) + return NULL; + + count = 0; + for (i = 0; i < num_visuals; i++) { + for (j = 0; j < 2; j++) { + struct ximage_config *xconf = &xdpy->configs[count]; + __GLcontextModes *mode = &xconf->base.mode; + + xconf->visual = &visuals[i]; + xconf->base.color_format = choose_format(xconf->visual); + if (xconf->base.color_format == PIPE_FORMAT_NONE) + continue; + + x11_screen_convert_visual(xdpy->xscr, xconf->visual, mode); + /* support double buffer mode */ + mode->doubleBufferMode = TRUE; + + xconf->base.depth_format = PIPE_FORMAT_NONE; + 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; + mode->depthBits = 24; + mode->stencilBits = 8; + mode->haveDepthBuffer = TRUE; + mode->haveStencilBuffer = TRUE; + } + + mode->maxPbufferWidth = 4096; + mode->maxPbufferHeight = 4096; + mode->maxPbufferPixels = 4096 * 4096; + mode->drawableType = + GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; + mode->swapMethod = GLX_SWAP_EXCHANGE_OML; + + if (mode->alphaBits) + mode->bindToTextureRgba = TRUE; + else + mode->bindToTextureRgb = TRUE; + + count++; + } + } + + xdpy->num_configs = count; + } + + configs = malloc(xdpy->num_configs * sizeof(*configs)); + if (configs) { + for (i = 0; i < xdpy->num_configs; i++) + configs[i] = (const struct native_config *) &xdpy->configs[i]; + if (num_configs) + *num_configs = xdpy->num_configs; + } + return configs; +} + +static boolean +ximage_display_is_pixmap_supported(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf) +{ + struct ximage_display *xdpy = ximage_display(ndpy); + enum pipe_format fmt; + uint depth; + + depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix); + switch (depth) { + case 32: + fmt = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case 24: + fmt = PIPE_FORMAT_X8R8G8B8_UNORM; + break; + case 16: + fmt = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + fmt = PIPE_FORMAT_NONE; + break; + } + + return (fmt == nconf->color_format); +} + +static void +ximage_display_destroy(struct native_display *ndpy) +{ + struct ximage_display *xdpy = ximage_display(ndpy); + + if (xdpy->configs) + free(xdpy->configs); + + xdpy->base.screen->destroy(xdpy->base.screen); + free(xdpy->winsys); + + x11_screen_destroy(xdpy->xscr); + if (xdpy->own_dpy) + XCloseDisplay(xdpy->dpy); + free(xdpy); +} + +struct native_display * +x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm) +{ + struct ximage_display *xdpy; + + xdpy = CALLOC_STRUCT(ximage_display); + if (!xdpy) + return NULL; + + xdpy->dpy = dpy; + if (!xdpy->dpy) { + xdpy->dpy = XOpenDisplay(NULL); + if (!xdpy->dpy) { + free(xdpy); + return NULL; + } + xdpy->own_dpy = TRUE; + } + + xdpy->xscr_number = DefaultScreen(xdpy->dpy); + xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number); + if (!xdpy->xscr) { + free(xdpy); + 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.destroy = ximage_display_destroy; + + xdpy->base.get_configs = ximage_display_get_configs; + xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported; + xdpy->base.create_context = ximage_display_create_context; + xdpy->base.create_window_surface = ximage_display_create_window_surface; + xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface; + xdpy->base.create_pbuffer_surface = ximage_display_create_pbuffer_surface; + + return &xdpy->base; +} diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.c b/src/gallium/state_trackers/egl/x11/sw_winsys.c new file mode 100644 index 0000000000..6ee3ede38c --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/sw_winsys.c @@ -0,0 +1,231 @@ +/************************************************************************** + * + * 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 "pipe/internal/p_winsys_screen.h" +#include "pipe/p_state.h" +#include "pipe/p_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 new file mode 100644 index 0000000000..f96c5a14b0 --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/sw_winsys.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * 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 new file mode 100644 index 0000000000..76ce45ee57 --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/x11_screen.c @@ -0,0 +1,453 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include "util/u_memory.h" +#include "util/u_math.h" +#include "util/u_format.h" +#include "xf86drm.h" +#include "egllog.h" + +#include "x11_screen.h" +#include "dri2.h" +#include "glxinit.h" + +struct x11_screen { + Display *dpy; + int number; + + /* + * This is used to fetch GLX visuals/fbconfigs. It uses code from egl_xdri. + * It might be better to rewrite the part in Xlib or XCB. + */ + __GLXdisplayPrivate *glx_dpy; + + int dri_major, dri_minor; + char *dri_driver; + char *dri_device; + int dri_fd; + + XVisualInfo *visuals; + int num_visuals; + + /* cached values for x11_drawable_get_depth */ + Drawable last_drawable; + unsigned int last_depth; +}; + + +/** + * Create a X11 screen. + */ +struct x11_screen * +x11_screen_create(Display *dpy, int screen) +{ + struct x11_screen *xscr; + + if (screen >= ScreenCount(dpy)) + return NULL; + + xscr = CALLOC_STRUCT(x11_screen); + if (xscr) { + xscr->dpy = dpy; + xscr->number = screen; + + xscr->dri_major = -1; + xscr->dri_fd = -1; + } + return xscr; +} + +/** + * Destroy a X11 screen. + */ +void +x11_screen_destroy(struct x11_screen *xscr) +{ + if (xscr->dri_fd >= 0) + close(xscr->dri_fd); + if (xscr->dri_driver) + Xfree(xscr->dri_driver); + if (xscr->dri_device) + Xfree(xscr->dri_device); + + /* xscr->glx_dpy will be destroyed with the X display */ + + if (xscr->visuals) + XFree(xscr->visuals); + free(xscr); +} + +static boolean +x11_screen_init_dri2(struct x11_screen *xscr) +{ + if (xscr->dri_major < 0) { + int eventBase, errorBase; + + if (!DRI2QueryExtension(xscr->dpy, &eventBase, &errorBase) || + !DRI2QueryVersion(xscr->dpy, &xscr->dri_major, &xscr->dri_minor)) + xscr->dri_major = -1; + } + return (xscr->dri_major >= 0); +} + +static boolean +x11_screen_init_glx(struct x11_screen *xscr) +{ + if (!xscr->glx_dpy) + xscr->glx_dpy = __glXInitialize(xscr->dpy); + return (xscr->glx_dpy != NULL); +} + +/** + * Return true if the screen supports the extension. + */ +boolean +x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext) +{ + boolean supported = FALSE; + + switch (ext) { + case X11_SCREEN_EXTENSION_XSHM: + supported = XShmQueryExtension(xscr->dpy); + break; + case X11_SCREEN_EXTENSION_GLX: + supported = x11_screen_init_glx(xscr); + break; + case X11_SCREEN_EXTENSION_DRI2: + supported = x11_screen_init_dri2(xscr); + break; + default: + break; + } + + return supported; +} + +/** + * Return the X visuals. + */ +const XVisualInfo * +x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals) +{ + if (!xscr->visuals) { + XVisualInfo vinfo_template; + vinfo_template.screen = xscr->number; + xscr->visuals = XGetVisualInfo(xscr->dpy, VisualScreenMask, + &vinfo_template, &xscr->num_visuals); + } + + if (num_visuals) + *num_visuals = xscr->num_visuals; + return xscr->visuals; +} + +void +x11_screen_convert_visual(struct x11_screen *xscr, const XVisualInfo *visual, + __GLcontextModes *mode) +{ + int r, g, b, a; + int visual_type; + + r = util_bitcount(visual->red_mask); + g = util_bitcount(visual->green_mask); + b = util_bitcount(visual->blue_mask); + a = visual->depth - (r + g + b); +#if defined(__cplusplus) || defined(c_plusplus) + visual_type = visual->c_class; +#else + visual_type = visual->class; +#endif + + /* convert to GLX visual type */ + switch (visual_type) { + case TrueColor: + visual_type = GLX_TRUE_COLOR; + break; + case DirectColor: + visual_type = GLX_DIRECT_COLOR; + break; + case PseudoColor: + visual_type = GLX_PSEUDO_COLOR; + break; + case StaticColor: + visual_type = GLX_STATIC_COLOR; + break; + case GrayScale: + visual_type = GLX_GRAY_SCALE; + break; + case StaticGray: + visual_type = GLX_STATIC_GRAY; + break; + default: + visual_type = GLX_NONE; + break; + } + + mode->rgbBits = r + g + b + a; + mode->redBits = r; + mode->greenBits = g; + mode->blueBits = b; + mode->alphaBits = a; + mode->visualID = visual->visualid; + mode->visualType = visual_type; + + /* sane defaults */ + mode->renderType = GLX_RGBA_BIT; + mode->rgbMode = TRUE; + mode->visualRating = GLX_SLOW_CONFIG; + mode->xRenderable = TRUE; +} + +/** + * Return the GLX fbconfigs. + */ +const __GLcontextModes * +x11_screen_get_glx_configs(struct x11_screen *xscr) +{ + return (x11_screen_init_glx(xscr)) + ? xscr->glx_dpy->screenConfigs[xscr->number].configs + : NULL; +} + +/** + * Return the GLX visuals. + */ +const __GLcontextModes * +x11_screen_get_glx_visuals(struct x11_screen *xscr) +{ + return (x11_screen_init_glx(xscr)) + ? xscr->glx_dpy->screenConfigs[xscr->number].visuals + : 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) +{ + /* 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; + } + + return xscr->dri_driver; +} + +/** + * Enable DRI2 and returns the file descriptor of the DRM device. The file + * descriptor will be closed automatically when the screen is destoryed. + */ +int +x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver) +{ + 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); + return -1; + } + + fd = open(xscr->dri_device, O_RDWR); + if (fd < 0) { + _eglLog(_EGL_WARNING, "failed to open %s", xscr->dri_device); + return -1; + } + + memset(&magic, 0, sizeof(magic)); + if (drmGetMagic(fd, &magic)) { + _eglLog(_EGL_WARNING, "failed to get magic"); + close(fd); + return -1; + } + + if (!DRI2Authenticate(xscr->dpy, + RootWindow(xscr->dpy, xscr->number), magic)) { + _eglLog(_EGL_WARNING, "failed to authenticate magic"); + close(fd); + return -1; + } + + xscr->dri_fd = fd; + } + + return xscr->dri_fd; +} + +/** + * Create/Destroy the DRI drawable. + */ +void +x11_drawable_enable_dri2(struct x11_screen *xscr, + Drawable drawable, boolean on) +{ + if (on) + DRI2CreateDrawable(xscr->dpy, drawable); + else + DRI2DestroyDrawable(xscr->dpy, drawable); +} + +/** + * Copy between buffers of the DRI2 drawable. + */ +void +x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable, + int x, int y, int width, int height, + int src_buf, int dst_buf) +{ + XRectangle rect; + XserverRegion region; + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + + region = XFixesCreateRegion(xscr->dpy, &rect, 1); + DRI2CopyRegion(xscr->dpy, drawable, region, dst_buf, src_buf); + XFixesDestroyRegion(xscr->dpy, region); +} + +/** + * Get the buffers of the DRI2 drawable. The returned array should be freed. + */ +struct x11_drawable_buffer * +x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable, + int *width, int *height, unsigned int *attachments, + boolean with_format, int num_ins, int *num_outs) +{ + DRI2Buffer *dri2bufs; + + if (with_format) + dri2bufs = DRI2GetBuffersWithFormat(xscr->dpy, drawable, width, height, + attachments, num_ins, num_outs); + else + dri2bufs = DRI2GetBuffers(xscr->dpy, drawable, width, height, + attachments, num_ins, num_outs); + + return (struct x11_drawable_buffer *) dri2bufs; +} + +/** + * Return the depth of a drawable. + * + * Unlike other drawable functions, the drawable needs not be a DRI2 drawable. + */ +uint +x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable) +{ + unsigned int depth; + + if (drawable != xscr->last_drawable) { + Window root; + int x, y; + unsigned int w, h, border; + Status ok; + + ok = XGetGeometry(xscr->dpy, drawable, &root, + &x, &y, &w, &h, &border, &depth); + if (!ok) + depth = 0; + + xscr->last_drawable = drawable; + xscr->last_depth = depth; + } + else { + depth = xscr->last_depth; + } + + return depth; +} + +/** + * Create a mode list of the given size. + */ +__GLcontextModes * +x11_context_modes_create(unsigned count) +{ + const size_t size = sizeof(__GLcontextModes); + __GLcontextModes *base = NULL; + __GLcontextModes **next; + unsigned i; + + next = &base; + for (i = 0; i < count; i++) { + *next = (__GLcontextModes *) calloc(1, size); + if (*next == NULL) { + x11_context_modes_destroy(base); + base = NULL; + break; + } + next = &((*next)->next); + } + + return base; +} + +/** + * Destroy a mode list. + */ +void +x11_context_modes_destroy(__GLcontextModes *modes) +{ + while (modes != NULL) { + __GLcontextModes *next = modes->next; + free(modes); + modes = next; + } +} + +/** + * Return the number of the modes in the mode list. + */ +unsigned +x11_context_modes_count(const __GLcontextModes *modes) +{ + const __GLcontextModes *mode; + int count = 0; + for (mode = modes; mode; mode = mode->next) + count++; + return count; +} diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.h b/src/gallium/state_trackers/egl/x11/x11_screen.h new file mode 100644 index 0000000000..5432858ac3 --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/x11_screen.h @@ -0,0 +1,105 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu + * + * 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 _X11_SCREEN_H_ +#define _X11_SCREEN_H_ + +#include +#include +#include +#include "pipe/p_compiler.h" +#include "common/native.h" + +enum x11_screen_extension { + X11_SCREEN_EXTENSION_XSHM, + X11_SCREEN_EXTENSION_GLX, + X11_SCREEN_EXTENSION_DRI2, +}; + +/* the same as DRI2Buffer */ +struct x11_drawable_buffer { + unsigned int attachment; + unsigned int name; + unsigned int pitch; + unsigned int cpp; + unsigned int flags; +}; + +struct x11_screen; + +struct x11_screen * +x11_screen_create(Display *dpy, int screen); + +void +x11_screen_destroy(struct x11_screen *xscr); + +boolean +x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext); + +const XVisualInfo * +x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals); + +void +x11_screen_convert_visual(struct x11_screen *xscr, const XVisualInfo *visual, + __GLcontextModes *mode); + +const __GLcontextModes * +x11_screen_get_glx_configs(struct x11_screen *xscr); + +const __GLcontextModes * +x11_screen_get_glx_visuals(struct x11_screen *xscr); + +const char * +x11_screen_probe_dri2(struct x11_screen *xscr); + +int +x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver); + +__GLcontextModes * +x11_context_modes_create(unsigned count); + +void +x11_context_modes_destroy(__GLcontextModes *modes); + +unsigned +x11_context_modes_count(const __GLcontextModes *modes); + +void +x11_drawable_enable_dri2(struct x11_screen *xscr, + Drawable drawable, boolean on); + +void +x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable, + int x, int y, int width, int height, + int src_buf, int dst_buf); + +struct x11_drawable_buffer * +x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable, + int *width, int *height, unsigned int *attachments, + boolean with_format, int num_ins, int *num_outs); + +uint +x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable); + +#endif /* _X11_SCREEN_H_ */ diff --git a/src/gallium/state_trackers/egl_g3d/Makefile b/src/gallium/state_trackers/egl_g3d/Makefile deleted file mode 100644 index b696f2fae9..0000000000 --- a/src/gallium/state_trackers/egl_g3d/Makefile +++ /dev/null @@ -1,75 +0,0 @@ -TOP = ../../../.. -include $(TOP)/configs/current - -common_INCLUDES = \ - -I. \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/egl/main \ - -I$(TOP)/include - -common_SOURCES = $(wildcard common/*.c) -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 -x11_OBJECTS = $(x11_SOURCES:.c=.o) - - -kms_INCLUDES = $(shell pkg-config --cflags-only-I libdrm) -kms_SOURCES = $(wildcard kms/*.c) -kms_OBJECTS = $(kms_SOURCES:.c=.o) - - -ALL_INCLUDES = $(common_INCLUDES) $(x11_INCLUDES) $(kms_INCLUDES) -ALL_SOURCES = $(common_SOURCES) $(x11_SOURCES) $(kms_SOURCES) -ALL_OBJECTS = $(common_OBJECTS) $(x11_OBJECTS) $(kms_OBJECTS) - -##### TARGETS ##### - -EGL_DISPLAYS_MODS = $(foreach dpy, $(EGL_DISPLAYS), libegl$(dpy).a) - -default: depend $(EGL_DISPLAYS_MODS) - - -libeglx11.a: $(x11_OBJECTS) $(common_OBJECTS) Makefile - $(MKLIB) -o eglx11 -static $(x11_OBJECTS) $(common_OBJECTS) - -libeglkms.a: $(kms_OBJECTS) $(common_OBJECTS) Makefile - $(MKLIB) -o eglkms -static $(kms_OBJECTS) $(common_OBJECTS) - -depend: - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(ALL_INCLUDES) $(ALL_SOURCES) 2> /dev/null - -clean: - rm -f $(ALL_OBJECTS) - rm -f $(EGL_DISPLAYS_MODS) - rm -f depend depend.bak - -# Dummy target -install: - @echo -n "" - -##### RULES ##### - -$(common_OBJECTS): %.o: %.c - $(CC) -c $(common_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@ - -$(x11_OBJECTS): %.o: %.c - $(CC) -c $(common_INCLUDES) $(x11_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@ - -$(kms_OBJECTS): %.o: %.c - $(CC) -c $(common_INCLUDES) $(kms_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@ - -sinclude depend diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c deleted file mode 100644 index 2ac6215646..0000000000 --- a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c +++ /dev/null @@ -1,1336 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.8 - * - * Copyright (C) 2009-2010 Chia-I Wu - * - * 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. - */ - -#include -#include -#include "pipe/p_screen.h" -#include "util/u_memory.h" -#include "util/u_rect.h" -#include "egldriver.h" -#include "eglcurrent.h" -#include "eglconfigutil.h" -#include "egllog.h" - -#include "native.h" -#include "egl_g3d.h" -#include "egl_st.h" - -/** - * Validate the draw/read surfaces of the context. - */ -static void -egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx) -{ - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - struct pipe_screen *screen = gdpy->native->screen; - struct egl_g3d_context *gctx = egl_g3d_context(ctx); - const uint st_att_map[NUM_NATIVE_ATTACHMENTS] = { - ST_SURFACE_FRONT_LEFT, - ST_SURFACE_BACK_LEFT, - ST_SURFACE_FRONT_RIGHT, - ST_SURFACE_BACK_RIGHT, - }; - EGLint num_surfaces, s; - - /* validate draw and/or read buffers */ - num_surfaces = (gctx->base.ReadSurface == gctx->base.DrawSurface) ? 1 : 2; - for (s = 0; s < num_surfaces; s++) { - struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; - struct egl_g3d_surface *gsurf; - struct egl_g3d_buffer *gbuf; - EGLint att; - - if (s == 0) { - gsurf = egl_g3d_surface(gctx->base.DrawSurface); - gbuf = &gctx->draw; - } - else { - gsurf = egl_g3d_surface(gctx->base.ReadSurface); - gbuf = &gctx->read; - } - - if (!gctx->force_validate) { - unsigned int seq_num; - - gsurf->native->validate(gsurf->native, gbuf->attachment_mask, - &seq_num, NULL, NULL, NULL); - /* skip validation */ - if (gsurf->sequence_number == seq_num) - continue; - } - - pipe_surface_reference(&gsurf->render_surface, NULL); - memset(textures, 0, sizeof(textures)); - - gsurf->native->validate(gsurf->native, gbuf->attachment_mask, - &gsurf->sequence_number, textures, - &gsurf->base.Width, &gsurf->base.Height); - for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { - struct pipe_texture *pt = textures[att]; - struct pipe_surface *ps; - - if (native_attachment_mask_test(gbuf->attachment_mask, att) && pt) { - ps = screen->get_tex_surface(screen, pt, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_READ | - PIPE_BUFFER_USAGE_GPU_WRITE); - gctx->stapi->st_set_framebuffer_surface(gbuf->st_fb, - st_att_map[att], ps); - - if (gsurf->render_att == att) - pipe_surface_reference(&gsurf->render_surface, ps); - - pipe_surface_reference(&ps, NULL); - pipe_texture_reference(&pt, NULL); - } - } - - gctx->stapi->st_resize_framebuffer(gbuf->st_fb, - gsurf->base.Width, gsurf->base.Height); - } - - gctx->force_validate = EGL_FALSE; - -} - -/** - * Create a st_framebuffer. - */ -static struct st_framebuffer * -create_framebuffer(_EGLContext *ctx, _EGLSurface *surf) -{ - struct egl_g3d_context *gctx = egl_g3d_context(ctx); - struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config); - - return gctx->stapi->st_create_framebuffer(&gconf->native->mode, - gconf->native->color_format, gconf->native->depth_format, - gconf->native->stencil_format, - gsurf->base.Width, gsurf->base.Height, &gsurf->base); -} - -/** - * Update the attachments of draw/read surfaces. - */ -static void -egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx) -{ - struct egl_g3d_context *gctx = egl_g3d_context(ctx); - EGLint s; - - /* route draw and read buffers' attachments */ - for (s = 0; s < 2; s++) { - struct egl_g3d_surface *gsurf; - struct egl_g3d_buffer *gbuf; - - if (s == 0) { - gsurf = egl_g3d_surface(gctx->base.DrawSurface); - gbuf = &gctx->draw; - } - else { - gsurf = egl_g3d_surface(gctx->base.ReadSurface); - gbuf = &gctx->read; - } - - gbuf->attachment_mask = (1 << gsurf->render_att); - - /* FIXME OpenGL defaults to draw the front or back buffer when the - * context is single-buffered or double-buffered respectively. In EGL, - * however, the buffer to be drawn is determined by the surface, instead - * of the context. As a result, rendering to a pixmap surface with a - * double-buffered context does not work as expected. - * - * gctx->stapi->st_draw_front_buffer(gctx->st_ctx, natt == - * NATIVE_ATTACHMENT_FRONT_LEFT); - */ - - /* - * FIXME If the back buffer is asked for here, and the front buffer is - * later needed by the client API (e.g. glDrawBuffer is called to draw - * the front buffer), it will create a new pipe texture and draw there. - * One fix is to ask for both buffers here, but it would be a waste if - * the front buffer is never used. A better fix is to add a callback to - * the pipe screen with context private (just like flush_frontbuffer). - */ - } -} - -/** - * Reallocate the context's framebuffers after draw/read surfaces change. - */ -static EGLBoolean -egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx) -{ - struct egl_g3d_context *gctx = egl_g3d_context(ctx); - struct egl_g3d_surface *gdraw = egl_g3d_surface(gctx->base.DrawSurface); - struct egl_g3d_surface *gread = egl_g3d_surface(gctx->base.ReadSurface); - - /* unreference the old framebuffers */ - if (gctx->draw.st_fb) { - EGLBoolean is_equal = (gctx->draw.st_fb == gctx->read.st_fb); - void *priv; - - priv = gctx->stapi->st_framebuffer_private(gctx->draw.st_fb); - if (!gdraw || priv != (void *) &gdraw->base) { - gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb); - gctx->draw.st_fb = NULL; - gctx->draw.attachment_mask = 0x0; - } - - if (is_equal) { - gctx->read.st_fb = NULL; - gctx->draw.attachment_mask = 0x0; - } - else { - priv = gctx->stapi->st_framebuffer_private(gctx->read.st_fb); - if (!gread || priv != (void *) &gread->base) { - gctx->stapi->st_unreference_framebuffer(gctx->read.st_fb); - gctx->read.st_fb = NULL; - gctx->draw.attachment_mask = 0x0; - } - } - } - - if (!gdraw) - return EGL_TRUE; - - /* create the draw fb */ - if (!gctx->draw.st_fb) { - gctx->draw.st_fb = create_framebuffer(&gctx->base, &gdraw->base); - if (!gctx->draw.st_fb) - return EGL_FALSE; - } - - /* create the read fb */ - if (!gctx->read.st_fb) { - if (gread != gdraw) { - gctx->read.st_fb = create_framebuffer(&gctx->base, &gread->base); - if (!gctx->read.st_fb) { - gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb); - gctx->draw.st_fb = NULL; - return EGL_FALSE; - } - } - else { - /* there is no st_reference_framebuffer... */ - gctx->read.st_fb = gctx->draw.st_fb; - } - } - - egl_g3d_route_context(dpy, &gctx->base); - gctx->force_validate = EGL_TRUE; - - return EGL_TRUE; -} - -/** - * Return the current context of the given API. - */ -static struct egl_g3d_context * -egl_g3d_get_current_context(EGLint api) -{ - _EGLThreadInfo *t = _eglGetCurrentThread(); - EGLint api_index = _eglConvertApiToIndex(api); - return egl_g3d_context(t->CurrentContexts[api_index]); -} - -/** - * Return the state tracker for the given context. - */ -static const struct egl_g3d_st * -egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx) -{ - struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); - const struct egl_g3d_st *stapi; - EGLint idx = -1; - - switch (ctx->ClientAPI) { - case EGL_OPENGL_ES_API: - switch (ctx->ClientVersion) { - case 1: - idx = EGL_G3D_ST_OPENGL_ES; - break; - case 2: - idx = EGL_G3D_ST_OPENGL_ES2; - break; - default: - _eglLog(_EGL_WARNING, "unknown client version %d", - ctx->ClientVersion); - break; - } - break; - case EGL_OPENVG_API: - idx = EGL_G3D_ST_OPENVG; - break; - case EGL_OPENGL_API: - idx = EGL_G3D_ST_OPENGL; - break; - default: - _eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI); - break; - } - - stapi = (idx >= 0) ? gdrv->stapis[idx] : NULL; - return stapi; -} - -/** - * Initialize the state trackers. - */ -static void -egl_g3d_init_st(_EGLDriver *drv) -{ - struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); - EGLint i; - - /* already initialized */ - if (gdrv->api_mask) - return; - - for (i = 0; i < NUM_EGL_G3D_STS; i++) { - gdrv->stapis[i] = egl_g3d_get_st(i); - if (gdrv->stapis[i]) - gdrv->api_mask |= gdrv->stapis[i]->api_bit; - } - - if (gdrv->api_mask) - _eglLog(_EGL_DEBUG, "Driver API mask: 0x%x", gdrv->api_mask); - else - _eglLog(_EGL_WARNING, "No supported client API"); -} - -/** - * Get the probe object of the display. - * - * Note that this function may be called before the display is initialized. - */ -static struct native_probe * -egl_g3d_get_probe(_EGLDriver *drv, _EGLDisplay *dpy) -{ - struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); - struct native_probe *nprobe; - - nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key); - if (!nprobe || nprobe->display != dpy->NativeDisplay) { - if (nprobe) - nprobe->destroy(nprobe); - nprobe = native_create_probe(dpy->NativeDisplay); - _eglSetProbeCache(gdrv->probe_key, (void *) nprobe); - } - - return nprobe; -} - -/** - * Destroy the probe object of the display. The display may be NULL. - * - * Note that this function may be called before the display is initialized. - */ -static void -egl_g3d_destroy_probe(_EGLDriver *drv, _EGLDisplay *dpy) -{ - struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); - struct native_probe *nprobe; - - nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key); - if (nprobe && (!dpy || nprobe->display == dpy->NativeDisplay)) { - nprobe->destroy(nprobe); - _eglSetProbeCache(gdrv->probe_key, NULL); - } -} - -/** - * Return an API mask that consists of the state trackers that supports the - * given mode. - * - * FIXME add st_is_mode_supported()? - */ -static EGLint -get_mode_api_mask(const __GLcontextModes *mode, EGLint api_mask) -{ - EGLint check; - - /* OpenGL ES 1.x and 2.x are checked together */ - check = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT; - if (api_mask & check) { - /* this is required by EGL, not by OpenGL ES */ - if (mode->drawableType & GLX_WINDOW_BIT && !mode->doubleBufferMode) - api_mask &= ~check; - } - - check = EGL_OPENVG_BIT; - if (api_mask & check) { - /* vega st needs the depth/stencil rb */ - if (!mode->depthBits && !mode->stencilBits) - api_mask &= ~check; - } - - return api_mask; -} - -#ifdef EGL_MESA_screen_surface - -static void -egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy) -{ - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - const struct native_connector **native_connectors; - EGLint num_connectors, i; - - native_connectors = - gdpy->native->modeset->get_connectors(gdpy->native, &num_connectors, NULL); - if (!num_connectors) { - if (native_connectors) - free(native_connectors); - return; - } - - for (i = 0; i < num_connectors; i++) { - const struct native_connector *nconn = native_connectors[i]; - struct egl_g3d_screen *gscr; - const struct native_mode **native_modes; - EGLint num_modes, j; - - /* TODO support for hotplug */ - native_modes = - gdpy->native->modeset->get_modes(gdpy->native, nconn, &num_modes); - if (!num_modes) { - if (native_modes) - free(native_modes); - continue; - } - - gscr = CALLOC_STRUCT(egl_g3d_screen); - if (!gscr) { - free(native_modes); - continue; - } - - _eglInitScreen(&gscr->base); - - for (j = 0; j < num_modes; j++) { - const struct native_mode *nmode = native_modes[j]; - _EGLMode *mode; - - mode = _eglAddNewMode(&gscr->base, nmode->width, nmode->height, - nmode->refresh_rate, nmode->desc); - if (!mode) - break; - /* gscr->native_modes and gscr->base.Modes should be consistent */ - assert(mode == &gscr->base.Modes[j]); - } - - gscr->native = nconn; - gscr->native_modes = native_modes; - - _eglAddScreen(dpy, &gscr->base); - } - - free(native_connectors); -} - -#endif /* EGL_MESA_screen_surface */ - -/** - * Add configs to display and return the next config ID. - */ -static EGLint -egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) -{ - struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - const struct native_config **native_configs; - int num_configs, i; - - native_configs = gdpy->native->get_configs(gdpy->native, - &num_configs); - if (!num_configs) { - if (native_configs) - free(native_configs); - return id; - } - - for (i = 0; i < num_configs; i++) { - EGLint api_mask; - struct egl_g3d_config *gconf; - EGLBoolean valid; - - api_mask = get_mode_api_mask(&native_configs[i]->mode, gdrv->api_mask); - if (!api_mask) { - _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x", - native_configs[i]->mode.visualID); - continue; - } - - gconf = CALLOC_STRUCT(egl_g3d_config); - if (!gconf) - continue; - - _eglInitConfig(&gconf->base, id); - valid = _eglConfigFromContextModesRec(&gconf->base, - &native_configs[i]->mode, api_mask, api_mask); - if (valid) { -#ifdef EGL_MESA_screen_surface - /* check if scanout surface bit is set */ - if (native_configs[i]->scanout_bit) { - EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE); - val |= EGL_SCREEN_BIT_MESA; - SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val); - } -#endif - valid = _eglValidateConfig(&gconf->base, EGL_FALSE); - } - if (!valid) { - _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", - native_configs[i]->mode.visualID); - free(gconf); - continue; - } - - gconf->native = native_configs[i]; - _eglAddConfig(dpy, &gconf->base); - id++; - } - - free(native_configs); - return id; -} - -/** - * Flush the front buffer of the context's draw surface. - */ -static void -egl_g3d_flush_frontbuffer(struct pipe_screen *screen, - struct pipe_surface *surf, 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); -} - -/** - * Re-validate the context. - */ -static void -egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private) -{ - struct egl_g3d_context *gctx = egl_g3d_context(context_private); - - /** - * 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.Display, &gctx->base); -} - -static EGLBoolean -egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy) -{ - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - EGLint i; - - _eglReleaseDisplayResources(drv, dpy); - _eglCleanupDisplay(dpy); - - if (dpy->Screens) { - for (i = 0; i < dpy->NumScreens; i++) { - struct egl_g3d_screen *gscr = egl_g3d_screen(dpy->Screens[i]); - free(gscr->native_modes); - free(gscr); - } - free(dpy->Screens); - } - - if (gdpy->native) - gdpy->native->destroy(gdpy->native); - - free(gdpy); - dpy->DriverData = NULL; - - return EGL_TRUE; -} - -static EGLBoolean -egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, - EGLint *major, EGLint *minor) -{ - struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); - struct egl_g3d_display *gdpy; - - /* the probe object is unlikely to be needed again */ - egl_g3d_destroy_probe(drv, dpy); - - gdpy = CALLOC_STRUCT(egl_g3d_display); - if (!gdpy) { - _eglError(EGL_BAD_ALLOC, "eglInitialize"); - goto fail; - } - dpy->DriverData = gdpy; - - gdpy->native = native_create_display(dpy->NativeDisplay); - if (!gdpy->native) { - _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)"); - goto fail; - } - - gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer; - 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 */ - if (gdpy->native->modeset) { - dpy->Extensions.MESA_screen_surface = EGL_TRUE; - egl_g3d_add_screens(drv, dpy); - } -#endif - - *major = 1; - *minor = 4; - - return EGL_TRUE; - -fail: - if (gdpy) - egl_g3d_terminate(drv, dpy); - return EGL_FALSE; -} - -static _EGLContext * -egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - _EGLContext *share, const EGLint *attribs) -{ - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - struct egl_g3d_context *gshare = egl_g3d_context(share); - struct egl_g3d_config *gconf = egl_g3d_config(conf); - struct egl_g3d_context *gctx; - const __GLcontextModes *mode; - - gctx = CALLOC_STRUCT(egl_g3d_context); - if (!gctx) { - _eglError(EGL_BAD_ALLOC, "eglCreateContext"); - return NULL; - } - - if (!_eglInitContext(drv, &gctx->base, conf, attribs)) { - free(gctx); - return NULL; - } - - gctx->stapi = egl_g3d_choose_st(drv, &gctx->base); - if (!gctx->stapi) { - free(gctx); - return NULL; - } - - mode = &gconf->native->mode; - gctx->pipe = - gdpy->native->create_context(gdpy->native, (void *) &gctx->base); - if (!gctx->pipe) { - free(gctx); - return NULL; - } - - gctx->st_ctx = gctx->stapi->st_create_context(gctx->pipe, mode, - (gshare) ? gshare->st_ctx : NULL); - if (!gctx->st_ctx) { - gctx->pipe->destroy(gctx->pipe); - free(gctx); - return NULL; - } - - return &gctx->base; -} - -static EGLBoolean -egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) -{ - struct egl_g3d_context *gctx = egl_g3d_context(ctx); - - if (_eglIsContextBound(&gctx->base)) - return EGL_TRUE; - - egl_g3d_realloc_context(dpy, &gctx->base); - - /* it will destroy pipe context */ - gctx->stapi->st_destroy_context(gctx->st_ctx); - - free(gctx); - - 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); -} - -static _EGLSurface * -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; - - gsurf = CALLOC_STRUCT(egl_g3d_surface); - if (!gsurf) { - _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface"); - return NULL; - } - - if (!_eglInitSurface(drv, &gsurf->base, EGL_WINDOW_BIT, conf, attribs)) { - free(gsurf); - return NULL; - } - - gsurf->native = - gdpy->native->create_window_surface(gdpy->native, win, gconf->native); - if (!gsurf->native) { - free(gsurf); - return NULL; - } - - if (!init_surface_geometry(&gsurf->base)) { - gsurf->native->destroy(gsurf->native); - free(gsurf); - return NULL; - } - - gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER || - !gconf->native->mode.doubleBufferMode) ? - NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT; - - return &gsurf->base; -} - -static _EGLSurface * -egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLConfig *conf, EGLNativePixmapType pix, - 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, "eglCreatePixmapSurface"); - return NULL; - } - - if (!_eglInitSurface(drv, &gsurf->base, 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; - } - - if (!init_surface_geometry(&gsurf->base)) { - gsurf->native->destroy(gsurf->native); - free(gsurf); - return NULL; - } - - gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT; - - return &gsurf->base; -} - -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(drv, &gsurf->base, 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; - } - - 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; - - return &gsurf->base; -} - -static EGLBoolean -egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) -{ - struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - - if (_eglIsSurfaceBound(&gsurf->base)) - return EGL_TRUE; - - pipe_surface_reference(&gsurf->render_surface, NULL); - gsurf->native->destroy(gsurf->native); - free(gsurf); - return EGL_TRUE; -} - -static EGLBoolean -egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx) -{ - struct egl_g3d_context *gctx = egl_g3d_context(ctx); - struct egl_g3d_context *old_gctx; - EGLint api; - EGLBoolean ok = EGL_TRUE; - - /* find the old context */ - api = (gctx) ? gctx->base.ClientAPI : eglQueryAPI(); - old_gctx = egl_g3d_get_current_context(api); - if (old_gctx && !_eglIsContextLinked(&old_gctx->base)) - old_gctx = NULL; - - if (!_eglMakeCurrent(drv, dpy, draw, read, ctx)) - return EGL_FALSE; - - if (old_gctx) { - /* flush old context */ - old_gctx->stapi->st_flush(old_gctx->st_ctx, - PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); - - /* - * The old context is no longer current, and egl_g3d_realloc_context() - * should be called to destroy the framebuffers. However, it is possible - * that it will be made current again with the same draw/read surfaces. - * It might be better to keep it around. - */ - } - - if (gctx) { - struct egl_g3d_surface *gdraw = egl_g3d_surface(draw); - - ok = egl_g3d_realloc_context(dpy, &gctx->base); - if (ok) { - ok = gctx->stapi->st_make_current(gctx->st_ctx, - gctx->draw.st_fb, gctx->read.st_fb); - if (ok) { - egl_g3d_validate_context(dpy, &gctx->base); - if (gdraw->base.Type == EGL_WINDOW_BIT) { - gctx->base.WindowRenderBuffer = - (gdraw->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) ? - EGL_SINGLE_BUFFER : EGL_BACK_BUFFER; - } - } - } - } - else if (old_gctx) { - ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL); - old_gctx->base.WindowRenderBuffer = EGL_NONE; - } - - return ok; -} - -static EGLBoolean -egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) -{ - struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - _EGLContext *ctx = _eglGetCurrentContext(); - struct egl_g3d_context *gctx = NULL; - - /* no-op for pixmap or pbuffer surface */ - if (gsurf->base.Type == EGL_PIXMAP_BIT || - gsurf->base.Type == EGL_PBUFFER_BIT) - return EGL_TRUE; - - /* or when the surface is single-buffered */ - if (gsurf->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) - return EGL_TRUE; - - if (ctx && ctx->DrawSurface == surf) - gctx = egl_g3d_context(ctx); - - /* flush if the surface is current */ - 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; -} - -/** - * Find a config that supports the pixmap. - */ -static _EGLConfig * -find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix) -{ - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - struct egl_g3d_config *gconf; - EGLint i; - - for (i = 0; i < dpy->NumConfigs; i++) { - gconf = egl_g3d_config(dpy->Configs[i]); - if (gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native)) - break; - } - - return (i < dpy->NumConfigs) ? &gconf->base : NULL; -} - -/** - * Get the pipe surface of the given attachment of the native surface. - */ -static struct pipe_surface * -get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf, - enum native_attachment natt) -{ - struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; - struct pipe_surface *psurf; - - textures[natt] = NULL; - nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL); - if (!textures[natt]) - return NULL; - - psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt], - 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE); - pipe_texture_reference(&textures[natt], NULL); - - return psurf; -} - -static EGLBoolean -egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, - NativePixmapType target) -{ - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - _EGLContext *ctx = _eglGetCurrentContext(); - struct egl_g3d_config *gconf; - struct native_surface *nsurf; - struct pipe_screen *screen = gdpy->native->screen; - struct pipe_surface *psurf; - - if (!gsurf->render_surface) - return EGL_TRUE; - - gconf = egl_g3d_config(find_pixmap_config(dpy, target)); - if (!gconf) - return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers"); - - nsurf = gdpy->native->create_pixmap_surface(gdpy->native, - target, gconf->native); - if (!nsurf) - return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers"); - - /* flush if the surface is current */ - if (ctx && ctx->DrawSurface == &gsurf->base) { - struct egl_g3d_context *gctx = egl_g3d_context(ctx); - gctx->stapi->st_flush(gctx->st_ctx, - PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); - } - - psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); - if (psurf) { - struct pipe_context pipe; - - /** - * XXX This is hacky. If we might allow the EGLDisplay to create a pipe - * context of its own and use the blitter context for this. - */ - memset(&pipe, 0, sizeof(pipe)); - pipe.screen = screen; - - util_surface_copy(&pipe, FALSE, psurf, 0, 0, - gsurf->render_surface, 0, 0, psurf->width, psurf->height); - - pipe_surface_reference(&psurf, NULL); - nsurf->flush_frontbuffer(nsurf); - } - - nsurf->destroy(nsurf); - - return EGL_TRUE; -} - -static EGLBoolean -egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) -{ - struct egl_g3d_context *gctx = egl_g3d_context(ctx); - gctx->stapi->st_finish(gctx->st_ctx); - return EGL_TRUE; -} - -static EGLBoolean -egl_g3d_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine) -{ - _EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW); - struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - - if (engine != EGL_CORE_NATIVE_ENGINE) - return _eglError(EGL_BAD_PARAMETER, "eglWaitNative"); - - if (gsurf) - gsurf->native->wait(gsurf->native); - - return EGL_TRUE; -} - -static _EGLProc -egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname) -{ - struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); - _EGLProc proc; - EGLint i; - - /* in case this is called before a display is initialized */ - egl_g3d_init_st(&gdrv->base); - - for (i = 0; i < NUM_EGL_G3D_STS; i++) { - const struct egl_g3d_st *stapi = gdrv->stapis[i]; - if (stapi) { - proc = (_EGLProc) stapi->st_get_proc_address(procname); - if (proc) - return proc; - } - } - - return (_EGLProc) NULL; -} - -static EGLBoolean -egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLSurface *surf, EGLint buffer) -{ - struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - struct egl_g3d_context *gctx; - enum pipe_format target_format; - int target; - - if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT) - return _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); - if (buffer != EGL_BACK_BUFFER) - return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage"); - if (gsurf->base.BoundToTexture) - return _eglError(EGL_BAD_ACCESS, "eglBindTexImage"); - - switch (gsurf->base.TextureFormat) { - case EGL_TEXTURE_RGB: - target_format = PIPE_FORMAT_R8G8B8_UNORM; - break; - case EGL_TEXTURE_RGBA: - target_format = PIPE_FORMAT_A8R8G8B8_UNORM; - break; - default: - return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); - } - - switch (gsurf->base.TextureTarget) { - case EGL_TEXTURE_2D: - target = ST_TEXTURE_2D; - break; - default: - return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); - } - - /* flush properly if the surface is bound */ - if (gsurf->base.Binding) { - gctx = egl_g3d_context(gsurf->base.Binding); - gctx->stapi->st_flush(gctx->st_ctx, - PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); - } - - /* XXX change to EGL_OPENGL_ES_API once OpenGL ES is merged */ - gctx = egl_g3d_get_current_context(EGL_OPENGL_API); - if (gctx) { - if (!gsurf->render_surface) - return EGL_FALSE; - - gctx->stapi->st_bind_texture_surface(gsurf->render_surface, - target, gsurf->base.MipmapLevel, target_format); - gsurf->base.BoundToTexture = EGL_TRUE; - } - - return EGL_TRUE; -} - -static EGLBoolean -egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLSurface *surf, EGLint buffer) -{ - struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - - if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT || - !gsurf->base.BoundToTexture) - return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage"); - if (buffer != EGL_BACK_BUFFER) - return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage"); - - if (gsurf->render_surface) { - _EGLThreadInfo *t = _eglGetCurrentThread(); - /* XXX change to EGL_OPENGL_ES_API once OpenGL ES is merged */ - struct egl_g3d_context *gctx = egl_g3d_context( - t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_API)]); - - /* what if the context the surface binds to is no longer current? */ - if (gctx) - gctx->stapi->st_unbind_texture_surface(gsurf->render_surface, - ST_TEXTURE_2D, gsurf->base.MipmapLevel); - } - - gsurf->base.BoundToTexture = EGL_FALSE; - - return EGL_TRUE; -} - -#ifdef EGL_MESA_screen_surface - -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; - - gsurf = CALLOC_STRUCT(egl_g3d_surface); - if (!gsurf) { - _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface"); - return NULL; - } - - if (!_eglInitSurface(drv, &gsurf->base, - 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; -} - -static EGLBoolean -egl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLScreen *scr, _EGLSurface *surf, - _EGLMode *mode) -{ - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - struct egl_g3d_screen *gscr = egl_g3d_screen(scr); - struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - struct native_surface *nsurf; - const struct native_mode *nmode; - EGLBoolean changed; - - if (gsurf) { - EGLint idx; - - if (!mode) - return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA"); - if (gsurf->base.Type != EGL_SCREEN_BIT_MESA) - return _eglError(EGL_BAD_SURFACE, "eglShowScreenSurfaceMESA"); - if (gsurf->base.Width < mode->Width || gsurf->base.Height < mode->Height) - return _eglError(EGL_BAD_MATCH, - "eglShowSurfaceMESA(surface smaller than mode size)"); - - /* find the index of the mode */ - for (idx = 0; idx < gscr->base.NumModes; idx++) - if (mode == &gscr->base.Modes[idx]) - break; - if (idx >= gscr->base.NumModes) { - return _eglError(EGL_BAD_MODE_MESA, - "eglShowSurfaceMESA(unknown mode)"); - } - - nsurf = gsurf->native; - nmode = gscr->native_modes[idx]; - } - else { - if (mode) - return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA"); - - /* disable the screen */ - nsurf = NULL; - nmode = NULL; - } - - /* TODO surface panning by CRTC choosing */ - changed = gdpy->native->modeset->program(gdpy->native, 0, nsurf, - gscr->base.OriginX, gscr->base.OriginY, &gscr->native, 1, nmode); - if (changed) { - gscr->base.CurrentSurface = &gsurf->base; - gscr->base.CurrentMode = mode; - } - - return changed; -} - -#endif /* EGL_MESA_screen_surface */ - -static EGLint -egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy) -{ - struct native_probe *nprobe; - enum native_probe_result res; - EGLint score; - - nprobe = egl_g3d_get_probe(drv, dpy); - res = native_get_probe_result(nprobe); - - switch (res) { - case NATIVE_PROBE_UNKNOWN: - default: - score = 0; - break; - case NATIVE_PROBE_FALLBACK: - score = 40; - break; - case NATIVE_PROBE_SUPPORTED: - score = 50; - break; - case NATIVE_PROBE_EXACT: - score = 100; - break; - } - - return score; -} - -static void -egl_g3d_unload(_EGLDriver *drv) -{ - struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); - - egl_g3d_destroy_probe(drv, NULL); - free(gdrv); -} - -_EGLDriver * -_eglMain(const char *args) -{ - static char driver_name[64]; - struct egl_g3d_driver *gdrv; - - snprintf(driver_name, sizeof(driver_name), - "Gallium/%s", native_get_name()); - - gdrv = CALLOC_STRUCT(egl_g3d_driver); - if (!gdrv) - return NULL; - - _eglInitDriverFallbacks(&gdrv->base); - - gdrv->base.API.Initialize = egl_g3d_initialize; - gdrv->base.API.Terminate = egl_g3d_terminate; - gdrv->base.API.CreateContext = egl_g3d_create_context; - gdrv->base.API.DestroyContext = egl_g3d_destroy_context; - gdrv->base.API.CreateWindowSurface = egl_g3d_create_window_surface; - gdrv->base.API.CreatePixmapSurface = egl_g3d_create_pixmap_surface; - gdrv->base.API.CreatePbufferSurface = egl_g3d_create_pbuffer_surface; - gdrv->base.API.DestroySurface = egl_g3d_destroy_surface; - gdrv->base.API.MakeCurrent = egl_g3d_make_current; - gdrv->base.API.SwapBuffers = egl_g3d_swap_buffers; - gdrv->base.API.CopyBuffers = egl_g3d_copy_buffers; - gdrv->base.API.WaitClient = egl_g3d_wait_client; - gdrv->base.API.WaitNative = egl_g3d_wait_native; - gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address; - - gdrv->base.API.BindTexImage = egl_g3d_bind_tex_image; - gdrv->base.API.ReleaseTexImage = egl_g3d_release_tex_image; - -#ifdef EGL_MESA_screen_surface - gdrv->base.API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface; - gdrv->base.API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface; -#endif - - gdrv->base.Name = driver_name; - gdrv->base.Probe = egl_g3d_probe; - gdrv->base.Unload = egl_g3d_unload; - - /* the key is " EGL G3D" */ - gdrv->probe_key = 0x0E61063D; - - return &gdrv->base; -} diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h deleted file mode 100644 index 3dae8c4052..0000000000 --- a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.8 - * - * Copyright (C) 2009-2010 Chia-I Wu - * - * 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 _EGL_G3D_H_ -#define _EGL_G3D_H_ - -#include "pipe/p_compiler.h" -#include "pipe/p_screen.h" -#include "pipe/p_context.h" -#include "pipe/p_format.h" -#include "egldriver.h" -#include "egldisplay.h" -#include "eglcontext.h" -#include "eglsurface.h" -#include "eglconfig.h" -#include "eglscreen.h" -#include "eglmode.h" - -#include "native.h" -#include "egl_st.h" - -struct egl_g3d_driver { - _EGLDriver base; - const struct egl_g3d_st *stapis[NUM_EGL_G3D_STS]; - EGLint api_mask; - - EGLint probe_key; -}; - -struct egl_g3d_display { - struct native_display *native; -}; - -struct egl_g3d_buffer { - struct st_framebuffer *st_fb; - uint attachment_mask; -}; - -struct egl_g3d_context { - _EGLContext base; - - const struct egl_g3d_st *stapi; - struct pipe_context *pipe; - - struct st_context *st_ctx; - EGLBoolean force_validate; - struct egl_g3d_buffer draw, read; -}; - -struct egl_g3d_surface { - _EGLSurface base; - struct native_surface *native; - enum native_attachment render_att; - struct pipe_surface *render_surface; - unsigned int sequence_number; -}; - -struct egl_g3d_config { - _EGLConfig base; - const struct native_config *native; -}; - -struct egl_g3d_screen { - _EGLScreen base; - const struct native_connector *native; - const struct native_mode **native_modes; -}; - -static INLINE struct egl_g3d_driver * -egl_g3d_driver(_EGLDriver *drv) -{ - return (struct egl_g3d_driver *) drv; -} - -static INLINE struct egl_g3d_display * -egl_g3d_display(_EGLDisplay *dpy) -{ - /* note that it is not direct casting */ - return (struct egl_g3d_display *) dpy->DriverData; -} - -static INLINE struct egl_g3d_context * -egl_g3d_context(_EGLContext *ctx) -{ - return (struct egl_g3d_context *) ctx; -} - -static INLINE struct egl_g3d_surface * -egl_g3d_surface(_EGLSurface *surf) -{ - return (struct egl_g3d_surface *) surf; -} - -static INLINE struct egl_g3d_config * -egl_g3d_config(_EGLConfig *conf) -{ - return (struct egl_g3d_config *) conf; -} - -static INLINE struct egl_g3d_screen * -egl_g3d_screen(_EGLScreen *scr) -{ - return (struct egl_g3d_screen *) scr; -} - -#endif /* _EGL_G3D_H_ */ diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_st.c b/src/gallium/state_trackers/egl_g3d/common/egl_st.c deleted file mode 100644 index a88ff911cd..0000000000 --- a/src/gallium/state_trackers/egl_g3d/common/egl_st.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.8 - * - * Copyright (C) 2009-2010 Chia-I Wu - * - * 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. - */ - -#include -#include "pipe/p_compiler.h" -#include "util/u_memory.h" -#include "egllog.h" -#include "EGL/egl.h" /* for EGL_api_BIT */ - -#include "egl_st.h" - -#ifndef HAVE_DLADDR -#define HAVE_DLADDR 1 -#endif - -#if HAVE_DLADDR - -static const char * -egl_g3d_st_names[] = { -#define ST_PUBLIC(name, ...) #name, -#include "st_public_tmp.h" - NULL -}; - -static boolean -egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym) -{ - st_proc *procs = (st_proc *) stapi; - void *handle; - Dl_info info; - const char **name; - - if (!dladdr(sym, &info)) - return FALSE; - handle = dlopen(info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE); - if (!handle) - return FALSE; - - for (name = egl_g3d_st_names; *name; name++) { - st_proc proc = (st_proc) dlsym(handle, *name); - if (!proc) { - _eglLog(_EGL_WARNING, "%s is missing in %s", *name, info.dli_fname); - memset(stapi, 0, sizeof(*stapi)); - dlclose(handle); - return FALSE; - } - *procs++ = proc; - } - - dlclose(handle); - return TRUE; -} - -#else /* HAVE_DLADDR */ - -static boolean -egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym) -{ -#define ST_PUBLIC(name, ...) stapi->name = name; -#include "st_public_tmp.h" - return TRUE; -} - -#endif /* HAVE_DLADDR */ - -static boolean -egl_g3d_init_st(struct egl_g3d_st *stapi, const char *api) -{ - void *handle, *sym; - boolean res = FALSE; - - /* already initialized */ - if (stapi->st_notify_swapbuffers != NULL) - return TRUE; - - handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL); - if (!handle) - return FALSE; - - sym = dlsym(handle, api); - if (sym && egl_g3d_fill_st(stapi, sym)) - res = TRUE; - - dlclose(handle); - return res; -} - -static struct { - const char *symbol; - EGLint api_bit; -} egl_g3d_st_info[NUM_EGL_G3D_STS] = { - { "st_api_OpenGL_ES1", EGL_OPENGL_ES_BIT }, - { "st_api_OpenVG", EGL_OPENVG_BIT }, - { "st_api_OpenGL_ES2", EGL_OPENGL_ES2_BIT }, - { "st_api_OpenGL", EGL_OPENGL_BIT }, -}; - -const struct egl_g3d_st * -egl_g3d_get_st(enum egl_g3d_st_api api) -{ - static struct egl_g3d_st all_trackers[NUM_EGL_G3D_STS]; - - if (egl_g3d_init_st(&all_trackers[api], egl_g3d_st_info[api].symbol)) { - all_trackers[api].api_bit = egl_g3d_st_info[api].api_bit; - return &all_trackers[api]; - } - else { - return NULL; - } -} diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_st.h b/src/gallium/state_trackers/egl_g3d/common/egl_st.h deleted file mode 100644 index 8fb464bd3d..0000000000 --- a/src/gallium/state_trackers/egl_g3d/common/egl_st.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.8 - * - * Copyright (C) 2009-2010 Chia-I Wu - * - * 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 _EGL_ST_H_ -#define _EGL_ST_H_ - -#include "GL/gl.h" /* for GL types */ -#include "GL/internal/glcore.h" /* for __GLcontextModes */ - -#include "pipe/p_compiler.h" -#include "pipe/p_format.h" -#include "pipe/p_context.h" - -/* avoid calling st functions directly */ -#if 1 - -#define ST_SURFACE_FRONT_LEFT 0 -#define ST_SURFACE_BACK_LEFT 1 -#define ST_SURFACE_FRONT_RIGHT 2 -#define ST_SURFACE_BACK_RIGHT 3 - -#define ST_TEXTURE_2D 0x2 - -struct st_context; -struct st_framebuffer; -typedef void (*st_proc)(); - -#else -#include "state_tracker/st_public.h" -#endif - -/* remember to update egl_g3d_get_st() when update the enums */ -enum egl_g3d_st_api { - EGL_G3D_ST_OPENGL_ES = 0, - EGL_G3D_ST_OPENVG, - EGL_G3D_ST_OPENGL_ES2, - EGL_G3D_ST_OPENGL, - - NUM_EGL_G3D_STS -}; - -struct egl_g3d_st { -#define ST_PUBLIC(name, ret, ...) ret (*name)(__VA_ARGS__); -#include "st_public_tmp.h" - /* fields must be added here */ - EGLint api_bit; -}; - -const struct egl_g3d_st * -egl_g3d_get_st(enum egl_g3d_st_api api); - -#endif /* _EGL_ST_H_ */ diff --git a/src/gallium/state_trackers/egl_g3d/common/native.h b/src/gallium/state_trackers/egl_g3d/common/native.h deleted file mode 100644 index 72a9cec7ef..0000000000 --- a/src/gallium/state_trackers/egl_g3d/common/native.h +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.8 - * - * Copyright (C) 2009-2010 Chia-I Wu - * - * 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_H_ -#define _NATIVE_H_ - -#include "EGL/egl.h" /* for EGL native types */ -#include "GL/gl.h" /* for GL types needed by __GLcontextModes */ -#include "GL/internal/glcore.h" /* for __GLcontextModes */ - -#include "pipe/p_compiler.h" -#include "pipe/p_screen.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" - -/** - * Only color buffers are listed. The others are allocated privately through, - * for example, st_renderbuffer_alloc_storage(). - */ -enum native_attachment { - NATIVE_ATTACHMENT_FRONT_LEFT, - NATIVE_ATTACHMENT_BACK_LEFT, - NATIVE_ATTACHMENT_FRONT_RIGHT, - NATIVE_ATTACHMENT_BACK_RIGHT, - - NUM_NATIVE_ATTACHMENTS -}; - -/** - * Enumerations for probe results. - */ -enum native_probe_result { - NATIVE_PROBE_UNKNOWN, - NATIVE_PROBE_FALLBACK, - NATIVE_PROBE_SUPPORTED, - NATIVE_PROBE_EXACT, -}; - -/** - * A probe object for display probe. - */ -struct native_probe { - int magic; - EGLNativeDisplayType display; - void *data; - - void (*destroy)(struct native_probe *nprobe); -}; - -struct native_surface { - void (*destroy)(struct native_surface *nsurf); - - /** - * Swap the front and back buffers so that the back buffer is visible. It - * is no-op if the surface is single-buffered. The contents of the back - * buffer after swapping may or may not be preserved. - */ - boolean (*swap_buffers)(struct native_surface *nsurf); - - /** - * Make the front buffer visible. In some native displays, changes to the - * front buffer might not be visible immediately and require manual flush. - */ - boolean (*flush_frontbuffer)(struct native_surface *nsurf); - - /** - * Validate the buffers of the surface. textures, if not NULL, points to an - * array of size NUM_NATIVE_ATTACHMENTS and the returned textures are owned - * by the caller. A sequence number is also returned. The caller can use - * it to check if anything has changed since the last call. Any of the - * pointers may be NULL and it indicates the caller has no interest in those - * values. - * - * If this function is called multiple times with different attachment - * masks, those not listed in the latest call might be destroyed. This - * behavior might change in the future. - */ - boolean (*validate)(struct native_surface *nsurf, uint attachment_mask, - unsigned int *seq_num, struct pipe_texture **textures, - int *width, int *height); - - /** - * Wait until all native commands affecting the surface has been executed. - */ - void (*wait)(struct native_surface *nsurf); -}; - -struct native_config { - /* __GLcontextModes should go away some day */ - __GLcontextModes mode; - enum pipe_format color_format; - enum pipe_format depth_format; - enum pipe_format stencil_format; - - /* treat it as an additional flag to mode.drawableType */ - 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 - * the native display server. - */ -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; - - void (*destroy)(struct native_display *ndpy); - - /** - * Get the supported configs. The configs are owned by the display, but - * the returned array should be free()ed. - * - * The configs will be converted to EGL config by - * _eglConfigFromContextModesRec and validated by _eglValidateConfig. - * Those failing to pass the test will be skipped. - */ - const struct native_config **(*get_configs)(struct native_display *ndpy, - int *num_configs); - - /** - * Test if a pixmap is supported by the given config. Required unless no - * config has GLX_PIXMAP_BIT set. - * - * This function is usually called to find a config that supports a given - * pixmap. Thus, it is usually called with the same pixmap in a row. - */ - boolean (*is_pixmap_supported)(struct native_display *ndpy, - EGLNativePixmapType pix, - const struct native_config *nconf); - - /** - * Create a pipe context. - */ - struct pipe_context *(*create_context)(struct native_display *ndpy, - void *context_private); - - /** - * Create a window surface. Required unless no config has GLX_WINDOW_BIT - * set. - */ - struct native_surface *(*create_window_surface)(struct native_display *ndpy, - EGLNativeWindowType win, - const struct native_config *nconf); - - /** - * Create a pixmap surface. Required unless no config has GLX_PIXMAP_BIT - * set. - */ - struct native_surface *(*create_pixmap_surface)(struct native_display *ndpy, - EGLNativePixmapType pix, - const struct native_config *nconf); - - /** - * Create a pbuffer surface. Required unless no config has GLX_PBUFFER_BIT - * set. - */ - struct native_surface *(*create_pbuffer_surface)(struct native_display *ndpy, - const struct native_config *nconf, - uint width, uint height); - - const struct native_display_modeset *modeset; -}; - -/** - * 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); -}; - -/** - * Test whether an attachment is set in the mask. - */ -static INLINE boolean -native_attachment_mask_test(uint mask, enum native_attachment att) -{ - return !!(mask & (1 << att)); -} - -/** - * Return a probe object for the given display. - * - * Note that the returned object may be cached and used by different native - * display modules. It allows fast probing when multiple modules probe the - * same display. - */ -struct native_probe * -native_create_probe(EGLNativeDisplayType dpy); - -/** - * Probe the probe object. - */ -enum native_probe_result -native_get_probe_result(struct native_probe *nprobe); - -const char * -native_get_name(void); - -struct native_display * -native_create_display(EGLNativeDisplayType dpy); - -#endif /* _NATIVE_H_ */ diff --git a/src/gallium/state_trackers/egl_g3d/common/st_public_tmp.h b/src/gallium/state_trackers/egl_g3d/common/st_public_tmp.h deleted file mode 100644 index 507a0ec402..0000000000 --- a/src/gallium/state_trackers/egl_g3d/common/st_public_tmp.h +++ /dev/null @@ -1,20 +0,0 @@ -ST_PUBLIC(st_create_context, struct st_context *, struct pipe_context *pipe, const __GLcontextModes *visual, struct st_context *share) -ST_PUBLIC(st_destroy_context, void, struct st_context *st) -ST_PUBLIC(st_copy_context_state, void, struct st_context *dst, struct st_context *src, uint mask) -ST_PUBLIC(st_create_framebuffer, struct st_framebuffer *, const __GLcontextModes *visual, enum pipe_format colorFormat, enum pipe_format depthFormat, enum pipe_format stencilFormat, uint width, uint height, void *privateData) -ST_PUBLIC(st_resize_framebuffer, void, struct st_framebuffer *stfb, uint width, uint height) -ST_PUBLIC(st_set_framebuffer_surface, void, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface *surf) -ST_PUBLIC(st_get_framebuffer_dimensions, void, struct st_framebuffer *stfb, uint *width, uint *height) -ST_PUBLIC(st_get_framebuffer_surface, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface **surface) -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_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) -ST_PUBLIC(st_notify_swapbuffers, void, struct st_framebuffer *stfb) -ST_PUBLIC(st_bind_texture_surface, int, struct pipe_surface *ps, int target, int level, enum pipe_format format) -ST_PUBLIC(st_unbind_texture_surface, int, struct pipe_surface *ps, int target, int level) -ST_PUBLIC(st_get_proc_address, st_proc, const char *procname) -#undef ST_PUBLIC diff --git a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c deleted file mode 100644 index d5baf2c2f0..0000000000 --- a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c +++ /dev/null @@ -1,866 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.8 - * - * Copyright (C) 2010 Chia-I Wu - * - * 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. - */ - -#include - -#include "pipe/p_screen.h" -#include "pipe/p_context.h" -#include "util/u_debug.h" -#include "util/u_memory.h" -#include "egllog.h" - -#include "native_kms.h" - -static boolean -kms_surface_validate(struct native_surface *nsurf, uint attachment_mask, - unsigned int *seq_num, struct pipe_texture **textures, - int *width, int *height) -{ - struct kms_surface *ksurf = kms_surface(nsurf); - struct kms_display *kdpy = ksurf->kdpy; - struct pipe_screen *screen = kdpy->base.screen; - struct pipe_texture templ, *ptex; - int att; - - if (attachment_mask) { - memset(&templ, 0, sizeof(templ)); - templ.target = PIPE_TEXTURE_2D; - templ.last_level = 0; - templ.width0 = ksurf->width; - templ.height0 = ksurf->height; - templ.depth0 = 1; - 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; - } - - /* create textures */ - for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { - /* delay the allocation */ - if (!native_attachment_mask_test(attachment_mask, att)) - continue; - - ptex = ksurf->textures[att]; - if (!ptex) { - ptex = screen->texture_create(screen, &templ); - ksurf->textures[att] = ptex; - } - - if (textures) { - textures[att] = NULL; - pipe_texture_reference(&textures[att], ptex); - } - } - - if (seq_num) - *seq_num = ksurf->sequence_number; - if (width) - *width = ksurf->width; - if (height) - *height = ksurf->height; - - return TRUE; -} - -/** - * Add textures as DRM framebuffers. - */ -static boolean -kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back) -{ - struct kms_surface *ksurf = kms_surface(nsurf); - struct kms_display *kdpy = ksurf->kdpy; - int num_framebuffers = (need_back) ? 2 : 1; - int i, err; - - for (i = 0; i < num_framebuffers; i++) { - struct kms_framebuffer *fb; - enum native_attachment natt; - unsigned int handle, stride; - uint block_bits; - - if (i == 0) { - fb = &ksurf->front_fb; - natt = NATIVE_ATTACHMENT_FRONT_LEFT; - } - else { - fb = &ksurf->back_fb; - natt = NATIVE_ATTACHMENT_BACK_LEFT; - } - - if (!fb->texture) { - /* make sure the texture has been allocated */ - kms_surface_validate(&ksurf->base, 1 << natt, NULL, NULL, NULL, NULL); - if (!ksurf->textures[natt]) - return FALSE; - - pipe_texture_reference(&fb->texture, ksurf->textures[natt]); - } - - /* already initialized */ - if (fb->buffer_id) - continue; - - /* 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)) - 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); - if (err) { - fb->buffer_id = 0; - return FALSE; - } - } - - return TRUE; -} - -static boolean -kms_surface_flush_frontbuffer(struct native_surface *nsurf) -{ -#ifdef DRM_MODE_FEATURE_DIRTYFB - struct kms_surface *ksurf = kms_surface(nsurf); - struct kms_display *kdpy = ksurf->kdpy; - - /* pbuffer is private */ - if (ksurf->type == KMS_SURFACE_TYPE_PBUFFER) - return TRUE; - - if (ksurf->front_fb.is_passive) - drmModeDirtyFB(kdpy->fd, ksurf->front_fb.buffer_id, NULL, 0); -#endif - - return TRUE; -} - -static boolean -kms_surface_swap_buffers(struct native_surface *nsurf) -{ - struct kms_surface *ksurf = kms_surface(nsurf); - struct kms_crtc *kcrtc = &ksurf->current_crtc; - struct kms_display *kdpy = ksurf->kdpy; - struct kms_framebuffer tmp_fb; - struct pipe_texture *tmp_texture; - int err; - - /* pbuffer is private */ - if (ksurf->type == KMS_SURFACE_TYPE_PBUFFER) - return TRUE; - - if (!ksurf->back_fb.buffer_id) { - if (!kms_surface_init_framebuffers(&ksurf->base, TRUE)) - return FALSE; - } - - if (ksurf->is_shown && kcrtc->crtc) { - err = drmModeSetCrtc(kdpy->fd, kcrtc->crtc->crtc_id, - ksurf->back_fb.buffer_id, kcrtc->crtc->x, kcrtc->crtc->y, - kcrtc->connectors, kcrtc->num_connectors, &kcrtc->crtc->mode); - if (err) - return FALSE; - } - - /* swap the buffers */ - tmp_fb = ksurf->front_fb; - ksurf->front_fb = ksurf->back_fb; - ksurf->back_fb = tmp_fb; - - tmp_texture = ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT]; - ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT] = - ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT]; - ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT] = tmp_texture; - - /* the front/back textures are swapped */ - ksurf->sequence_number++; - - return TRUE; -} - -static void -kms_surface_wait(struct native_surface *nsurf) -{ - /* no-op */ -} - -static void -kms_surface_destroy(struct native_surface *nsurf) -{ - struct kms_surface *ksurf = kms_surface(nsurf); - int i; - - if (ksurf->current_crtc.crtc) - drmModeFreeCrtc(ksurf->current_crtc.crtc); - - if (ksurf->front_fb.buffer_id) - drmModeRmFB(ksurf->kdpy->fd, ksurf->front_fb.buffer_id); - pipe_texture_reference(&ksurf->front_fb.texture, NULL); - - if (ksurf->back_fb.buffer_id) - drmModeRmFB(ksurf->kdpy->fd, ksurf->back_fb.buffer_id); - pipe_texture_reference(&ksurf->back_fb.texture, NULL); - - for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { - struct pipe_texture *ptex = ksurf->textures[i]; - pipe_texture_reference(&ptex, NULL); - } - - free(ksurf); -} - -static struct kms_surface * -kms_display_create_surface(struct native_display *ndpy, - enum kms_surface_type type, - const struct native_config *nconf, - uint width, uint height) -{ - struct kms_display *kdpy = kms_display(ndpy); - struct kms_config *kconf = kms_config(nconf); - struct kms_surface *ksurf; - - ksurf = CALLOC_STRUCT(kms_surface); - if (!ksurf) - return NULL; - - ksurf->kdpy = kdpy; - ksurf->type = type; - ksurf->color_format = kconf->base.color_format; - ksurf->width = width; - ksurf->height = height; - - ksurf->base.destroy = kms_surface_destroy; - ksurf->base.swap_buffers = kms_surface_swap_buffers; - ksurf->base.flush_frontbuffer = kms_surface_flush_frontbuffer; - ksurf->base.validate = kms_surface_validate; - ksurf->base.wait = kms_surface_wait; - - return ksurf; -} - -/** - * Choose a CRTC that supports all given connectors. - */ -static uint32_t -kms_display_choose_crtc(struct native_display *ndpy, - uint32_t *connectors, int num_connectors) -{ - struct kms_display *kdpy = kms_display(ndpy); - int idx; - - for (idx = 0; idx < kdpy->resources->count_crtcs; idx++) { - boolean found_crtc = TRUE; - int i, j; - - for (i = 0; i < num_connectors; i++) { - drmModeConnectorPtr connector; - int encoder_idx = -1; - - connector = drmModeGetConnector(kdpy->fd, connectors[i]); - if (!connector) { - found_crtc = FALSE; - break; - } - - /* find an encoder the CRTC supports */ - for (j = 0; j < connector->count_encoders; j++) { - drmModeEncoderPtr encoder = - drmModeGetEncoder(kdpy->fd, connector->encoders[j]); - if (encoder->possible_crtcs & (1 << idx)) { - encoder_idx = j; - break; - } - drmModeFreeEncoder(encoder); - } - - drmModeFreeConnector(connector); - if (encoder_idx < 0) { - found_crtc = FALSE; - break; - } - } - - if (found_crtc) - break; - } - - if (idx >= kdpy->resources->count_crtcs) { - _eglLog(_EGL_WARNING, - "failed to find a CRTC that supports the given %d connectors", - num_connectors); - return 0; - } - - return kdpy->resources->crtcs[idx]; -} - -/** - * Remember the original CRTC status and set the CRTC - */ -static boolean -kms_display_set_crtc(struct native_display *ndpy, int crtc_idx, - uint32_t buffer_id, uint32_t x, uint32_t y, - uint32_t *connectors, int num_connectors, - drmModeModeInfoPtr mode) -{ - struct kms_display *kdpy = kms_display(ndpy); - struct kms_crtc *kcrtc = &kdpy->saved_crtcs[crtc_idx]; - uint32_t crtc_id; - int err; - - if (kcrtc->crtc) { - crtc_id = kcrtc->crtc->crtc_id; - } - else { - int count = 0, i; - - /* - * Choose the CRTC once. It could be more dynamic, but let's keep it - * simple for now. - */ - crtc_id = kms_display_choose_crtc(&kdpy->base, - connectors, num_connectors); - - /* save the original CRTC status */ - kcrtc->crtc = drmModeGetCrtc(kdpy->fd, crtc_id); - if (!kcrtc->crtc) - return FALSE; - - for (i = 0; i < kdpy->num_connectors; i++) { - struct kms_connector *kconn = &kdpy->connectors[i]; - drmModeConnectorPtr connector = kconn->connector; - drmModeEncoderPtr encoder; - - encoder = drmModeGetEncoder(kdpy->fd, connector->encoder_id); - if (encoder) { - if (encoder->crtc_id == crtc_id) { - kcrtc->connectors[count++] = connector->connector_id; - if (count >= Elements(kcrtc->connectors)) - break; - } - drmModeFreeEncoder(encoder); - } - } - - kcrtc->num_connectors = count; - } - - err = drmModeSetCrtc(kdpy->fd, crtc_id, buffer_id, x, y, - connectors, num_connectors, mode); - if (err) { - drmModeFreeCrtc(kcrtc->crtc); - kcrtc->crtc = NULL; - kcrtc->num_connectors = 0; - - return FALSE; - } - - return TRUE; -} - -static boolean -kms_display_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) -{ - struct kms_display *kdpy = kms_display(ndpy); - struct kms_surface *ksurf = kms_surface(nsurf); - const struct kms_mode *kmode = kms_mode(nmode); - uint32_t connector_ids[32]; - uint32_t buffer_id; - drmModeModeInfo mode_tmp, *mode; - int i; - - if (num_nconns > Elements(connector_ids)) { - _eglLog(_EGL_WARNING, "too many connectors (%d)", num_nconns); - num_nconns = Elements(connector_ids); - } - - if (ksurf) { - if (!kms_surface_init_framebuffers(&ksurf->base, FALSE)) - return FALSE; - - buffer_id = ksurf->front_fb.buffer_id; - /* the mode argument of drmModeSetCrtc is not constified */ - mode_tmp = kmode->mode; - mode = &mode_tmp; - } - else { - /* disable the CRTC */ - buffer_id = 0; - mode = NULL; - num_nconns = 0; - } - - for (i = 0; i < num_nconns; i++) { - struct kms_connector *kconn = kms_connector(nconns[i]); - connector_ids[i] = kconn->connector->connector_id; - } - - if (!kms_display_set_crtc(&kdpy->base, crtc_idx, buffer_id, x, y, - connector_ids, num_nconns, mode)) { - _eglLog(_EGL_WARNING, "failed to set CRTC %d", crtc_idx); - - return FALSE; - } - - if (kdpy->shown_surfaces[crtc_idx]) - kdpy->shown_surfaces[crtc_idx]->is_shown = FALSE; - kdpy->shown_surfaces[crtc_idx] = ksurf; - - /* remember the settings for buffer swapping */ - if (ksurf) { - uint32_t crtc_id = kdpy->saved_crtcs[crtc_idx].crtc->crtc_id; - struct kms_crtc *kcrtc = &ksurf->current_crtc; - - if (kcrtc->crtc) - drmModeFreeCrtc(kcrtc->crtc); - kcrtc->crtc = drmModeGetCrtc(kdpy->fd, crtc_id); - - assert(num_nconns < Elements(kcrtc->connectors)); - memcpy(kcrtc->connectors, connector_ids, - sizeof(*connector_ids) * num_nconns); - kcrtc->num_connectors = num_nconns; - - ksurf->is_shown = TRUE; - } - - return TRUE; -} - -static const struct native_mode ** -kms_display_get_modes(struct native_display *ndpy, - const struct native_connector *nconn, - int *num_modes) -{ - struct kms_display *kdpy = kms_display(ndpy); - struct kms_connector *kconn = kms_connector(nconn); - const struct native_mode **nmodes_return; - int count, i; - - /* delete old data */ - if (kconn->connector) { - drmModeFreeConnector(kconn->connector); - free(kconn->kms_modes); - - kconn->connector = NULL; - kconn->kms_modes = NULL; - kconn->num_modes = 0; - } - - /* detect again */ - kconn->connector = drmModeGetConnector(kdpy->fd, kconn->connector_id); - if (!kconn->connector) - return NULL; - - count = kconn->connector->count_modes; - kconn->kms_modes = calloc(count, sizeof(*kconn->kms_modes)); - if (!kconn->kms_modes) { - drmModeFreeConnector(kconn->connector); - kconn->connector = NULL; - - return NULL; - } - - for (i = 0; i < count; i++) { - struct kms_mode *kmode = &kconn->kms_modes[i]; - drmModeModeInfoPtr mode = &kconn->connector->modes[i]; - - kmode->mode = *mode; - - 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; - } - - nmodes_return = malloc(count * sizeof(*nmodes_return)); - if (nmodes_return) { - for (i = 0; i < count; i++) - nmodes_return[i] = &kconn->kms_modes[i].base; - if (num_modes) - *num_modes = count; - } - - return nmodes_return; -} - -static const struct native_connector ** -kms_display_get_connectors(struct native_display *ndpy, int *num_connectors, - int *num_crtc) -{ - struct kms_display *kdpy = kms_display(ndpy); - const struct native_connector **connectors; - int i; - - if (!kdpy->connectors) { - kdpy->connectors = - calloc(kdpy->resources->count_connectors, sizeof(*kdpy->connectors)); - if (!kdpy->connectors) - return NULL; - - for (i = 0; i < kdpy->resources->count_connectors; i++) { - struct kms_connector *kconn = &kdpy->connectors[i]; - - kconn->connector_id = kdpy->resources->connectors[i]; - /* kconn->connector is allocated when the modes are asked */ - } - - kdpy->num_connectors = kdpy->resources->count_connectors; - } - - connectors = malloc(kdpy->num_connectors * sizeof(*connectors)); - if (connectors) { - for (i = 0; i < kdpy->num_connectors; i++) - connectors[i] = &kdpy->connectors[i].base; - if (num_connectors) - *num_connectors = kdpy->num_connectors; - } - - if (num_crtc) - *num_crtc = kdpy->resources->count_crtcs; - - return connectors; -} - -static struct native_surface * -kms_display_create_scanout_surface(struct native_display *ndpy, - const struct native_config *nconf, - uint width, uint height) -{ - struct kms_surface *ksurf; - - ksurf = kms_display_create_surface(ndpy, - KMS_SURFACE_TYPE_SCANOUT, nconf, width, height); - return &ksurf->base; -} - -static struct native_surface * -kms_display_create_pbuffer_surface(struct native_display *ndpy, - const struct native_config *nconf, - uint width, uint height) -{ - struct kms_surface *ksurf; - - ksurf = kms_display_create_surface(ndpy, - KMS_SURFACE_TYPE_PBUFFER, nconf, width, height); - return &ksurf->base; -} - -static struct pipe_context * -kms_display_create_context(struct native_display *ndpy, void *context_private) -{ - struct kms_display *kdpy = kms_display(ndpy); - struct pipe_context *pctx; - - pctx = kdpy->api->create_context(kdpy->api, kdpy->base.screen); - if (pctx) - pctx->priv = context_private; - return pctx; -} - -static boolean -kms_display_is_format_supported(struct native_display *ndpy, - enum pipe_format fmt, boolean is_color) -{ - return ndpy->screen->is_format_supported(ndpy->screen, - fmt, PIPE_TEXTURE_2D, - (is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET : - PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); -} - -static const struct native_config ** -kms_display_get_configs(struct native_display *ndpy, int *num_configs) -{ - struct kms_display *kdpy = kms_display(ndpy); - const struct native_config **configs; - - /* first time */ - if (!kdpy->config) { - struct native_config *nconf; - enum pipe_format format; - - kdpy->config = calloc(1, sizeof(*kdpy->config)); - if (!kdpy->config) - return NULL; - - nconf = &kdpy->config->base; - - /* always double-buffered */ - nconf->mode.doubleBufferMode = TRUE; - - format = PIPE_FORMAT_A8R8G8B8_UNORM; - if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) { - format = PIPE_FORMAT_B8G8R8A8_UNORM; - if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) - format = PIPE_FORMAT_NONE; - } - if (format == PIPE_FORMAT_NONE) - return NULL; - - nconf->color_format = format; - nconf->mode.redBits = 8; - nconf->mode.greenBits = 8; - nconf->mode.blueBits = 8; - nconf->mode.alphaBits = 8; - nconf->mode.rgbBits = 32; - - format = PIPE_FORMAT_S8Z24_UNORM; - if (!kms_display_is_format_supported(&kdpy->base, format, FALSE)) { - format = PIPE_FORMAT_Z24S8_UNORM; - if (!kms_display_is_format_supported(&kdpy->base, format, FALSE)) - format = PIPE_FORMAT_NONE; - } - if (format != PIPE_FORMAT_NONE) { - nconf->depth_format = format; - nconf->stencil_format = format; - - nconf->mode.depthBits = 24; - nconf->mode.stencilBits = 8; - nconf->mode.haveDepthBuffer = TRUE; - nconf->mode.haveStencilBuffer = TRUE; - } - - nconf->scanout_bit = TRUE; - nconf->mode.drawableType = GLX_PBUFFER_BIT; - nconf->mode.swapMethod = GLX_SWAP_EXCHANGE_OML; - - nconf->mode.visualID = 0; - nconf->mode.visualType = EGL_NONE; - - nconf->mode.renderType = GLX_RGBA_BIT; - nconf->mode.rgbMode = TRUE; - nconf->mode.xRenderable = FALSE; - } - - configs = malloc(sizeof(*configs)); - if (configs) { - configs[0] = &kdpy->config->base; - if (num_configs) - *num_configs = 1; - } - - return configs; -} - -static void -kms_display_destroy(struct native_display *ndpy) -{ - struct kms_display *kdpy = kms_display(ndpy); - int i; - - if (kdpy->config) - free(kdpy->config); - - if (kdpy->connectors) { - for (i = 0; i < kdpy->num_connectors; i++) { - struct kms_connector *kconn = &kdpy->connectors[i]; - if (kconn->connector) { - drmModeFreeConnector(kconn->connector); - free(kconn->kms_modes); - } - } - free(kdpy->connectors); - } - - if (kdpy->shown_surfaces) - free(kdpy->shown_surfaces); - - if (kdpy->saved_crtcs) { - for (i = 0; i < kdpy->resources->count_crtcs; i++) { - struct kms_crtc *kcrtc = &kdpy->saved_crtcs[i]; - - if (kcrtc->crtc) { - /* restore crtc */ - drmModeSetCrtc(kdpy->fd, kcrtc->crtc->crtc_id, - kcrtc->crtc->buffer_id, kcrtc->crtc->x, kcrtc->crtc->y, - kcrtc->connectors, kcrtc->num_connectors, - &kcrtc->crtc->mode); - - drmModeFreeCrtc(kcrtc->crtc); - } - } - free(kdpy->saved_crtcs); - } - - if (kdpy->resources) - drmModeFreeResources(kdpy->resources); - - if (kdpy->base.screen) - kdpy->base.screen->destroy(kdpy->base.screen); - - if (kdpy->fd >= 0) - drmClose(kdpy->fd); - - if (kdpy->api) - kdpy->api->destroy(kdpy->api); - free(kdpy); -} - -/** - * Initialize KMS and pipe screen. - */ -static boolean -kms_display_init_screen(struct native_display *ndpy) -{ - struct kms_display *kdpy = kms_display(ndpy); - struct drm_create_screen_arg arg; - int fd; - - fd = drmOpen(kdpy->api->name, NULL); - if (fd < 0) { - _eglLog(_EGL_WARNING, "failed to open DRM device"); - return FALSE; - } - -#if 0 - if (drmSetMaster(fd)) { - _eglLog(_EGL_WARNING, "failed to become DRM master"); - return FALSE; - } -#endif - - memset(&arg, 0, sizeof(arg)); - arg.mode = DRM_CREATE_NORMAL; - kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd, &arg); - if (!kdpy->base.screen) { - _eglLog(_EGL_WARNING, "failed to create DRM screen"); - drmClose(fd); - return FALSE; - } - - kdpy->fd = fd; - - return TRUE; -} - -static struct native_display_modeset kms_display_modeset = { - .get_connectors = kms_display_get_connectors, - .get_modes = kms_display_get_modes, - .create_scanout_surface = kms_display_create_scanout_surface, - .program = kms_display_program -}; - -static struct native_display * -kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api) -{ - struct kms_display *kdpy; - - kdpy = CALLOC_STRUCT(kms_display); - if (!kdpy) - return NULL; - - kdpy->api = api; - if (!kdpy->api) { - _eglLog(_EGL_WARNING, "failed to create DRM API"); - free(kdpy); - return NULL; - } - - kdpy->fd = -1; - if (!kms_display_init_screen(&kdpy->base)) { - kms_display_destroy(&kdpy->base); - return NULL; - } - - /* resources are fixed, unlike crtc, connector, or encoder */ - kdpy->resources = drmModeGetResources(kdpy->fd); - if (!kdpy->resources) { - kms_display_destroy(&kdpy->base); - return NULL; - } - - kdpy->saved_crtcs = - calloc(kdpy->resources->count_crtcs, sizeof(*kdpy->saved_crtcs)); - if (!kdpy->saved_crtcs) { - kms_display_destroy(&kdpy->base); - return NULL; - } - - kdpy->shown_surfaces = - calloc(kdpy->resources->count_crtcs, sizeof(*kdpy->shown_surfaces)); - if (!kdpy->shown_surfaces) { - kms_display_destroy(&kdpy->base); - return NULL; - } - - kdpy->base.destroy = kms_display_destroy; - kdpy->base.get_configs = kms_display_get_configs; - kdpy->base.create_context = kms_display_create_context; - kdpy->base.create_pbuffer_surface = kms_display_create_pbuffer_surface; - - kdpy->base.modeset = &kms_display_modeset; - - return &kdpy->base; -} - -struct native_probe * -native_create_probe(EGLNativeDisplayType dpy) -{ - return NULL; -} - -enum native_probe_result -native_get_probe_result(struct native_probe *nprobe) -{ - return NATIVE_PROBE_UNKNOWN; -} - -/* the api is destroyed with the native display */ -static struct drm_api *drm_api; - -const char * -native_get_name(void) -{ - static char kms_name[32]; - - if (!drm_api) - drm_api = drm_api_create(); - - if (drm_api) - snprintf(kms_name, sizeof(kms_name), "KMS/%s", drm_api->name); - else - snprintf(kms_name, sizeof(kms_name), "KMS"); - - return kms_name; -} - -struct native_display * -native_create_display(EGLNativeDisplayType dpy) -{ - struct native_display *ndpy = NULL; - - if (!drm_api) - drm_api = drm_api_create(); - - if (drm_api) - ndpy = kms_create_display(dpy, drm_api); - - return ndpy; -} diff --git a/src/gallium/state_trackers/egl_g3d/kms/native_kms.h b/src/gallium/state_trackers/egl_g3d/kms/native_kms.h deleted file mode 100644 index 095186e3cf..0000000000 --- a/src/gallium/state_trackers/egl_g3d/kms/native_kms.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.8 - * - * Copyright (C) 2010 Chia-I Wu - * - * 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_KMS_H_ -#define _NATIVE_KMS_H_ - -#include -#include - -#include "pipe/p_compiler.h" -#include "util/u_format.h" -#include "pipe/p_state.h" -#include "state_tracker/drm_api.h" - -#include "common/native.h" - -enum kms_surface_type { - KMS_SURFACE_TYPE_PBUFFER, - KMS_SURFACE_TYPE_SCANOUT -}; - -struct kms_config; -struct kms_connector; -struct kms_mode; - -struct kms_crtc { - drmModeCrtcPtr crtc; - uint32_t connectors[32]; - int num_connectors; -}; - -struct kms_display { - struct native_display base; - - int fd; - struct drm_api *api; - drmModeResPtr resources; - struct kms_config *config; - - struct kms_connector *connectors; - int num_connectors; - - struct kms_surface **shown_surfaces; - /* save the original settings of the CRTCs */ - struct kms_crtc *saved_crtcs; -}; - -struct kms_framebuffer { - struct pipe_texture *texture; - boolean is_passive; - - uint32_t buffer_id; -}; - -struct kms_surface { - struct native_surface base; - enum kms_surface_type type; - enum pipe_format color_format; - struct kms_display *kdpy; - int width, height; - - struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; - unsigned int sequence_number; - struct kms_framebuffer front_fb, back_fb; - - boolean is_shown; - struct kms_crtc current_crtc; -}; - -struct kms_config { - struct native_config base; -}; - -struct kms_connector { - struct native_connector base; - - uint32_t connector_id; - drmModeConnectorPtr connector; - struct kms_mode *kms_modes; - int num_modes; -}; - -struct kms_mode { - struct native_mode base; - drmModeModeInfo mode; -}; - -static INLINE struct kms_display * -kms_display(const struct native_display *ndpy) -{ - return (struct kms_display *) ndpy; -} - -static INLINE struct kms_surface * -kms_surface(const struct native_surface *nsurf) -{ - return (struct kms_surface *) nsurf; -} - -static INLINE struct kms_config * -kms_config(const struct native_config *nconf) -{ - return (struct kms_config *) nconf; -} - -static INLINE struct kms_connector * -kms_connector(const struct native_connector *nconn) -{ - return (struct kms_connector *) nconn; -} - -static INLINE struct kms_mode * -kms_mode(const struct native_mode *nmode) -{ - return (struct kms_mode *) nmode; -} - -#endif /* _NATIVE_KMS_H_ */ diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c b/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c deleted file mode 100644 index 07f82d878c..0000000000 --- a/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c +++ /dev/null @@ -1,705 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.8 - * - * Copyright (C) 2009-2010 Chia-I Wu - * - * 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. - */ - -#include "util/u_memory.h" -#include "util/u_math.h" -#include "util/u_format.h" -#include "pipe/p_compiler.h" -#include "pipe/p_screen.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "state_tracker/drm_api.h" -#include "egllog.h" - -#include "native_x11.h" -#include "x11_screen.h" - -enum dri2_surface_type { - DRI2_SURFACE_TYPE_WINDOW, - DRI2_SURFACE_TYPE_PIXMAP, - DRI2_SURFACE_TYPE_PBUFFER -}; - -struct dri2_display { - struct native_display base; - Display *dpy; - boolean own_dpy; - - struct drm_api *api; - struct x11_screen *xscr; - int xscr_number; - - struct dri2_config *configs; - int num_configs; -}; - -struct dri2_surface { - struct native_surface base; - Drawable drawable; - enum dri2_surface_type type; - enum pipe_format color_format; - struct dri2_display *dri2dpy; - - struct pipe_texture *pbuffer_textures[NUM_NATIVE_ATTACHMENTS]; - boolean have_back, have_fake; - int width, height; - unsigned int sequence_number; -}; - -struct dri2_config { - struct native_config base; -}; - -static INLINE struct dri2_display * -dri2_display(const struct native_display *ndpy) -{ - return (struct dri2_display *) ndpy; -} - -static INLINE struct dri2_surface * -dri2_surface(const struct native_surface *nsurf) -{ - return (struct dri2_surface *) nsurf; -} - -static INLINE struct dri2_config * -dri2_config(const struct native_config *nconf) -{ - return (struct dri2_config *) nconf; -} - -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); - - 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); - - 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); - struct dri2_display *dri2dpy = dri2surf->dri2dpy; - unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS]; - struct pipe_texture templ; - 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)) { - unsigned int dri2att; - - switch (att) { - case NATIVE_ATTACHMENT_FRONT_LEFT: - dri2att = DRI2BufferFrontLeft; - break; - case NATIVE_ATTACHMENT_BACK_LEFT: - dri2att = DRI2BufferBackLeft; - break; - case NATIVE_ATTACHMENT_FRONT_RIGHT: - dri2att = DRI2BufferFrontRight; - break; - case NATIVE_ATTACHMENT_BACK_RIGHT: - dri2att = DRI2BufferBackRight; - break; - default: - assert(0); - dri2att = 0; - break; - } - - dri2atts[num_ins] = dri2att; - num_ins++; - } - } - - 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++; - - 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; - - 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; - } - - 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; - } - - 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; - } - } - } - - free(xbufs); - - if (seq_num) - *seq_num = dri2surf->sequence_number; - if (width) - *width = dri2surf->width; - if (height) - *height = dri2surf->height; - - return TRUE; -} - -static void -dri2_surface_wait(struct native_surface *nsurf) -{ - struct dri2_surface *dri2surf = dri2_surface(nsurf); - struct dri2_display *dri2dpy = dri2surf->dri2dpy; - - if (dri2surf->have_fake) { - x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable, - 0, 0, dri2surf->width, dri2surf->height, - DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); - } -} - -static void -dri2_surface_destroy(struct native_surface *nsurf) -{ - struct dri2_surface *dri2surf = dri2_surface(nsurf); - int i; - - for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { - struct pipe_texture *ptex = dri2surf->pbuffer_textures[i]; - pipe_texture_reference(&ptex, NULL); - } - - if (dri2surf->drawable) - x11_drawable_enable_dri2(dri2surf->dri2dpy->xscr, - dri2surf->drawable, FALSE); - free(dri2surf); -} - -static struct dri2_surface * -dri2_display_create_surface(struct native_display *ndpy, - enum dri2_surface_type type, - Drawable drawable, - const struct native_config *nconf) -{ - struct dri2_display *dri2dpy = dri2_display(ndpy); - struct dri2_config *dri2conf = dri2_config(nconf); - struct dri2_surface *dri2surf; - - dri2surf = CALLOC_STRUCT(dri2_surface); - if (!dri2surf) - return NULL; - - if (drawable) - x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE); - - dri2surf->dri2dpy = dri2dpy; - dri2surf->type = type; - dri2surf->drawable = drawable; - dri2surf->color_format = dri2conf->base.color_format; - - dri2surf->base.destroy = dri2_surface_destroy; - dri2surf->base.swap_buffers = dri2_surface_swap_buffers; - dri2surf->base.flush_frontbuffer = dri2_surface_flush_frontbuffer; - dri2surf->base.validate = dri2_surface_validate; - dri2surf->base.wait = dri2_surface_wait; - - return dri2surf; -} - -static struct native_surface * -dri2_display_create_window_surface(struct native_display *ndpy, - EGLNativeWindowType win, - const struct native_config *nconf) -{ - struct dri2_surface *dri2surf; - - dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_WINDOW, - (Drawable) win, nconf); - return (dri2surf) ? &dri2surf->base : NULL; -} - -static struct native_surface * -dri2_display_create_pixmap_surface(struct native_display *ndpy, - EGLNativePixmapType pix, - const struct native_config *nconf) -{ - struct dri2_surface *dri2surf; - - dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PIXMAP, - (Drawable) pix, nconf); - return (dri2surf) ? &dri2surf->base : NULL; -} - -static struct native_surface * -dri2_display_create_pbuffer_surface(struct native_display *ndpy, - const struct native_config *nconf, - uint width, uint height) -{ - struct dri2_surface *dri2surf; - - dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PBUFFER, - (Drawable) None, nconf); - if (dri2surf) { - dri2surf->width = width; - dri2surf->height = height; - } - return (dri2surf) ? &dri2surf->base : NULL; -} - -static struct pipe_context * -dri2_display_create_context(struct native_display *ndpy, void *context_private) -{ - struct dri2_display *dri2dpy = dri2_display(ndpy); - struct pipe_context *pctx; - - pctx = dri2dpy->api->create_context(dri2dpy->api, dri2dpy->base.screen); - if (pctx) - pctx->priv = context_private; - return pctx; -} - -static int -choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32]) -{ - int count = 0; - - switch (mode->rgbBits) { - case 32: - formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM; - formats[count++] = PIPE_FORMAT_B8G8R8A8_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_B8G8R8A8_UNORM; - break; - case 16: - formats[count++] = PIPE_FORMAT_R5G6B5_UNORM; - break; - default: - break; - } - - return count; -} - -static int -choose_depth_stencil_format(const __GLcontextModes *mode, - enum pipe_format formats[32]) -{ - int count = 0; - - switch (mode->depthBits) { - case 32: - formats[count++] = PIPE_FORMAT_Z32_UNORM; - break; - case 24: - if (mode->stencilBits) { - formats[count++] = PIPE_FORMAT_S8Z24_UNORM; - formats[count++] = PIPE_FORMAT_Z24S8_UNORM; - } - else { - formats[count++] = PIPE_FORMAT_X8Z24_UNORM; - formats[count++] = PIPE_FORMAT_Z24X8_UNORM; - } - break; - case 16: - formats[count++] = PIPE_FORMAT_Z16_UNORM; - break; - default: - break; - } - - return count; -} - -static boolean -is_format_supported(struct pipe_screen *screen, - enum pipe_format fmt, boolean is_color) -{ - return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, - (is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET : - PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); -} - -static boolean -dri2_display_convert_config(struct native_display *ndpy, - const __GLcontextModes *mode, - struct native_config *nconf) -{ - enum pipe_format formats[32]; - int num_formats, i; - - if (!(mode->renderType & GLX_RGBA_BIT) || !mode->rgbMode) - return FALSE; - - /* skip single-buffered configs */ - if (!mode->doubleBufferMode) - return FALSE; - - nconf->mode = *mode; - nconf->mode.renderType = GLX_RGBA_BIT; - nconf->mode.rgbMode = TRUE; - /* pbuffer is allocated locally and is always supported */ - nconf->mode.drawableType |= GLX_PBUFFER_BIT; - /* the swap method is always copy */ - nconf->mode.swapMethod = GLX_SWAP_COPY_OML; - - /* fix up */ - nconf->mode.rgbBits = - nconf->mode.redBits + nconf->mode.greenBits + - nconf->mode.blueBits + nconf->mode.alphaBits; - if (!(nconf->mode.drawableType & GLX_WINDOW_BIT)) { - nconf->mode.visualID = 0; - nconf->mode.visualType = GLX_NONE; - } - if (!(nconf->mode.drawableType & GLX_PBUFFER_BIT)) { - nconf->mode.bindToTextureRgb = FALSE; - nconf->mode.bindToTextureRgba = FALSE; - } - - nconf->color_format = PIPE_FORMAT_NONE; - nconf->depth_format = PIPE_FORMAT_NONE; - nconf->stencil_format = PIPE_FORMAT_NONE; - - /* choose color format */ - num_formats = choose_color_format(mode, formats); - for (i = 0; i < num_formats; i++) { - if (is_format_supported(ndpy->screen, formats[i], TRUE)) { - nconf->color_format = formats[i]; - break; - } - } - if (nconf->color_format == PIPE_FORMAT_NONE) - return FALSE; - - /* choose depth/stencil format */ - num_formats = choose_depth_stencil_format(mode, formats); - for (i = 0; i < num_formats; i++) { - if (is_format_supported(ndpy->screen, formats[i], FALSE)) { - nconf->depth_format = formats[i]; - nconf->stencil_format = formats[i]; - break; - } - } - if ((nconf->mode.depthBits && nconf->depth_format == PIPE_FORMAT_NONE) || - (nconf->mode.stencilBits && nconf->stencil_format == PIPE_FORMAT_NONE)) - return FALSE; - - return TRUE; -} - -static const struct native_config ** -dri2_display_get_configs(struct native_display *ndpy, int *num_configs) -{ - struct dri2_display *dri2dpy = dri2_display(ndpy); - const struct native_config **configs; - int i; - - /* first time */ - if (!dri2dpy->configs) { - const __GLcontextModes *modes; - int num_modes, count; - - modes = x11_screen_get_glx_configs(dri2dpy->xscr); - if (!modes) - return NULL; - num_modes = x11_context_modes_count(modes); - - dri2dpy->configs = calloc(num_modes, sizeof(*dri2dpy->configs)); - if (!dri2dpy->configs) - return NULL; - - count = 0; - for (i = 0; i < num_modes; i++) { - struct native_config *nconf = &dri2dpy->configs[count].base; - if (dri2_display_convert_config(&dri2dpy->base, modes, nconf)) - count++; - modes = modes->next; - } - - dri2dpy->num_configs = count; - } - - configs = malloc(dri2dpy->num_configs * sizeof(*configs)); - if (configs) { - for (i = 0; i < dri2dpy->num_configs; i++) - configs[i] = (const struct native_config *) &dri2dpy->configs[i]; - if (num_configs) - *num_configs = dri2dpy->num_configs; - } - - return configs; -} - -static boolean -dri2_display_is_pixmap_supported(struct native_display *ndpy, - EGLNativePixmapType pix, - const struct native_config *nconf) -{ - struct dri2_display *dri2dpy = dri2_display(ndpy); - uint depth, nconf_depth; - - depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix); - nconf_depth = util_format_get_blocksizebits(nconf->color_format); - - /* simple depth match for now */ - return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth)); -} - -static void -dri2_display_destroy(struct native_display *ndpy) -{ - struct dri2_display *dri2dpy = dri2_display(ndpy); - - if (dri2dpy->configs) - free(dri2dpy->configs); - - if (dri2dpy->base.screen) - dri2dpy->base.screen->destroy(dri2dpy->base.screen); - - if (dri2dpy->xscr) - x11_screen_destroy(dri2dpy->xscr); - if (dri2dpy->own_dpy) - XCloseDisplay(dri2dpy->dpy); - if (dri2dpy->api && dri2dpy->api->destroy) - dri2dpy->api->destroy(dri2dpy->api); - free(dri2dpy); -} - -/** - * Initialize DRI2 and pipe screen. - */ -static boolean -dri2_display_init_screen(struct native_display *ndpy) -{ - struct dri2_display *dri2dpy = dri2_display(ndpy); - const char *driver = dri2dpy->api->name; - struct drm_create_screen_arg arg; - int fd; - - if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) || - !x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_GLX)) { - _eglLog(_EGL_WARNING, "GLX/DRI2 is not supported"); - return FALSE; - } - - fd = x11_screen_enable_dri2(dri2dpy->xscr, driver); - if (fd < 0) - return FALSE; - - memset(&arg, 0, sizeof(arg)); - arg.mode = DRM_CREATE_NORMAL; - dri2dpy->base.screen = dri2dpy->api->create_screen(dri2dpy->api, fd, &arg); - if (!dri2dpy->base.screen) { - _eglLog(_EGL_WARNING, "failed to create DRM screen"); - return FALSE; - } - - return TRUE; -} - -struct native_display * -x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api) -{ - struct dri2_display *dri2dpy; - - dri2dpy = CALLOC_STRUCT(dri2_display); - if (!dri2dpy) - return NULL; - - dri2dpy->api = api; - if (!dri2dpy->api) { - _eglLog(_EGL_WARNING, "failed to create DRM API"); - free(dri2dpy); - return NULL; - } - - dri2dpy->dpy = dpy; - if (!dri2dpy->dpy) { - dri2dpy->dpy = XOpenDisplay(NULL); - if (!dri2dpy->dpy) { - dri2_display_destroy(&dri2dpy->base); - return NULL; - } - dri2dpy->own_dpy = TRUE; - } - - dri2dpy->xscr_number = DefaultScreen(dri2dpy->dpy); - dri2dpy->xscr = x11_screen_create(dri2dpy->dpy, dri2dpy->xscr_number); - if (!dri2dpy->xscr) { - dri2_display_destroy(&dri2dpy->base); - return NULL; - } - - if (!dri2_display_init_screen(&dri2dpy->base)) { - dri2_display_destroy(&dri2dpy->base); - return NULL; - } - - dri2dpy->base.destroy = dri2_display_destroy; - dri2dpy->base.get_configs = dri2_display_get_configs; - dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported; - dri2dpy->base.create_context = dri2_display_create_context; - dri2dpy->base.create_window_surface = dri2_display_create_window_surface; - dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface; - dri2dpy->base.create_pbuffer_surface = dri2_display_create_pbuffer_surface; - - return &dri2dpy->base; -} diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_x11.c b/src/gallium/state_trackers/egl_g3d/x11/native_x11.c deleted file mode 100644 index 695ab88010..0000000000 --- a/src/gallium/state_trackers/egl_g3d/x11/native_x11.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.8 - * - * Copyright (C) 2009-2010 Chia-I Wu - * - * 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. - */ - -#include -#include "util/u_debug.h" -#include "util/u_memory.h" -#include "state_tracker/drm_api.h" -#include "egllog.h" - -#include "native_x11.h" -#include "x11_screen.h" - -#define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */ - -static struct drm_api *api; - -static void -x11_probe_destroy(struct native_probe *nprobe) -{ - if (nprobe->data) - free(nprobe->data); - free(nprobe); -} - -struct native_probe * -native_create_probe(EGLNativeDisplayType dpy) -{ - struct native_probe *nprobe; - struct x11_screen *xscr; - int scr; - const char *driver_name = NULL; - Display *xdpy; - - nprobe = CALLOC_STRUCT(native_probe); - if (!nprobe) - return NULL; - - xdpy = dpy; - if (!xdpy) { - xdpy = XOpenDisplay(NULL); - if (!xdpy) { - free(nprobe); - return NULL; - } - } - - scr = DefaultScreen(xdpy); - xscr = x11_screen_create(xdpy, scr); - if (xscr) { - if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) { - driver_name = x11_screen_probe_dri2(xscr); - nprobe->data = strdup(driver_name); - } - - x11_screen_destroy(xscr); - } - - if (xdpy != dpy) - XCloseDisplay(xdpy); - - nprobe->magic = X11_PROBE_MAGIC; - nprobe->display = dpy; - - nprobe->destroy = x11_probe_destroy; - - return nprobe; -} - -enum native_probe_result -native_get_probe_result(struct native_probe *nprobe) -{ - if (!nprobe || nprobe->magic != X11_PROBE_MAGIC) - return NATIVE_PROBE_UNKNOWN; - - if (!api) - api = drm_api_create(); - - /* this is a software driver */ - if (!api) - return NATIVE_PROBE_SUPPORTED; - - /* the display does not support DRI2 or the driver mismatches */ - if (!nprobe->data || strcmp(api->name, (const char *) nprobe->data) != 0) - return NATIVE_PROBE_FALLBACK; - - return NATIVE_PROBE_EXACT; -} - -const char * -native_get_name(void) -{ - static char x11_name[32]; - - if (!api) - api = drm_api_create(); - - if (api) - snprintf(x11_name, sizeof(x11_name), "X11/%s", api->name); - else - snprintf(x11_name, sizeof(x11_name), "X11"); - - return x11_name; -} - -struct native_display * -native_create_display(EGLNativeDisplayType dpy) -{ - struct native_display *ndpy = NULL; - boolean force_sw; - - if (!api) - api = drm_api_create(); - - force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE); - if (api && !force_sw) { - ndpy = x11_create_dri2_display(dpy, api); - } - - if (!ndpy) { - EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING; - - _eglLog(level, "use software fallback"); - ndpy = x11_create_ximage_display(dpy, TRUE); - } - - return ndpy; -} diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_x11.h b/src/gallium/state_trackers/egl_g3d/x11/native_x11.h deleted file mode 100644 index 622ddac5df..0000000000 --- a/src/gallium/state_trackers/egl_g3d/x11/native_x11.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.8 - * - * Copyright (C) 2009-2010 Chia-I Wu - * - * 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_X11_H_ -#define _NATIVE_X11_H_ - -#include "state_tracker/drm_api.h" -#include "common/native.h" - -struct native_display * -x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm); - -struct native_display * -x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api); - -#endif /* _NATIVE_X11_H_ */ diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c b/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c deleted file mode 100644 index dfa8df2223..0000000000 --- a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c +++ /dev/null @@ -1,694 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.8 - * - * Copyright (C) 2009-2010 Chia-I Wu - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "util/u_memory.h" -#include "util/u_math.h" -#include "util/u_format.h" -#include "pipe/p_compiler.h" -#include "pipe/internal/p_winsys_screen.h" -#include "softpipe/sp_winsys.h" -#include "egllog.h" - -#include "sw_winsys.h" -#include "native_x11.h" -#include "x11_screen.h" - -enum ximage_surface_type { - XIMAGE_SURFACE_TYPE_WINDOW, - XIMAGE_SURFACE_TYPE_PIXMAP, - XIMAGE_SURFACE_TYPE_PBUFFER -}; - -struct ximage_display { - struct native_display base; - Display *dpy; - boolean own_dpy; - - 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 ximage_surface { - struct native_surface base; - Drawable drawable; - enum ximage_surface_type type; - enum pipe_format color_format; - XVisualInfo visual; - struct ximage_display *xdpy; - - int width, height; - GC gc; - - struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS]; - unsigned int sequence_number; -}; - -struct ximage_config { - struct native_config base; - const XVisualInfo *visual; -}; - -static INLINE struct ximage_display * -ximage_display(const struct native_display *ndpy) -{ - return (struct ximage_display *) ndpy; -} - -static INLINE struct ximage_surface * -ximage_surface(const struct native_surface *nsurf) -{ - return (struct ximage_surface *) nsurf; -} - -static INLINE struct ximage_config * -ximage_config(const struct native_config *nconf) -{ - return (struct ximage_config *) nconf; -} - -static void -ximage_surface_free_buffer(struct native_surface *nsurf, - enum native_attachment which) -{ - struct ximage_surface *xsurf = ximage_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 -ximage_surface_alloc_buffer(struct native_surface *nsurf, - enum native_attachment which) -{ - struct ximage_surface *xsurf = ximage_surface(nsurf); - struct ximage_buffer *xbuf = &xsurf->buffers[which]; - struct pipe_screen *screen = xsurf->xdpy->base.screen; - struct pipe_texture templ; - - /* free old data */ - if (xbuf->texture) - ximage_surface_free_buffer(&xsurf->base, which); - - memset(&templ, 0, sizeof(templ)); - templ.target = PIPE_TEXTURE_2D; - templ.format = xsurf->color_format; - templ.width0 = xsurf->width; - templ.height0 = xsurf->height; - 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); - } - } - } - else { - xbuf->texture = screen->texture_create(screen, &templ); - } - - /* clean up the buffer if allocation failed */ - if (!xbuf->texture) - ximage_surface_free_buffer(&xsurf->base, which); - - return (xbuf->texture != NULL); -} - -static boolean -ximage_surface_draw_buffer(struct native_surface *nsurf, - enum native_attachment which) -{ - 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; - - if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER) - return TRUE; - - assert(xsurf->drawable && xbuf->ximage && xbuf->texture); - - transfer = screen->get_tex_transfer(screen, xbuf->texture, - 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height); - if (!transfer) - 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); - - /* - * 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); - - return TRUE; -} - -static boolean -ximage_surface_flush_frontbuffer(struct native_surface *nsurf) -{ - return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); -} - -static boolean -ximage_surface_swap_buffers(struct native_surface *nsurf) -{ - struct ximage_surface *xsurf = ximage_surface(nsurf); - struct ximage_buffer *xfront, *xback, xtmp; - - 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; - } -} - -static boolean -ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask, - unsigned int *seq_num, struct pipe_texture **textures, - int *width, int *height) -{ - struct ximage_surface *xsurf = ximage_surface(nsurf); - boolean new_buffers = FALSE; - int att; - - ximage_surface_update_geometry(&xsurf->base); - - 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 (textures) { - 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) - *height = xsurf->height; - - return TRUE; -} - -static void -ximage_surface_wait(struct native_surface *nsurf) -{ - struct ximage_surface *xsurf = ximage_surface(nsurf); - XSync(xsurf->xdpy->dpy, FALSE); - /* TODO XGetImage and update the front texture */ -} - -static void -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]; - 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); -} - -static struct ximage_surface * -ximage_display_create_surface(struct native_display *ndpy, - enum ximage_surface_type type, - Drawable drawable, - const struct native_config *nconf) -{ - 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) - return NULL; - - xsurf->xdpy = xdpy; - xsurf->type = type; - xsurf->color_format = xconf->base.color_format; - xsurf->drawable = drawable; - - 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; - } - } - } - - xsurf->base.destroy = ximage_surface_destroy; - xsurf->base.swap_buffers = ximage_surface_swap_buffers; - xsurf->base.flush_frontbuffer = ximage_surface_flush_frontbuffer; - xsurf->base.validate = ximage_surface_validate; - xsurf->base.wait = ximage_surface_wait; - - return xsurf; -} - -static struct native_surface * -ximage_display_create_window_surface(struct native_display *ndpy, - EGLNativeWindowType win, - const struct native_config *nconf) -{ - struct ximage_surface *xsurf; - - xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_WINDOW, - (Drawable) win, nconf); - return (xsurf) ? &xsurf->base : NULL; -} - -static struct native_surface * -ximage_display_create_pixmap_surface(struct native_display *ndpy, - EGLNativePixmapType pix, - const struct native_config *nconf) -{ - struct ximage_surface *xsurf; - - xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PIXMAP, - (Drawable) pix, nconf); - return (xsurf) ? &xsurf->base : NULL; -} - -static struct native_surface * -ximage_display_create_pbuffer_surface(struct native_display *ndpy, - const struct native_config *nconf, - uint width, uint height) -{ - struct ximage_surface *xsurf; - - xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PBUFFER, - (Drawable) None, nconf); - if (xsurf) { - xsurf->width = width; - xsurf->height = height; - } - return (xsurf) ? &xsurf->base : NULL; -} - -static struct pipe_context * -ximage_display_create_context(struct native_display *ndpy, - void *context_private) -{ - struct pipe_context *pctx = softpipe_create(ndpy->screen); - if (pctx) - pctx->priv = context_private; - return pctx; -} - -static enum pipe_format -choose_format(const XVisualInfo *vinfo) -{ - enum pipe_format fmt; - /* TODO elaborate the formats */ - switch (vinfo->depth) { - case 32: - fmt = PIPE_FORMAT_A8R8G8B8_UNORM; - break; - case 24: - fmt = PIPE_FORMAT_X8R8G8B8_UNORM; - break; - case 16: - fmt = PIPE_FORMAT_R5G6B5_UNORM; - break; - default: - fmt = PIPE_FORMAT_NONE; - break; - } - - return fmt; -} - -static const struct native_config ** -ximage_display_get_configs(struct native_display *ndpy, int *num_configs) -{ - struct ximage_display *xdpy = ximage_display(ndpy); - const struct native_config **configs; - int i; - - /* first time */ - if (!xdpy->configs) { - const XVisualInfo *visuals; - int num_visuals, count, j; - - visuals = x11_screen_get_visuals(xdpy->xscr, &num_visuals); - if (!visuals) - return NULL; - - /* - * Create two configs for each visual. - * One with depth/stencil buffer; one without - */ - xdpy->configs = calloc(num_visuals * 2, sizeof(*xdpy->configs)); - if (!xdpy->configs) - return NULL; - - count = 0; - for (i = 0; i < num_visuals; i++) { - for (j = 0; j < 2; j++) { - struct ximage_config *xconf = &xdpy->configs[count]; - __GLcontextModes *mode = &xconf->base.mode; - - xconf->visual = &visuals[i]; - xconf->base.color_format = choose_format(xconf->visual); - if (xconf->base.color_format == PIPE_FORMAT_NONE) - continue; - - x11_screen_convert_visual(xdpy->xscr, xconf->visual, mode); - /* support double buffer mode */ - mode->doubleBufferMode = TRUE; - - xconf->base.depth_format = PIPE_FORMAT_NONE; - 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; - mode->depthBits = 24; - mode->stencilBits = 8; - mode->haveDepthBuffer = TRUE; - mode->haveStencilBuffer = TRUE; - } - - mode->maxPbufferWidth = 4096; - mode->maxPbufferHeight = 4096; - mode->maxPbufferPixels = 4096 * 4096; - mode->drawableType = - GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; - mode->swapMethod = GLX_SWAP_EXCHANGE_OML; - - if (mode->alphaBits) - mode->bindToTextureRgba = TRUE; - else - mode->bindToTextureRgb = TRUE; - - count++; - } - } - - xdpy->num_configs = count; - } - - configs = malloc(xdpy->num_configs * sizeof(*configs)); - if (configs) { - for (i = 0; i < xdpy->num_configs; i++) - configs[i] = (const struct native_config *) &xdpy->configs[i]; - if (num_configs) - *num_configs = xdpy->num_configs; - } - return configs; -} - -static boolean -ximage_display_is_pixmap_supported(struct native_display *ndpy, - EGLNativePixmapType pix, - const struct native_config *nconf) -{ - struct ximage_display *xdpy = ximage_display(ndpy); - enum pipe_format fmt; - uint depth; - - depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix); - switch (depth) { - case 32: - fmt = PIPE_FORMAT_A8R8G8B8_UNORM; - break; - case 24: - fmt = PIPE_FORMAT_X8R8G8B8_UNORM; - break; - case 16: - fmt = PIPE_FORMAT_R5G6B5_UNORM; - break; - default: - fmt = PIPE_FORMAT_NONE; - break; - } - - return (fmt == nconf->color_format); -} - -static void -ximage_display_destroy(struct native_display *ndpy) -{ - struct ximage_display *xdpy = ximage_display(ndpy); - - if (xdpy->configs) - free(xdpy->configs); - - xdpy->base.screen->destroy(xdpy->base.screen); - free(xdpy->winsys); - - x11_screen_destroy(xdpy->xscr); - if (xdpy->own_dpy) - XCloseDisplay(xdpy->dpy); - free(xdpy); -} - -struct native_display * -x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm) -{ - struct ximage_display *xdpy; - - xdpy = CALLOC_STRUCT(ximage_display); - if (!xdpy) - return NULL; - - xdpy->dpy = dpy; - if (!xdpy->dpy) { - xdpy->dpy = XOpenDisplay(NULL); - if (!xdpy->dpy) { - free(xdpy); - return NULL; - } - xdpy->own_dpy = TRUE; - } - - xdpy->xscr_number = DefaultScreen(xdpy->dpy); - xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number); - if (!xdpy->xscr) { - free(xdpy); - 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.destroy = ximage_display_destroy; - - xdpy->base.get_configs = ximage_display_get_configs; - xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported; - xdpy->base.create_context = ximage_display_create_context; - xdpy->base.create_window_surface = ximage_display_create_window_surface; - xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface; - xdpy->base.create_pbuffer_surface = ximage_display_create_pbuffer_surface; - - return &xdpy->base; -} diff --git a/src/gallium/state_trackers/egl_g3d/x11/sw_winsys.c b/src/gallium/state_trackers/egl_g3d/x11/sw_winsys.c deleted file mode 100644 index 6ee3ede38c..0000000000 --- a/src/gallium/state_trackers/egl_g3d/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 "pipe/internal/p_winsys_screen.h" -#include "pipe/p_state.h" -#include "pipe/p_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_g3d/x11/sw_winsys.h b/src/gallium/state_trackers/egl_g3d/x11/sw_winsys.h deleted file mode 100644 index f96c5a14b0..0000000000 --- a/src/gallium/state_trackers/egl_g3d/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_g3d/x11/x11_screen.c b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c deleted file mode 100644 index 76ce45ee57..0000000000 --- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.8 - * - * Copyright (C) 2009-2010 Chia-I Wu - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include "util/u_memory.h" -#include "util/u_math.h" -#include "util/u_format.h" -#include "xf86drm.h" -#include "egllog.h" - -#include "x11_screen.h" -#include "dri2.h" -#include "glxinit.h" - -struct x11_screen { - Display *dpy; - int number; - - /* - * This is used to fetch GLX visuals/fbconfigs. It uses code from egl_xdri. - * It might be better to rewrite the part in Xlib or XCB. - */ - __GLXdisplayPrivate *glx_dpy; - - int dri_major, dri_minor; - char *dri_driver; - char *dri_device; - int dri_fd; - - XVisualInfo *visuals; - int num_visuals; - - /* cached values for x11_drawable_get_depth */ - Drawable last_drawable; - unsigned int last_depth; -}; - - -/** - * Create a X11 screen. - */ -struct x11_screen * -x11_screen_create(Display *dpy, int screen) -{ - struct x11_screen *xscr; - - if (screen >= ScreenCount(dpy)) - return NULL; - - xscr = CALLOC_STRUCT(x11_screen); - if (xscr) { - xscr->dpy = dpy; - xscr->number = screen; - - xscr->dri_major = -1; - xscr->dri_fd = -1; - } - return xscr; -} - -/** - * Destroy a X11 screen. - */ -void -x11_screen_destroy(struct x11_screen *xscr) -{ - if (xscr->dri_fd >= 0) - close(xscr->dri_fd); - if (xscr->dri_driver) - Xfree(xscr->dri_driver); - if (xscr->dri_device) - Xfree(xscr->dri_device); - - /* xscr->glx_dpy will be destroyed with the X display */ - - if (xscr->visuals) - XFree(xscr->visuals); - free(xscr); -} - -static boolean -x11_screen_init_dri2(struct x11_screen *xscr) -{ - if (xscr->dri_major < 0) { - int eventBase, errorBase; - - if (!DRI2QueryExtension(xscr->dpy, &eventBase, &errorBase) || - !DRI2QueryVersion(xscr->dpy, &xscr->dri_major, &xscr->dri_minor)) - xscr->dri_major = -1; - } - return (xscr->dri_major >= 0); -} - -static boolean -x11_screen_init_glx(struct x11_screen *xscr) -{ - if (!xscr->glx_dpy) - xscr->glx_dpy = __glXInitialize(xscr->dpy); - return (xscr->glx_dpy != NULL); -} - -/** - * Return true if the screen supports the extension. - */ -boolean -x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext) -{ - boolean supported = FALSE; - - switch (ext) { - case X11_SCREEN_EXTENSION_XSHM: - supported = XShmQueryExtension(xscr->dpy); - break; - case X11_SCREEN_EXTENSION_GLX: - supported = x11_screen_init_glx(xscr); - break; - case X11_SCREEN_EXTENSION_DRI2: - supported = x11_screen_init_dri2(xscr); - break; - default: - break; - } - - return supported; -} - -/** - * Return the X visuals. - */ -const XVisualInfo * -x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals) -{ - if (!xscr->visuals) { - XVisualInfo vinfo_template; - vinfo_template.screen = xscr->number; - xscr->visuals = XGetVisualInfo(xscr->dpy, VisualScreenMask, - &vinfo_template, &xscr->num_visuals); - } - - if (num_visuals) - *num_visuals = xscr->num_visuals; - return xscr->visuals; -} - -void -x11_screen_convert_visual(struct x11_screen *xscr, const XVisualInfo *visual, - __GLcontextModes *mode) -{ - int r, g, b, a; - int visual_type; - - r = util_bitcount(visual->red_mask); - g = util_bitcount(visual->green_mask); - b = util_bitcount(visual->blue_mask); - a = visual->depth - (r + g + b); -#if defined(__cplusplus) || defined(c_plusplus) - visual_type = visual->c_class; -#else - visual_type = visual->class; -#endif - - /* convert to GLX visual type */ - switch (visual_type) { - case TrueColor: - visual_type = GLX_TRUE_COLOR; - break; - case DirectColor: - visual_type = GLX_DIRECT_COLOR; - break; - case PseudoColor: - visual_type = GLX_PSEUDO_COLOR; - break; - case StaticColor: - visual_type = GLX_STATIC_COLOR; - break; - case GrayScale: - visual_type = GLX_GRAY_SCALE; - break; - case StaticGray: - visual_type = GLX_STATIC_GRAY; - break; - default: - visual_type = GLX_NONE; - break; - } - - mode->rgbBits = r + g + b + a; - mode->redBits = r; - mode->greenBits = g; - mode->blueBits = b; - mode->alphaBits = a; - mode->visualID = visual->visualid; - mode->visualType = visual_type; - - /* sane defaults */ - mode->renderType = GLX_RGBA_BIT; - mode->rgbMode = TRUE; - mode->visualRating = GLX_SLOW_CONFIG; - mode->xRenderable = TRUE; -} - -/** - * Return the GLX fbconfigs. - */ -const __GLcontextModes * -x11_screen_get_glx_configs(struct x11_screen *xscr) -{ - return (x11_screen_init_glx(xscr)) - ? xscr->glx_dpy->screenConfigs[xscr->number].configs - : NULL; -} - -/** - * Return the GLX visuals. - */ -const __GLcontextModes * -x11_screen_get_glx_visuals(struct x11_screen *xscr) -{ - return (x11_screen_init_glx(xscr)) - ? xscr->glx_dpy->screenConfigs[xscr->number].visuals - : 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) -{ - /* 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; - } - - return xscr->dri_driver; -} - -/** - * Enable DRI2 and returns the file descriptor of the DRM device. The file - * descriptor will be closed automatically when the screen is destoryed. - */ -int -x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver) -{ - 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); - return -1; - } - - fd = open(xscr->dri_device, O_RDWR); - if (fd < 0) { - _eglLog(_EGL_WARNING, "failed to open %s", xscr->dri_device); - return -1; - } - - memset(&magic, 0, sizeof(magic)); - if (drmGetMagic(fd, &magic)) { - _eglLog(_EGL_WARNING, "failed to get magic"); - close(fd); - return -1; - } - - if (!DRI2Authenticate(xscr->dpy, - RootWindow(xscr->dpy, xscr->number), magic)) { - _eglLog(_EGL_WARNING, "failed to authenticate magic"); - close(fd); - return -1; - } - - xscr->dri_fd = fd; - } - - return xscr->dri_fd; -} - -/** - * Create/Destroy the DRI drawable. - */ -void -x11_drawable_enable_dri2(struct x11_screen *xscr, - Drawable drawable, boolean on) -{ - if (on) - DRI2CreateDrawable(xscr->dpy, drawable); - else - DRI2DestroyDrawable(xscr->dpy, drawable); -} - -/** - * Copy between buffers of the DRI2 drawable. - */ -void -x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable, - int x, int y, int width, int height, - int src_buf, int dst_buf) -{ - XRectangle rect; - XserverRegion region; - - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - - region = XFixesCreateRegion(xscr->dpy, &rect, 1); - DRI2CopyRegion(xscr->dpy, drawable, region, dst_buf, src_buf); - XFixesDestroyRegion(xscr->dpy, region); -} - -/** - * Get the buffers of the DRI2 drawable. The returned array should be freed. - */ -struct x11_drawable_buffer * -x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable, - int *width, int *height, unsigned int *attachments, - boolean with_format, int num_ins, int *num_outs) -{ - DRI2Buffer *dri2bufs; - - if (with_format) - dri2bufs = DRI2GetBuffersWithFormat(xscr->dpy, drawable, width, height, - attachments, num_ins, num_outs); - else - dri2bufs = DRI2GetBuffers(xscr->dpy, drawable, width, height, - attachments, num_ins, num_outs); - - return (struct x11_drawable_buffer *) dri2bufs; -} - -/** - * Return the depth of a drawable. - * - * Unlike other drawable functions, the drawable needs not be a DRI2 drawable. - */ -uint -x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable) -{ - unsigned int depth; - - if (drawable != xscr->last_drawable) { - Window root; - int x, y; - unsigned int w, h, border; - Status ok; - - ok = XGetGeometry(xscr->dpy, drawable, &root, - &x, &y, &w, &h, &border, &depth); - if (!ok) - depth = 0; - - xscr->last_drawable = drawable; - xscr->last_depth = depth; - } - else { - depth = xscr->last_depth; - } - - return depth; -} - -/** - * Create a mode list of the given size. - */ -__GLcontextModes * -x11_context_modes_create(unsigned count) -{ - const size_t size = sizeof(__GLcontextModes); - __GLcontextModes *base = NULL; - __GLcontextModes **next; - unsigned i; - - next = &base; - for (i = 0; i < count; i++) { - *next = (__GLcontextModes *) calloc(1, size); - if (*next == NULL) { - x11_context_modes_destroy(base); - base = NULL; - break; - } - next = &((*next)->next); - } - - return base; -} - -/** - * Destroy a mode list. - */ -void -x11_context_modes_destroy(__GLcontextModes *modes) -{ - while (modes != NULL) { - __GLcontextModes *next = modes->next; - free(modes); - modes = next; - } -} - -/** - * Return the number of the modes in the mode list. - */ -unsigned -x11_context_modes_count(const __GLcontextModes *modes) -{ - const __GLcontextModes *mode; - int count = 0; - for (mode = modes; mode; mode = mode->next) - count++; - return count; -} diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h deleted file mode 100644 index 5432858ac3..0000000000 --- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.8 - * - * Copyright (C) 2009-2010 Chia-I Wu - * - * 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 _X11_SCREEN_H_ -#define _X11_SCREEN_H_ - -#include -#include -#include -#include "pipe/p_compiler.h" -#include "common/native.h" - -enum x11_screen_extension { - X11_SCREEN_EXTENSION_XSHM, - X11_SCREEN_EXTENSION_GLX, - X11_SCREEN_EXTENSION_DRI2, -}; - -/* the same as DRI2Buffer */ -struct x11_drawable_buffer { - unsigned int attachment; - unsigned int name; - unsigned int pitch; - unsigned int cpp; - unsigned int flags; -}; - -struct x11_screen; - -struct x11_screen * -x11_screen_create(Display *dpy, int screen); - -void -x11_screen_destroy(struct x11_screen *xscr); - -boolean -x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext); - -const XVisualInfo * -x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals); - -void -x11_screen_convert_visual(struct x11_screen *xscr, const XVisualInfo *visual, - __GLcontextModes *mode); - -const __GLcontextModes * -x11_screen_get_glx_configs(struct x11_screen *xscr); - -const __GLcontextModes * -x11_screen_get_glx_visuals(struct x11_screen *xscr); - -const char * -x11_screen_probe_dri2(struct x11_screen *xscr); - -int -x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver); - -__GLcontextModes * -x11_context_modes_create(unsigned count); - -void -x11_context_modes_destroy(__GLcontextModes *modes); - -unsigned -x11_context_modes_count(const __GLcontextModes *modes); - -void -x11_drawable_enable_dri2(struct x11_screen *xscr, - Drawable drawable, boolean on); - -void -x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable, - int x, int y, int width, int height, - int src_buf, int dst_buf); - -struct x11_drawable_buffer * -x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable, - int *width, int *height, unsigned int *attachments, - boolean with_format, int num_ins, int *num_outs); - -uint -x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable); - -#endif /* _X11_SCREEN_H_ */ diff --git a/src/gallium/winsys/drm/Makefile.egl b/src/gallium/winsys/drm/Makefile.egl new file mode 100644 index 0000000000..1b10f1115c --- /dev/null +++ b/src/gallium/winsys/drm/Makefile.egl @@ -0,0 +1,65 @@ +# src/gallium/winsys/drm/Makefile.egl + +# The driver Makefile should define +# +# EGL_DRIVER_NAME, the name of the driver +# EGL_DRIVER_SOURCES, the sources of the driver +# EGL_DRIVER_LIBS, extra libraries needed by the driver +# EGL_DRIVER_PIPES, the pipe drivers of the driver +# +# before including this file. + +EGL_DRIVER_OBJECTS = $(EGL_DRIVER_SOURCES:.c=.o) + +common_LIBS = -ldrm -lm -ldl + +x11_ST = $(TOP)/src/gallium/state_trackers/egl/libeglx11.a +x11_LIBS = $(common_LIBS) -lX11 -lXext -lXfixes + +kms_ST = $(TOP)/src/gallium/state_trackers/egl/libeglkms.a +kms_LIBS = $(common_LIBS) + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + + +##### TARGETS ##### + +EGL_DISPLAY_DRIVERS = $(foreach dpy, $(EGL_DISPLAYS), egl_$(dpy)_$(EGL_DRIVER_NAME).so) + +LIB_GALLIUM_DIR = $(TOP)/$(LIB_DIR)/gallium +EGL_DISPLAY_LIBS = $(foreach drv, $(EGL_DISPLAY_DRIVERS), $(LIB_GALLIUM_DIR)/$(drv)) + +default: $(EGL_DISPLAY_LIBS) + +$(EGL_DISPLAY_LIBS): $(LIB_GALLIUM_DIR)/%.so: %.so + @mkdir -p $(LIB_GALLIUM_DIR) + $(INSTALL) $^ $(LIB_GALLIUM_DIR) + +define mklib-egl +$(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + $(MKLIB_OPTIONS) $(EGL_DRIVER_OBJECTS) \ + -Wl,--whole-archive $($(1)_ST) -Wl,--no-whole-archive \ + $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $($(1)_LIBS) $(EGL_DRIVER_LIBS) +endef + +egl_x11_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(x11_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile + $(call mklib-egl,x11) + +egl_kms_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(kms_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile + $(call mklib-egl,kms) + +clean: + -rm -f $(EGL_DRIVER_OBJECTS) + -rm -f $(EGL_DISPLAY_DRIVERS) + +install: $(EGL_DISPLAY_LIBS) + @$(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) + @echo "Install $(EGL_DISPLAY_DRIVERS)" + @for lib in "$(EGL_DISPLAY_LIBS)"; do \ + $(MINSTALL) -m 755 "$$lib" $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR); \ + done + +depend: diff --git a/src/gallium/winsys/drm/Makefile.egl_g3d b/src/gallium/winsys/drm/Makefile.egl_g3d deleted file mode 100644 index d8f47396d1..0000000000 --- a/src/gallium/winsys/drm/Makefile.egl_g3d +++ /dev/null @@ -1,65 +0,0 @@ -# src/gallium/winsys/drm/Makefile.egl_g3d - -# The driver Makefile should define -# -# EGL_DRIVER_NAME, the name of the driver -# EGL_DRIVER_SOURCES, the sources of the driver -# EGL_DRIVER_LIBS, extra libraries needed by the driver -# EGL_DRIVER_PIPES, the pipe drivers of the driver -# -# before including this file. - -EGL_DRIVER_OBJECTS = $(EGL_DRIVER_SOURCES:.c=.o) - -common_LIBS = -ldrm -lm -ldl - -x11_ST = $(TOP)/src/gallium/state_trackers/egl_g3d/libeglx11.a -x11_LIBS = $(common_LIBS) -lX11 -lXext -lXfixes - -kms_ST = $(TOP)/src/gallium/state_trackers/egl_g3d/libeglkms.a -kms_LIBS = $(common_LIBS) - -##### RULES ##### - -.c.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ - - -##### TARGETS ##### - -EGL_DISPLAY_DRIVERS = $(foreach dpy, $(EGL_DISPLAYS), egl_$(dpy)_$(EGL_DRIVER_NAME).so) - -LIB_GALLIUM_DIR = $(TOP)/$(LIB_DIR)/gallium -EGL_DISPLAY_LIBS = $(foreach drv, $(EGL_DISPLAY_DRIVERS), $(LIB_GALLIUM_DIR)/$(drv)) - -default: $(EGL_DISPLAY_LIBS) - -$(EGL_DISPLAY_LIBS): $(LIB_GALLIUM_DIR)/%.so: %.so - @mkdir -p $(LIB_GALLIUM_DIR) - $(INSTALL) $^ $(LIB_GALLIUM_DIR) - -define mklib-egl -$(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \ - $(MKLIB_OPTIONS) $(EGL_DRIVER_OBJECTS) \ - -Wl,--whole-archive $($(1)_ST) -Wl,--no-whole-archive \ - $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $($(1)_LIBS) $(EGL_DRIVER_LIBS) -endef - -egl_x11_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(x11_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile - $(call mklib-egl,x11) - -egl_kms_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(kms_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile - $(call mklib-egl,kms) - -clean: - -rm -f $(EGL_DRIVER_OBJECTS) - -rm -f $(EGL_DISPLAY_DRIVERS) - -install: $(EGL_DISPLAY_LIBS) - @$(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) - @echo "Install $(EGL_DISPLAY_DRIVERS)" - @for lib in "$(EGL_DISPLAY_LIBS)"; do \ - $(MINSTALL) -m 755 "$$lib" $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR); \ - done - -depend: diff --git a/src/gallium/winsys/drm/i965/egl/Makefile b/src/gallium/winsys/drm/i965/egl/Makefile new file mode 100644 index 0000000000..1c13258200 --- /dev/null +++ b/src/gallium/winsys/drm/i965/egl/Makefile @@ -0,0 +1,14 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +EGL_DRIVER_NAME = i965 +EGL_DRIVER_SOURCES = dummy.c +EGL_DRIVER_LIBS = -ldrm_intel + +EGL_DRIVER_PIPES = \ + $(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/i965/libi965.a + +include ../../Makefile.egl diff --git a/src/gallium/winsys/drm/i965/egl/dummy.c b/src/gallium/winsys/drm/i965/egl/dummy.c new file mode 100644 index 0000000000..4a1bc28b0b --- /dev/null +++ b/src/gallium/winsys/drm/i965/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/i965/egl_g3d/Makefile b/src/gallium/winsys/drm/i965/egl_g3d/Makefile deleted file mode 100644 index dd2efe2485..0000000000 --- a/src/gallium/winsys/drm/i965/egl_g3d/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -TOP = ../../../../../.. -include $(TOP)/configs/current - -EGL_DRIVER_NAME = i965 -EGL_DRIVER_SOURCES = dummy.c -EGL_DRIVER_LIBS = -ldrm_intel - -EGL_DRIVER_PIPES = \ - $(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/trace/libtrace.a \ - $(TOP)/src/gallium/drivers/i965/libi965.a - -include ../../Makefile.egl_g3d diff --git a/src/gallium/winsys/drm/i965/egl_g3d/dummy.c b/src/gallium/winsys/drm/i965/egl_g3d/dummy.c deleted file mode 100644 index 4a1bc28b0b..0000000000 --- a/src/gallium/winsys/drm/i965/egl_g3d/dummy.c +++ /dev/null @@ -1 +0,0 @@ -/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile new file mode 100644 index 0000000000..60d675ca73 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/Makefile @@ -0,0 +1,14 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +EGL_DRIVER_NAME = i915 +EGL_DRIVER_SOURCES = dummy.c +EGL_DRIVER_LIBS = -ldrm_intel + +EGL_DRIVER_PIPES = \ + $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/i915/libi915.a + +include ../../Makefile.egl diff --git a/src/gallium/winsys/drm/intel/egl/dummy.c b/src/gallium/winsys/drm/intel/egl/dummy.c new file mode 100644 index 0000000000..4a1bc28b0b --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/intel/egl_g3d/Makefile b/src/gallium/winsys/drm/intel/egl_g3d/Makefile deleted file mode 100644 index cdbb680773..0000000000 --- a/src/gallium/winsys/drm/intel/egl_g3d/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -TOP = ../../../../../.. -include $(TOP)/configs/current - -EGL_DRIVER_NAME = i915 -EGL_DRIVER_SOURCES = dummy.c -EGL_DRIVER_LIBS = -ldrm_intel - -EGL_DRIVER_PIPES = \ - $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/trace/libtrace.a \ - $(TOP)/src/gallium/drivers/i915/libi915.a - -include ../../Makefile.egl_g3d diff --git a/src/gallium/winsys/drm/intel/egl_g3d/dummy.c b/src/gallium/winsys/drm/intel/egl_g3d/dummy.c deleted file mode 100644 index 4a1bc28b0b..0000000000 --- a/src/gallium/winsys/drm/intel/egl_g3d/dummy.c +++ /dev/null @@ -1 +0,0 @@ -/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/nouveau/egl/Makefile b/src/gallium/winsys/drm/nouveau/egl/Makefile new file mode 100644 index 0000000000..8e812acc86 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/egl/Makefile @@ -0,0 +1,19 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +EGL_DRIVER_NAME = nouveau +EGL_DRIVER_SOURCES = dummy.c +EGL_DRIVER_LIBS = -ldrm_nouveau + +EGL_DRIVER_PIPES = \ + $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \ + $(TOP)/src/gallium/drivers/nv04/libnv04.a \ + $(TOP)/src/gallium/drivers/nv10/libnv10.a \ + $(TOP)/src/gallium/drivers/nv20/libnv20.a \ + $(TOP)/src/gallium/drivers/nv30/libnv30.a \ + $(TOP)/src/gallium/drivers/nv40/libnv40.a \ + $(TOP)/src/gallium/drivers/nv50/libnv50.a \ + $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a + +include ../../Makefile.egl diff --git a/src/gallium/winsys/drm/nouveau/egl/dummy.c b/src/gallium/winsys/drm/nouveau/egl/dummy.c new file mode 100644 index 0000000000..4a1bc28b0b --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/nouveau/egl_g3d/Makefile b/src/gallium/winsys/drm/nouveau/egl_g3d/Makefile deleted file mode 100644 index 865a5d56a9..0000000000 --- a/src/gallium/winsys/drm/nouveau/egl_g3d/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -TOP = ../../../../../.. -include $(TOP)/configs/current - -EGL_DRIVER_NAME = nouveau -EGL_DRIVER_SOURCES = dummy.c -EGL_DRIVER_LIBS = -ldrm_nouveau - -EGL_DRIVER_PIPES = \ - $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \ - $(TOP)/src/gallium/drivers/nv04/libnv04.a \ - $(TOP)/src/gallium/drivers/nv10/libnv10.a \ - $(TOP)/src/gallium/drivers/nv20/libnv20.a \ - $(TOP)/src/gallium/drivers/nv30/libnv30.a \ - $(TOP)/src/gallium/drivers/nv40/libnv40.a \ - $(TOP)/src/gallium/drivers/nv50/libnv50.a \ - $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a - -include ../../Makefile.egl_g3d diff --git a/src/gallium/winsys/drm/nouveau/egl_g3d/dummy.c b/src/gallium/winsys/drm/nouveau/egl_g3d/dummy.c deleted file mode 100644 index 4a1bc28b0b..0000000000 --- a/src/gallium/winsys/drm/nouveau/egl_g3d/dummy.c +++ /dev/null @@ -1 +0,0 @@ -/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/radeon/egl/Makefile b/src/gallium/winsys/drm/radeon/egl/Makefile new file mode 100644 index 0000000000..cd4f9b20f0 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/egl/Makefile @@ -0,0 +1,14 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +EGL_DRIVER_NAME = radeon +EGL_DRIVER_SOURCES = dummy.c +EGL_DRIVER_LIBS = -ldrm_radeon + +EGL_DRIVER_PIPES = \ + $(TOP)/src/gallium/winsys/drm/radeon/core/libradeonwinsys.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/r300/libr300.a + +include ../../Makefile.egl diff --git a/src/gallium/winsys/drm/radeon/egl/dummy.c b/src/gallium/winsys/drm/radeon/egl/dummy.c new file mode 100644 index 0000000000..4a1bc28b0b --- /dev/null +++ b/src/gallium/winsys/drm/radeon/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/radeon/egl_g3d/Makefile b/src/gallium/winsys/drm/radeon/egl_g3d/Makefile deleted file mode 100644 index e0de68c678..0000000000 --- a/src/gallium/winsys/drm/radeon/egl_g3d/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -TOP = ../../../../../.. -include $(TOP)/configs/current - -EGL_DRIVER_NAME = radeon -EGL_DRIVER_SOURCES = dummy.c -EGL_DRIVER_LIBS = -ldrm_radeon - -EGL_DRIVER_PIPES = \ - $(TOP)/src/gallium/winsys/drm/radeon/core/libradeonwinsys.a \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/trace/libtrace.a \ - $(TOP)/src/gallium/drivers/r300/libr300.a - -include ../../Makefile.egl_g3d diff --git a/src/gallium/winsys/drm/radeon/egl_g3d/dummy.c b/src/gallium/winsys/drm/radeon/egl_g3d/dummy.c deleted file mode 100644 index 4a1bc28b0b..0000000000 --- a/src/gallium/winsys/drm/radeon/egl_g3d/dummy.c +++ /dev/null @@ -1 +0,0 @@ -/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/swrast/egl/Makefile b/src/gallium/winsys/drm/swrast/egl/Makefile new file mode 100644 index 0000000000..26fe2d2805 --- /dev/null +++ b/src/gallium/winsys/drm/swrast/egl/Makefile @@ -0,0 +1,12 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +EGL_DRIVER_NAME = swrast +EGL_DRIVER_SOURCES = dummy.c +EGL_DRIVER_LIBS = + +EGL_DRIVER_PIPES = \ + $(TOP)/src/gallium/winsys/drm/swrast/core/libswrastdrm.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a + +include ../../Makefile.egl diff --git a/src/gallium/winsys/drm/swrast/egl/dummy.c b/src/gallium/winsys/drm/swrast/egl/dummy.c new file mode 100644 index 0000000000..4a1bc28b0b --- /dev/null +++ b/src/gallium/winsys/drm/swrast/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/swrast/egl_g3d/Makefile b/src/gallium/winsys/drm/swrast/egl_g3d/Makefile deleted file mode 100644 index f0d051ea0e..0000000000 --- a/src/gallium/winsys/drm/swrast/egl_g3d/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -TOP = ../../../../../.. -include $(TOP)/configs/current - -EGL_DRIVER_NAME = swrast -EGL_DRIVER_SOURCES = dummy.c -EGL_DRIVER_LIBS = - -EGL_DRIVER_PIPES = \ - $(TOP)/src/gallium/winsys/drm/swrast/core/libswrastdrm.a \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a - -include ../../Makefile.egl_g3d diff --git a/src/gallium/winsys/drm/swrast/egl_g3d/dummy.c b/src/gallium/winsys/drm/swrast/egl_g3d/dummy.c deleted file mode 100644 index 4a1bc28b0b..0000000000 --- a/src/gallium/winsys/drm/swrast/egl_g3d/dummy.c +++ /dev/null @@ -1 +0,0 @@ -/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/vmware/egl/Makefile b/src/gallium/winsys/drm/vmware/egl/Makefile new file mode 100644 index 0000000000..a3e73131c3 --- /dev/null +++ b/src/gallium/winsys/drm/vmware/egl/Makefile @@ -0,0 +1,14 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +EGL_DRIVER_NAME = vmwgfx +EGL_DRIVER_SOURCES = dummy.c +EGL_DRIVER_LIBS = + +EGL_DRIVER_PIPES = \ + $(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/svga/libsvga.a + +include ../../Makefile.egl diff --git a/src/gallium/winsys/drm/vmware/egl/dummy.c b/src/gallium/winsys/drm/vmware/egl/dummy.c new file mode 100644 index 0000000000..4a1bc28b0b --- /dev/null +++ b/src/gallium/winsys/drm/vmware/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/vmware/egl_g3d/Makefile b/src/gallium/winsys/drm/vmware/egl_g3d/Makefile deleted file mode 100644 index 3cf79924e0..0000000000 --- a/src/gallium/winsys/drm/vmware/egl_g3d/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -TOP = ../../../../../.. -include $(TOP)/configs/current - -EGL_DRIVER_NAME = vmwgfx -EGL_DRIVER_SOURCES = dummy.c -EGL_DRIVER_LIBS = - -EGL_DRIVER_PIPES = \ - $(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/trace/libtrace.a \ - $(TOP)/src/gallium/drivers/svga/libsvga.a - -include ../../Makefile.egl_g3d diff --git a/src/gallium/winsys/drm/vmware/egl_g3d/dummy.c b/src/gallium/winsys/drm/vmware/egl_g3d/dummy.c deleted file mode 100644 index 4a1bc28b0b..0000000000 --- a/src/gallium/winsys/drm/vmware/egl_g3d/dummy.c +++ /dev/null @@ -1 +0,0 @@ -/* mklib expects at least one object file */ -- cgit v1.2.3 From 60cd2449f8f2b698f0adacd4a401db13c5fa46f9 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sat, 23 Jan 2010 20:08:02 +0800 Subject: st/es: Pass -linker and -ldflags to mklib. --- src/gallium/state_trackers/es/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/es/Makefile b/src/gallium/state_trackers/es/Makefile index 095ffbb938..b036551271 100644 --- a/src/gallium/state_trackers/es/Makefile +++ b/src/gallium/state_trackers/es/Makefile @@ -49,7 +49,7 @@ default: $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAM # Make the shared libs $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME): $(ES1_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXILIARIES) - $(MKLIB) -o $(GLES_1_LIB) \ + $(MKLIB) -o $(GLES_1_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major $(GLES_1_VERSION_MAJOR) \ -minor $(GLES_1_VERSION_MINOR) \ -patch $(GLES_1_VERSION_PATCH) \ @@ -59,7 +59,7 @@ $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME): $(ES1_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXIL $(GALLIUM_AUXILIARIES) $(SYS_LIBS) $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME): $(ES2_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXILIARIES) - $(MKLIB) -o $(GLES_2_LIB) \ + $(MKLIB) -o $(GLES_2_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major $(GLES_2_VERSION_MAJOR) \ -minor $(GLES_2_VERSION_MINOR) \ -patch $(GLES_2_VERSION_PATCH) \ -- cgit v1.2.3 From 6c4431c092b06d31eee5ac7ed656ab6d6423c3ef Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sat, 23 Jan 2010 20:09:20 +0800 Subject: st/vega: Clean up Makefile. --- src/gallium/state_trackers/vega/Makefile | 80 +++++++++++--------------------- 1 file changed, 26 insertions(+), 54 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile index fc97bf51f8..037d8dc911 100644 --- a/src/gallium/state_trackers/vega/Makefile +++ b/src/gallium/state_trackers/vega/Makefile @@ -1,8 +1,14 @@ -# src/mesa/Makefile +# src/gallium/state_trackers/vega/Makefile TOP = ../../../.. include $(TOP)/configs/current -GALLIUM = $(TOP) + +VG_LIB = OpenVG +VG_LIB_NAME = lib$(VG_LIB).so + +VG_MAJOR = 1 +VG_MINOR = 0 +VG_TINY = 0 ### Lists of source files, included by Makefiles @@ -34,88 +40,54 @@ VG_SOURCES = \ shader.c \ shaders_cache.c +VG_OBJECTS = $(VG_SOURCES:.c=.o) -### All the core C sources - -ALL_SOURCES = \ - $(VG_SOURCES) - - -### Object files -VG_OBJECTS = \ - $(VG_SOURCES:.c=.o) +VG_LIBS = $(GALLIUM_AUXILIARIES) -lm ### Include directories INCLUDE_DIRS = \ -I$(TOP)/include \ - -I$(GALLIUM)/include \ - -I$(GALLIUM)/src/gallium/include \ - -I$(GALLIUM)/src/gallium/auxiliary + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary -VG_LIB = OpenVG -VG_LIB_NAME = lib$(VG_LIB).so - -VG_MAJOR = 1 -VG_MINOR = 0 -VG_TINY = 0 - -GALLIUM_LIBS = \ - $(GALLIUM)/src/gallium/auxiliary/libgallium.a - -.SUFFIXES : .cpp .c.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@ -.cpp.o: - $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@ - -.S.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ - - -default: depend subdirs $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME) +default: depend $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME) # Make the OpenVG library -$(TOP)/$(LIB_DIR)/$(VG_LIB_NAME): $(VG_OBJECTS) $(GALLIUM_LIBS) - $(TOP)/bin/mklib -o $(VG_LIB) \ +$(TOP)/$(LIB_DIR)/$(VG_LIB_NAME): $(VG_OBJECTS) $(VG_LIBS) + $(MKLIB) -o $(VG_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major $(VG_MAJOR) \ -minor $(VG_MINOR) \ -patch $(VG_TINY) \ -install $(TOP)/$(LIB_DIR) \ - $(VG_OBJECTS) $(GALLIUM_LIBS) \ - -Wl,--whole-archive $(LIBS) -Wl,--no-whole-archive $(SYS_LIBS) + $(VG_OBJECTS) $(VG_LIBS) ###################################################################### # Generic stuff -depend: $(ALL_SOURCES) +depend: $(VG_SOURCES) @ echo "running $(MKDEP)" @ rm -f depend # workaround oops on gutsy?!? @ touch depend - @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \ + @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(VG_SOURCES) \ > /dev/null 2>/dev/null - -subdirs: - install: default - $(INSTALL) -d $(INSTALL_DIR)/include/VG - $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) - $(INSTALL) -m 644 $(TOP)/include/VG/*.h $(INSTALL_DIR)/include/VG - @if [ -e $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME) ]; then \ - $(INSTALL) $(TOP)/$(LIB_DIR)/libOpenVG* $(INSTALL_DIR)/$(LIB_DIR); \ - fi + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/VG + $(INSTALL) -m 644 $(TOP)/include/VG/*.h $(DESTDIR)$(INSTALL_DIR)/include/VG + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/libOpenVG* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) # Emacs tags tags: etags `find . -name \*.[ch]` $(TOP)/include/VG/*.h clean: - -rm -f *.o - -rm -f */*.o - -rm -f */*/*.o - -rm -f depend depend.bak + rm -f $(VG_OBJECTS) + rm -f depend depend.bak -include depend +sinclude depend -- cgit v1.2.3 From ecb3b3102a3022e31cf9d75ae099eddbe298517f Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sun, 24 Jan 2010 20:32:34 +0800 Subject: egl: Make surfaces and contexts resources. Turn _EGLSurface and _EGLContext into _EGLResource so that they can be managed uniformly. --- src/egl/main/eglapi.c | 6 +-- src/egl/main/eglcontext.c | 69 ------------------------ src/egl/main/eglcontext.h | 56 ++++++++++---------- src/egl/main/eglcurrent.c | 2 +- src/egl/main/egldisplay.c | 34 ++++++------ src/egl/main/egldisplay.h | 5 +- src/egl/main/eglsurface.c | 70 ------------------------- src/egl/main/eglsurface.h | 56 ++++++++++---------- src/gallium/state_trackers/egl/common/egl_g3d.c | 2 +- 9 files changed, 79 insertions(+), 221 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 6e8f444d7f..26ed45c6fe 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -526,7 +526,7 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval) _EGLSurface *surf; _EGL_DECLARE_DD(dpy); - if (!ctx || !_eglIsContextLinked(ctx) || ctx->Display != disp) + if (!ctx || !_eglIsContextLinked(ctx) || ctx->Resource.Display != disp) return _eglError(EGL_BAD_CONTEXT, __FUNCTION__); surf = ctx->DrawSurface; @@ -573,7 +573,7 @@ eglWaitClient(void) return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__); /* a valid current context implies an initialized current display */ - disp = ctx->Display; + disp = ctx->Resource.Display; drv = disp->Driver; assert(drv); @@ -617,7 +617,7 @@ eglWaitNative(EGLint engine) return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__); /* a valid current context implies an initialized current display */ - disp = ctx->Display; + disp = ctx->Resource.Display; drv = disp->Driver; assert(drv); diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index 41960f5426..ee4b1b59f5 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -251,72 +251,3 @@ _eglCopyContextMESA(_EGLDriver *drv, EGLDisplay dpy, EGLContext source, */ return EGL_FALSE; } - - -/** - * Link a context to a display and return the handle of the link. - * The handle can be passed to client directly. - */ -EGLContext -_eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy) -{ - ctx->Display = dpy; - ctx->Next = dpy->ContextList; - dpy->ContextList = ctx; - return (EGLContext) ctx; -} - - -/** - * Unlink a linked context from its display. - * Accessing an unlinked context should generate EGL_BAD_CONTEXT error. - */ -void -_eglUnlinkContext(_EGLContext *ctx) -{ - _EGLContext *prev; - - prev = ctx->Display->ContextList; - if (prev != ctx) { - while (prev) { - if (prev->Next == ctx) - break; - prev = prev->Next; - } - assert(prev); - prev->Next = ctx->Next; - } - else { - ctx->Display->ContextList = ctx->Next; - } - - ctx->Next = NULL; - ctx->Display = NULL; -} - - -#ifndef _EGL_SKIP_HANDLE_CHECK - - -/** - * Return EGL_TRUE if the given handle is a valid handle to a context. - */ -EGLBoolean -_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy) -{ - _EGLContext *cur = NULL; - - if (dpy) - cur = dpy->ContextList; - while (cur) { - if (cur == (_EGLContext *) ctx) { - assert(cur->Display == dpy); - break; - } - cur = cur->Next; - } - return (cur != NULL); -} - - -#endif /* !_EGL_SKIP_HANDLE_CHECK */ diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h index 0dcec92488..b81dc1ed82 100644 --- a/src/egl/main/eglcontext.h +++ b/src/egl/main/eglcontext.h @@ -4,6 +4,7 @@ #include "egltypedefs.h" +#include "egldisplay.h" /** @@ -11,9 +12,8 @@ */ struct _egl_context { - /* Managed by EGLDisplay for linking */ - _EGLDisplay *Display; - _EGLContext *Next; + /* A context is a display resource */ + _EGLResource Resource; /* The bound status of the context */ _EGLThreadInfo *Binding; @@ -65,33 +65,27 @@ _eglIsContextBound(_EGLContext *ctx) } -extern EGLContext -_eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy); - - -extern void -_eglUnlinkContext(_EGLContext *ctx); - - -#ifndef _EGL_SKIP_HANDLE_CHECK - - -extern EGLBoolean -_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy); - - -#else /* !_EGL_SKIP_HANDLE_CHECK */ - - -static INLINE EGLBoolean -_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy) +/** + * Link a context to a display and return the handle of the link. + * The handle can be passed to client directly. + */ +static INLINE EGLContext +_eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy) { - _EGLContext *c = (_EGLContext *) ctx; - return (dpy && c && c->Display == dpy); + _eglLinkResource(&ctx->Resource, _EGL_RESOURCE_CONTEXT, dpy); + return (EGLContext) ctx; } -#endif /* _EGL_SKIP_HANDLE_CHECK */ +/** + * Unlink a linked context from its display. + * Accessing an unlinked context should generate EGL_BAD_CONTEXT error. + */ +static INLINE void +_eglUnlinkContext(_EGLContext *ctx) +{ + _eglUnlinkResource(&ctx->Resource, _EGL_RESOURCE_CONTEXT); +} /** @@ -101,8 +95,9 @@ _eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy) static INLINE _EGLContext * _eglLookupContext(EGLContext context, _EGLDisplay *dpy) { + _EGLResource *res = (_EGLResource *) context; _EGLContext *ctx = (_EGLContext *) context; - if (!_eglCheckContextHandle(context, dpy)) + if (!res || !dpy || !_eglCheckResource(res, _EGL_RESOURCE_CONTEXT, dpy)) ctx = NULL; return ctx; } @@ -114,7 +109,9 @@ _eglLookupContext(EGLContext context, _EGLDisplay *dpy) static INLINE EGLContext _eglGetContextHandle(_EGLContext *ctx) { - return (EGLContext) ((ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT); + _EGLResource *res = (_EGLResource *) ctx; + return (res && _eglIsResourceLinked(res)) ? + (EGLContext) ctx : EGL_NO_CONTEXT; } @@ -124,7 +121,8 @@ _eglGetContextHandle(_EGLContext *ctx) static INLINE EGLBoolean _eglIsContextLinked(_EGLContext *ctx) { - return (EGLBoolean) (_eglGetContextHandle(ctx) != EGL_NO_CONTEXT); + _EGLResource *res = (_EGLResource *) ctx; + return (res && _eglIsResourceLinked(res)); } diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c index df506151b5..f91631240f 100644 --- a/src/egl/main/eglcurrent.c +++ b/src/egl/main/eglcurrent.c @@ -246,7 +246,7 @@ _eglGetCurrentDisplay(void) _EGLThreadInfo *t = _eglGetCurrentThread(); _EGLContext *ctx = t->CurrentContexts[t->CurrentAPIIndex]; if (ctx) - return ctx->Display; + return ctx->Resource.Display; else return NULL; } diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index ef144f7f07..c978adb47f 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -26,12 +26,18 @@ _eglFiniDisplay(void) /* atexit function is called with global mutex locked */ dpyList = _eglGlobal.DisplayList; while (dpyList) { + EGLint i; + /* pop list head */ dpy = dpyList; dpyList = dpyList->Next; - if (dpy->ContextList || dpy->SurfaceList) - _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy); + for (i = 0; i < _EGL_NUM_RESOURCES; i++) { + if (dpy->ResourceLists[i]) { + _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy); + break; + } + } free(dpy); } @@ -135,29 +141,27 @@ _eglFindDisplay(NativeDisplayType nativeDisplay) void _eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display) { - _EGLContext *contexts; - _EGLSurface *surfaces; - - contexts = display->ContextList; - surfaces = display->SurfaceList; + _EGLResource *list; - while (contexts) { - _EGLContext *ctx = contexts; - contexts = contexts->Next; + list = display->ResourceLists[_EGL_RESOURCE_CONTEXT]; + while (list) { + _EGLContext *ctx = (_EGLContext *) list; + list = list->Next; _eglUnlinkContext(ctx); drv->API.DestroyContext(drv, display, ctx); } - assert(!display->ContextList); + assert(!display->ResourceLists[_EGL_RESOURCE_CONTEXT]); - while (surfaces) { - _EGLSurface *surf = surfaces; - surfaces = surfaces->Next; + list = display->ResourceLists[_EGL_RESOURCE_SURFACE]; + while (list) { + _EGLSurface *surf = (_EGLSurface *) list; + list = list->Next; _eglUnlinkSurface(surf); drv->API.DestroySurface(drv, display, surf); } - assert(!display->SurfaceList); + assert(!display->ResourceLists[_EGL_RESOURCE_SURFACE]); } diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index c1069d7c59..60ed7bcc03 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -63,10 +63,7 @@ struct _egl_display EGLint NumConfigs; _EGLConfig **Configs; /* array [NumConfigs] of ptr to _EGLConfig */ - /* lists of linked contexts and surface */ - _EGLContext *ContextList; - _EGLSurface *SurfaceList; - + /* lists of resources */ _EGLResource *ResourceLists[_EGL_NUM_RESOURCES]; }; diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c index 5e9a3417a6..940a1b760c 100644 --- a/src/egl/main/eglsurface.c +++ b/src/egl/main/eglsurface.c @@ -511,73 +511,3 @@ _eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy, } #endif /* EGL_VERSION_1_2 */ - - -/** - * Link a surface to a display and return the handle of the link. - * The handle can be passed to client directly. - */ -EGLSurface -_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy) -{ - surf->Display = dpy; - surf->Next = dpy->SurfaceList; - dpy->SurfaceList = surf; - return (EGLSurface) surf; -} - - -/** - * Unlink a linked surface from its display. - * Accessing an unlinked surface should generate EGL_BAD_SURFACE error. - */ -void -_eglUnlinkSurface(_EGLSurface *surf) -{ - _EGLSurface *prev; - - prev = surf->Display->SurfaceList; - if (prev != surf) { - while (prev) { - if (prev->Next == surf) - break; - prev = prev->Next; - } - assert(prev); - prev->Next = surf->Next; - } - else { - prev = NULL; - surf->Display->SurfaceList = surf->Next; - } - - surf->Next = NULL; - surf->Display = NULL; -} - - -#ifndef _EGL_SKIP_HANDLE_CHECK - - -/** - * Return EGL_TRUE if the given handle is a valid handle to a surface. - */ -EGLBoolean -_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy) -{ - _EGLSurface *cur = NULL; - - if (dpy) - cur = dpy->SurfaceList; - while (cur) { - if (cur == (_EGLSurface *) surf) { - assert(cur->Display == dpy); - break; - } - cur = cur->Next; - } - return (cur != NULL); -} - - -#endif /* !_EGL_SKIP_HANDLE_CHECK */ diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h index b1163293fe..da07133c2c 100644 --- a/src/egl/main/eglsurface.h +++ b/src/egl/main/eglsurface.h @@ -3,6 +3,7 @@ #include "egltypedefs.h" +#include "egldisplay.h" /** @@ -10,9 +11,8 @@ */ struct _egl_surface { - /* Managed by EGLDisplay for linking */ - _EGLDisplay *Display; - _EGLSurface *Next; + /* A surface is a display resource */ + _EGLResource Resource; /* The bound status of the surface */ _EGLContext *Binding; @@ -111,33 +111,27 @@ _eglIsSurfaceBound(_EGLSurface *surf) } -extern EGLSurface -_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy); - - -extern void -_eglUnlinkSurface(_EGLSurface *surf); - - -#ifndef _EGL_SKIP_HANDLE_CHECK - - -extern EGLBoolean -_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy); - - -#else /* !_EGL_SKIP_HANDLE_CHECK */ - - -static INLINE EGLBoolean -_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy) +/** + * Link a surface to a display and return the handle of the link. + * The handle can be passed to client directly. + */ +static INLINE EGLSurface +_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy) { - _EGLSurface *s = (_EGLSurface *) surf; - return (dpy && s && s->Display == dpy); + _eglLinkResource(&surf->Resource, _EGL_RESOURCE_SURFACE, dpy); + return (EGLSurface) surf; } -#endif /* _EGL_SKIP_HANDLE_CHECK */ +/** + * Unlink a linked surface from its display. + * Accessing an unlinked surface should generate EGL_BAD_SURFACE error. + */ +static INLINE void +_eglUnlinkSurface(_EGLSurface *surf) +{ + _eglUnlinkResource(&surf->Resource, _EGL_RESOURCE_SURFACE); +} /** @@ -147,8 +141,9 @@ _eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy) static INLINE _EGLSurface * _eglLookupSurface(EGLSurface surface, _EGLDisplay *dpy) { + _EGLResource *res = (_EGLResource *) surface; _EGLSurface *surf = (_EGLSurface *) surface; - if (!_eglCheckSurfaceHandle(surf, dpy)) + if (!res || !dpy || !_eglCheckResource(res, _EGL_RESOURCE_SURFACE, dpy)) surf = NULL; return surf; } @@ -160,7 +155,9 @@ _eglLookupSurface(EGLSurface surface, _EGLDisplay *dpy) static INLINE EGLSurface _eglGetSurfaceHandle(_EGLSurface *surf) { - return (EGLSurface) ((surf && surf->Display) ? surf : EGL_NO_SURFACE); + _EGLResource *res = (_EGLResource *) surf; + return (res && _eglIsResourceLinked(res)) ? + (EGLSurface) surf : EGL_NO_SURFACE; } @@ -170,7 +167,8 @@ _eglGetSurfaceHandle(_EGLSurface *surf) static INLINE EGLBoolean _eglIsSurfaceLinked(_EGLSurface *surf) { - return (EGLBoolean) (_eglGetSurfaceHandle(surf) != EGL_NO_SURFACE); + _EGLResource *res = (_EGLResource *) surf; + return (res && _eglIsResourceLinked(res)); } diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index 2ac6215646..dc26f95cee 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -543,7 +543,7 @@ egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private) * Set force_validate to skip an unnecessary check. */ gctx->force_validate = EGL_TRUE; - egl_g3d_validate_context(gctx->base.Display, &gctx->base); + egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base); } static EGLBoolean -- cgit v1.2.3 From daea9270f877e3f32ef93f71ffa2d27dac4162b4 Mon Sep 17 00:00:00 2001 From: Igor Oliveira Date: Sun, 24 Jan 2010 12:26:31 -0400 Subject: egl: check if driver_name is null --- src/gallium/state_trackers/egl/x11/native_x11.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c index 695ab88010..dd3c9f8b6a 100644 --- a/src/gallium/state_trackers/egl/x11/native_x11.c +++ b/src/gallium/state_trackers/egl/x11/native_x11.c @@ -70,7 +70,8 @@ native_create_probe(EGLNativeDisplayType dpy) if (xscr) { if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) { driver_name = x11_screen_probe_dri2(xscr); - nprobe->data = strdup(driver_name); + if (driver_name) + nprobe->data = strdup(driver_name); } x11_screen_destroy(xscr); -- cgit v1.2.3 From 4aed0944f4b8b8d14d210cf6bc87ccddfa9a77ec Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 25 Jan 2010 11:55:48 +0800 Subject: egl: Native types are renamed in EGL 1.3. Rename Native*Type to EGLNative*Type. --- src/egl/drivers/glx/egl_glx.c | 10 ++++++---- src/egl/drivers/xdri/egl_xdri.c | 3 ++- src/egl/main/eglapi.c | 8 ++++---- src/egl/main/eglapi.h | 6 +++--- src/egl/main/egldisplay.c | 4 ++-- src/egl/main/egldisplay.h | 4 ++-- src/egl/main/eglsurface.c | 6 +++--- src/egl/main/eglsurface.h | 6 +++--- src/gallium/state_trackers/egl/common/egl_g3d.c | 2 +- 9 files changed, 26 insertions(+), 23 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index 6d2815888b..89a4353f8a 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -677,8 +677,9 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static _EGLSurface * -GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, - NativeWindowType window, const EGLint *attrib_list) +GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, + _EGLConfig *conf, EGLNativeWindowType window, + const EGLint *attrib_list) { struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); struct GLX_egl_surface *GLX_surf; @@ -719,8 +720,9 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, } static _EGLSurface * -GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, - NativePixmapType pixmap, const EGLint *attrib_list) +GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, + _EGLConfig *conf, EGLNativePixmapType pixmap, + const EGLint *attrib_list) { struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); struct GLX_egl_surface *GLX_surf; diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index b133939155..df251d908b 100644 --- a/src/egl/drivers/xdri/egl_xdri.c +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -484,7 +484,8 @@ xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d, */ static _EGLSurface * xdri_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - NativeWindowType window, const EGLint *attrib_list) + EGLNativeWindowType window, + const EGLint *attrib_list) { struct xdri_egl_display *xdri_dpy = lookup_display(dpy); struct xdri_egl_config *xdri_config = lookup_config(conf); diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 218de3ab6b..c197cfd38f 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -73,7 +73,7 @@ * We initialize our global vars and create a private _EGLDisplay object. */ EGLDisplay EGLAPIENTRY -eglGetDisplay(NativeDisplayType nativeDisplay) +eglGetDisplay(EGLNativeDisplayType nativeDisplay) { _EGLDisplay *dpy; dpy = _eglFindDisplay(nativeDisplay); @@ -418,7 +418,7 @@ eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, - NativeWindowType window, const EGLint *attrib_list) + EGLNativeWindowType window, const EGLint *attrib_list) { _EGLDisplay *disp = _eglLookupDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); @@ -439,7 +439,7 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, - NativePixmapType pixmap, const EGLint *attrib_list) + EGLNativePixmapType pixmap, const EGLint *attrib_list) { _EGLDisplay *disp = _eglLookupDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); @@ -553,7 +553,7 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) EGLBoolean EGLAPIENTRY -eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target) +eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); return drv->API.CopyBuffers(drv, disp, surf, target); diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index bd3c3b4875..db31c7cf93 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -27,8 +27,8 @@ typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurfa typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value); /* surface funcs */ -typedef _EGLSurface *(*CreateWindowSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, NativeWindowType window, const EGLint *attrib_list); -typedef _EGLSurface *(*CreatePixmapSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, NativePixmapType pixmap, const EGLint *attrib_list); +typedef _EGLSurface *(*CreateWindowSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, EGLNativeWindowType window, const EGLint *attrib_list); +typedef _EGLSurface *(*CreatePixmapSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, EGLNativePixmapType pixmap, const EGLint *attrib_list); typedef _EGLSurface *(*CreatePbufferSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list); typedef EGLBoolean (*DestroySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface); typedef EGLBoolean (*QuerySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint *value); @@ -37,7 +37,7 @@ typedef EGLBoolean (*BindTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurf typedef EGLBoolean (*ReleaseTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer); typedef EGLBoolean (*SwapInterval_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint interval); typedef EGLBoolean (*SwapBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw); -typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, NativePixmapType target); +typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLNativePixmapType target); /* misc funcs */ typedef const char *(*QueryString_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name); diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index 74c655df41..359900ca2f 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -52,7 +52,7 @@ _eglFiniDisplay(void) * Note that nativeDisplay may be an X Display ptr, or a string. */ _EGLDisplay * -_eglNewDisplay(NativeDisplayType nativeDisplay) +_eglNewDisplay(EGLNativeDisplayType nativeDisplay) { _EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay)); if (dpy) { @@ -114,7 +114,7 @@ _eglUnlinkDisplay(_EGLDisplay *dpy) * linked displays. */ _EGLDisplay * -_eglFindDisplay(NativeDisplayType nativeDisplay) +_eglFindDisplay(EGLNativeDisplayType nativeDisplay) { _EGLDisplay *dpy; diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 5d44eb1ea8..d811f2ee8e 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -76,7 +76,7 @@ _eglFiniDisplay(void); extern _EGLDisplay * -_eglNewDisplay(NativeDisplayType displayName); +_eglNewDisplay(EGLNativeDisplayType displayName); extern EGLDisplay @@ -88,7 +88,7 @@ _eglUnlinkDisplay(_EGLDisplay *dpy); extern _EGLDisplay * -_eglFindDisplay(NativeDisplayType nativeDisplay); +_eglFindDisplay(EGLNativeDisplayType nativeDisplay); PUBLIC void diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c index 940a1b760c..89eb93d808 100644 --- a/src/egl/main/eglsurface.c +++ b/src/egl/main/eglsurface.c @@ -237,7 +237,7 @@ _eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) EGLBoolean _eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, - NativePixmapType target) + EGLNativePixmapType target) { /* copy surface to native pixmap */ /* All implementation burdon for this is in the device driver */ @@ -319,7 +319,7 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, */ _EGLSurface * _eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - NativeWindowType window, const EGLint *attrib_list) + EGLNativeWindowType window, const EGLint *attrib_list) { #if 0 /* THIS IS JUST EXAMPLE CODE */ _EGLSurface *surf; @@ -344,7 +344,7 @@ _eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, */ _EGLSurface * _eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - NativePixmapType pixmap, const EGLint *attrib_list) + EGLNativePixmapType pixmap, const EGLint *attrib_list) { #if 0 /* THIS IS JUST EXAMPLE CODE */ _EGLSurface *surf; diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h index f1642356b0..4062b990fa 100644 --- a/src/egl/main/eglsurface.h +++ b/src/egl/main/eglsurface.h @@ -50,7 +50,7 @@ _eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf); extern EGLBoolean -_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, NativePixmapType target); +_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLNativePixmapType target); extern EGLBoolean @@ -58,11 +58,11 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint at extern _EGLSurface * -_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list); +_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, EGLNativeWindowType window, const EGLint *attrib_list); extern _EGLSurface * -_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list); +_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, EGLNativePixmapType pixmap, const EGLint *attrib_list); extern _EGLSurface * diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index dc26f95cee..d073f226f2 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -974,7 +974,7 @@ get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf, static EGLBoolean egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, - NativePixmapType target) + EGLNativePixmapType target) { struct egl_g3d_display *gdpy = egl_g3d_display(dpy); struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); -- cgit v1.2.3 From 16cf7e14a6dee85fadc0ab4e7c066288c3362352 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 21 Jan 2010 21:28:14 +0100 Subject: st/xorg: Fix warning --- src/gallium/state_trackers/xorg/xorg_dri2.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 468563e34c..83dc92e7fa 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -375,6 +375,7 @@ xorg_dri2_init(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); DRI2InfoRec dri2info; +#if DRI2INFOREC_VERSION >= 2 int major, minor; if (xf86LoaderCheckSymbol("DRI2Version")) { @@ -384,6 +385,7 @@ xorg_dri2_init(ScreenPtr pScreen) major = 1; minor = 0; } +#endif dri2info.version = DRI2INFOREC_VERSION; dri2info.fd = ms->fd; -- cgit v1.2.3 From 36fd55f9f03b00263ee1ccf22bbb50e5ba048e80 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 21 Jan 2010 21:23:22 +0100 Subject: st/xorg: Export helper function for detecting modesetting --- src/gallium/state_trackers/xorg/xorg_driver.c | 22 ++++++++++++++++++++++ src/gallium/state_trackers/xorg/xorg_winsys.h | 1 + 2 files changed, 23 insertions(+) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index 41bfcd0f5e..c180f0b156 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -110,6 +110,28 @@ xorg_tracker_set_functions(ScrnInfoPtr scrn) scrn->ValidMode = drv_valid_mode; } +Bool +xorg_tracker_have_modesetting(ScrnInfoPtr pScrn, struct pci_device *device) +{ + char *BusID = xalloc(64); + sprintf(BusID, "pci:%04x:%02x:%02x.%d", + device->domain, device->bus, + device->dev, device->func); + + if (drmCheckModesettingSupported(BusID)) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, + "Drm modesetting not supported %s\n", BusID); + xfree(BusID); + return FALSE; + } + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, + "Drm modesetting supported on %s\n", BusID); + + xfree(BusID); + return TRUE; +} + /* * Internal function definitions diff --git a/src/gallium/state_trackers/xorg/xorg_winsys.h b/src/gallium/state_trackers/xorg/xorg_winsys.h index 47ee4b9ffd..865733bca2 100644 --- a/src/gallium/state_trackers/xorg/xorg_winsys.h +++ b/src/gallium/state_trackers/xorg/xorg_winsys.h @@ -45,5 +45,6 @@ void xorg_tracker_set_functions(ScrnInfoPtr scrn); const OptionInfoRec * xorg_tracker_available_options(int chipid, int busid); +Bool xorg_tracker_have_modesetting(ScrnInfoPtr pScrn, struct pci_device *device); #endif -- cgit v1.2.3 From 0b482c4fbe69a807bb69bf92f37e362f818c664d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 22 Jan 2010 18:28:40 +0100 Subject: st/xorg: Improve options and print them to log Set 2D acceleration to off by default Get fallback debugging from the Xorg config Also print if 3D acceleration is enabled --- src/gallium/state_trackers/xorg/xorg_driver.c | 20 +++++++++++++++++--- src/gallium/state_trackers/xorg/xorg_tracker.h | 1 + 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index c180f0b156..0ff6c52915 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -78,11 +78,13 @@ typedef enum { OPTION_SW_CURSOR, OPTION_2D_ACCEL, + OPTION_DEBUG_FALLBACK, } drv_option_enums; static const OptionInfoRec drv_options[] = { {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_DEBUG_FALLBACK, "DebugFallback", OPTV_BOOLEAN, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; @@ -670,10 +672,11 @@ 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); + if (ms->screen) { - ms->exa = xorg_exa_init(pScrn, xf86ReturnOptValBool(ms->Options, - OPTION_2D_ACCEL, TRUE)); - ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE); + ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d); xorg_xv_init(pScreen); #ifdef DRI2 @@ -681,6 +684,17 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif } + 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", + ms->debug_fallback ? "enabled" : "disabled"); +#ifdef DRI2 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is %s\n", + ms->screen ? "enabled" : "disabled"); +#else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n"); +#endif + miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h index c0cfbe6061..b5915d2a42 100644 --- a/src/gallium/state_trackers/xorg/xorg_tracker.h +++ b/src/gallium/state_trackers/xorg/xorg_tracker.h @@ -112,6 +112,7 @@ typedef struct _modesettingRec /* exa */ struct exa_context *exa; Bool noEvict; + Bool accelerate_2d; Bool debug_fallback; /* winsys hocks */ -- cgit v1.2.3 From 92676b9fe6356a8974830c47c0191d1ca57a0741 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Mon, 25 Jan 2010 16:32:18 +0100 Subject: xorg: adapt to blend changes --- src/gallium/state_trackers/xorg/xorg_composite.c | 12 ++++++------ src/gallium/state_trackers/xorg/xorg_renderer.c | 10 +++++----- src/gallium/state_trackers/xorg/xorg_xv.c | 12 ++++++------ 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c index 1c248a629e..66f83f566c 100644 --- a/src/gallium/state_trackers/xorg/xorg_composite.c +++ b/src/gallium/state_trackers/xorg/xorg_composite.c @@ -220,13 +220,13 @@ bind_blend_state(struct exa_context *exa, int op, blend_for_op(&blend_opt, op, pSrcPicture, pMaskPicture, pDstPicture); memset(&blend, 0, sizeof(struct pipe_blend_state)); - blend.blend_enable = 1; - blend.colormask |= PIPE_MASK_RGBA; + blend.rt[0].blend_enable = 1; + blend.rt[0].colormask = PIPE_MASK_RGBA; - blend.rgb_src_factor = blend_opt.rgb_src; - blend.alpha_src_factor = blend_opt.rgb_src; - blend.rgb_dst_factor = blend_opt.rgb_dst; - blend.alpha_dst_factor = blend_opt.rgb_dst; + blend.rt[0].rgb_src_factor = blend_opt.rgb_src; + blend.rt[0].alpha_src_factor = blend_opt.rgb_src; + blend.rt[0].rgb_dst_factor = blend_opt.rgb_dst; + blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst; cso_set_blend(exa->renderer->cso, &blend); } diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c index 8f729b565b..0b6600da6f 100644 --- a/src/gallium/state_trackers/xorg/xorg_renderer.c +++ b/src/gallium/state_trackers/xorg/xorg_renderer.c @@ -445,11 +445,11 @@ void renderer_copy_prepare(struct xorg_renderer *r, { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].colormask = PIPE_MASK_RGBA; cso_set_blend(r->cso, &blend); } diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c index 5bf0e94b62..c4580935c3 100644 --- a/src/gallium/state_trackers/xorg/xorg_xv.c +++ b/src/gallium/state_trackers/xorg/xorg_xv.c @@ -403,14 +403,14 @@ bind_blend_state(struct xorg_xv_port_priv *port) struct pipe_blend_state blend; memset(&blend, 0, sizeof(struct pipe_blend_state)); - blend.blend_enable = 1; - blend.colormask |= PIPE_MASK_RGBA; + blend.rt[0].blend_enable = 1; /* XXX why? */ + blend.rt[0].colormask = PIPE_MASK_RGBA; /* porter&duff src */ - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; cso_set_blend(port->r->cso, &blend); } -- cgit v1.2.3 From feefa7a510058f57a81e5e928cd2fcb63506624f Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Mon, 25 Jan 2010 16:33:09 +0100 Subject: vega: adapt to blend changes --- src/gallium/state_trackers/vega/api_filters.c | 18 +++---- src/gallium/state_trackers/vega/api_masks.c | 13 ++--- src/gallium/state_trackers/vega/mask.c | 15 +++--- src/gallium/state_trackers/vega/polygon.c | 10 ++-- src/gallium/state_trackers/vega/renderer.c | 20 ++++---- src/gallium/state_trackers/vega/vg_context.c | 70 +++++++++++++-------------- 6 files changed, 70 insertions(+), 76 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c index 8f69ee0109..555d3bd7f9 100644 --- a/src/gallium/state_trackers/vega/api_filters.c +++ b/src/gallium/state_trackers/vega/api_filters.c @@ -127,19 +127,19 @@ static void setup_blend() struct vg_context *ctx = vg_current_context(); struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; if (ctx->state.vg.filter_channel_mask & VG_RED) - blend.colormask |= PIPE_MASK_R; + blend.rt[0].colormask |= PIPE_MASK_R; if (ctx->state.vg.filter_channel_mask & VG_GREEN) - blend.colormask |= PIPE_MASK_G; + blend.rt[0].colormask |= PIPE_MASK_G; if (ctx->state.vg.filter_channel_mask & VG_BLUE) - blend.colormask |= PIPE_MASK_B; + blend.rt[0].colormask |= PIPE_MASK_B; if (ctx->state.vg.filter_channel_mask & VG_ALPHA) - blend.colormask |= PIPE_MASK_A; - blend.blend_enable = 1; + blend.rt[0].colormask |= PIPE_MASK_A; + blend.rt[0].blend_enable = 1; /* XXX why? */ cso_set_blend(ctx->cso_context, &blend); } diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c index 97cbe69205..e6070c7353 100644 --- a/src/gallium/state_trackers/vega/api_masks.c +++ b/src/gallium/state_trackers/vega/api_masks.c @@ -128,14 +128,11 @@ clear_with_quad(struct vg_context *st, float x0, float y0, { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask |= PIPE_MASK_R; - blend.colormask |= PIPE_MASK_G; - blend.colormask |= PIPE_MASK_B; - blend.colormask |= PIPE_MASK_A; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].colormask = PIPE_MASK_RGBA; cso_set_blend(st->cso_context, &blend); } diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c index 3e260e7073..d94fa47da6 100644 --- a/src/gallium/state_trackers/vega/mask.c +++ b/src/gallium/state_trackers/vega/mask.c @@ -354,15 +354,12 @@ static void setup_mask_blend() struct pipe_blend_state blend; memset(&blend, 0, sizeof(struct pipe_blend_state)); - blend.blend_enable = 1; - blend.colormask |= PIPE_MASK_R; - blend.colormask |= PIPE_MASK_G; - blend.colormask |= PIPE_MASK_B; - blend.colormask |= PIPE_MASK_A; - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].blend_enable = 1; /* XXX why? */ + blend.rt[0].colormask = PIPE_MASK_RGBA; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; cso_set_blend(ctx->cso_context, &blend); } diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c index d385ee567f..f5352ee84e 100644 --- a/src/gallium/state_trackers/vega/polygon.c +++ b/src/gallium/state_trackers/vega/polygon.c @@ -248,12 +248,12 @@ VGboolean polygon_is_closed(struct polygon *p) static void set_blend_for_fill(struct pipe_blend_state *blend) { memset(blend, 0, sizeof(struct pipe_blend_state)); - blend->colormask = 0; /*disable colorwrites*/ + blend->rt[0].colormask = 0; /*disable colorwrites*/ - blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; } static void draw_polygon(struct vg_context *ctx, diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c index 64e3a7c545..47e18dc1e2 100644 --- a/src/gallium/state_trackers/vega/renderer.c +++ b/src/gallium/state_trackers/vega/renderer.c @@ -317,11 +317,11 @@ void renderer_copy_texture(struct renderer *ctx, { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].colormask = PIPE_MASK_RGBA; cso_set_blend(ctx->cso, &blend); } @@ -486,11 +486,11 @@ void renderer_copy_surface(struct renderer *ctx, { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].colormask = PIPE_MASK_RGBA; cso_set_blend(ctx->cso, &blend); } diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c index c16ac036e3..f05a5e68c6 100644 --- a/src/gallium/state_trackers/vega/vg_context.c +++ b/src/gallium/state_trackers/vega/vg_context.c @@ -252,7 +252,7 @@ static void update_clip_state(struct vg_context *ctx) ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0, 0); /* disable color writes */ - blend->colormask = 0; /*disable colorwrites*/ + blend->rt[0].colormask = 0; /*disable colorwrites*/ cso_set_blend(ctx->cso_context, blend); /* enable scissoring */ @@ -286,7 +286,8 @@ static void update_clip_state(struct vg_context *ctx) renderer_draw_quad(ctx->renderer, minx, miny, maxx, maxy, 0.0f); } - blend->colormask = 1; /*enable colorwrites*/ + blend->rt[0].colormask = PIPE_MASK_R; /*enable colorwrites*/ + /* XXX really only for red channel? */ cso_restore_blend(ctx->cso_context); cso_restore_fragment_shader(ctx->cso_context); @@ -301,57 +302,56 @@ void vg_validate_state(struct vg_context *ctx) if ((ctx->state.dirty & BLEND_DIRTY)) { struct pipe_blend_state *blend = &ctx->state.g3d.blend; memset(blend, 0, sizeof(struct pipe_blend_state)); - blend->blend_enable = 1; - blend->colormask |= PIPE_MASK_R; - blend->colormask |= PIPE_MASK_G; - blend->colormask |= PIPE_MASK_B; - blend->colormask |= PIPE_MASK_A; + blend->rt[0].blend_enable = 1; + blend->rt[0].colormask = PIPE_MASK_RGBA; switch (ctx->state.vg.blend_mode) { case VG_BLEND_SRC: - blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + /* could disable blending ? */ break; case VG_BLEND_SRC_OVER: - blend->rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; - blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; break; case VG_BLEND_DST_OVER: - blend->rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; - blend->alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; break; case VG_BLEND_SRC_IN: - blend->rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; - blend->alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; break; case VG_BLEND_DST_IN: - blend->rgb_src_factor = PIPE_BLENDFACTOR_ZERO; - blend->alpha_src_factor = PIPE_BLENDFACTOR_ZERO; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; break; case VG_BLEND_MULTIPLY: case VG_BLEND_SCREEN: case VG_BLEND_DARKEN: case VG_BLEND_LIGHTEN: - blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + /* could disable blending ? */ break; case VG_BLEND_ADDITIVE: - blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_ONE; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; break; default: assert(!"not implemented blend mode"); -- cgit v1.2.3 From 3770769f21138ba722a38c1400b501fdcedea17d Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Mon, 25 Jan 2010 16:34:29 +0100 Subject: st/python: adapt to blend changes --- src/gallium/state_trackers/python/samples/gs.py | 10 +++++----- src/gallium/state_trackers/python/samples/tri.py | 10 +++++----- src/gallium/state_trackers/python/st_device.c | 10 +++++----- .../tests/regress/fragment-shader/fragment-shader.py | 10 +++++----- .../tests/regress/vertex-shader/vertex-shader.py | 10 +++++----- .../state_trackers/python/tests/texture_render.py | 10 +++++----- .../state_trackers/python/tests/texture_sample.py | 20 ++++++++++---------- 7 files changed, 40 insertions(+), 40 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/python/samples/gs.py b/src/gallium/state_trackers/python/samples/gs.py index a07cf557f2..cd68abac9a 100644 --- a/src/gallium/state_trackers/python/samples/gs.py +++ b/src/gallium/state_trackers/python/samples/gs.py @@ -72,11 +72,11 @@ def test(dev): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # depth/stencil/alpha diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py index e5e168bdc8..f0b5e3dc98 100644 --- a/src/gallium/state_trackers/python/samples/tri.py +++ b/src/gallium/state_trackers/python/samples/tri.py @@ -72,11 +72,11 @@ def test(dev): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # depth/stencil/alpha diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index d144af2447..e41125f6f9 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -180,11 +180,11 @@ st_context_create(struct st_device *st_dev) { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].colormask = PIPE_MASK_RGBA; cso_set_blend(st_ctx->cso, &blend); } diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py index 8d3bf9d4d7..e9d844c718 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py @@ -50,11 +50,11 @@ def test(dev, name): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # depth/stencil/alpha diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py index 01bf5a3210..a185474fa3 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py @@ -50,11 +50,11 @@ def test(dev, name): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # depth/stencil/alpha diff --git a/src/gallium/state_trackers/python/tests/texture_render.py b/src/gallium/state_trackers/python/tests/texture_render.py index 79287f2cac..0fac1ea5ef 100755 --- a/src/gallium/state_trackers/python/tests/texture_render.py +++ b/src/gallium/state_trackers/python/tests/texture_render.py @@ -115,11 +115,11 @@ class TextureTest(TestCase): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # no-op depth/stencil/alpha diff --git a/src/gallium/state_trackers/python/tests/texture_sample.py b/src/gallium/state_trackers/python/tests/texture_sample.py index 520961c805..db32b537a1 100755 --- a/src/gallium/state_trackers/python/tests/texture_sample.py +++ b/src/gallium/state_trackers/python/tests/texture_sample.py @@ -140,11 +140,11 @@ class TextureColorSampleTest(TestCase): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # no-op depth/stencil/alpha @@ -327,11 +327,11 @@ class TextureDepthSampleTest(TestCase): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # depth/stencil/alpha -- cgit v1.2.3 From dbc0e24ab866ce8bdd974b52e050dd022620b146 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Mon, 25 Jan 2010 16:43:33 +0100 Subject: xorg: do not enable unnecessary blending for xv --- src/gallium/state_trackers/xorg/xorg_xv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c index c4580935c3..73c076fac4 100644 --- a/src/gallium/state_trackers/xorg/xorg_xv.c +++ b/src/gallium/state_trackers/xorg/xorg_xv.c @@ -403,7 +403,7 @@ bind_blend_state(struct xorg_xv_port_priv *port) struct pipe_blend_state blend; memset(&blend, 0, sizeof(struct pipe_blend_state)); - blend.rt[0].blend_enable = 1; /* XXX why? */ + blend.rt[0].blend_enable = 0; blend.rt[0].colormask = PIPE_MASK_RGBA; /* porter&duff src */ -- cgit v1.2.3 From 0d3a6a505d537b879f31be0ed14fa8577717efaf Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Mon, 25 Jan 2010 16:52:14 +0100 Subject: vega: don't enable blending if not necessary In some places blending was enabled even though it wasn't necessary. Also remove a (bogus) reenabling of color writes, which wasn't really used. --- src/gallium/state_trackers/vega/api_filters.c | 2 +- src/gallium/state_trackers/vega/mask.c | 2 +- src/gallium/state_trackers/vega/vg_context.c | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c index 555d3bd7f9..cf4a11bb14 100644 --- a/src/gallium/state_trackers/vega/api_filters.c +++ b/src/gallium/state_trackers/vega/api_filters.c @@ -139,7 +139,7 @@ static void setup_blend() blend.rt[0].colormask |= PIPE_MASK_B; if (ctx->state.vg.filter_channel_mask & VG_ALPHA) blend.rt[0].colormask |= PIPE_MASK_A; - blend.rt[0].blend_enable = 1; /* XXX why? */ + blend.rt[0].blend_enable = 0; cso_set_blend(ctx->cso_context, &blend); } diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c index d94fa47da6..ba8ecef1d2 100644 --- a/src/gallium/state_trackers/vega/mask.c +++ b/src/gallium/state_trackers/vega/mask.c @@ -354,7 +354,7 @@ static void setup_mask_blend() struct pipe_blend_state blend; memset(&blend, 0, sizeof(struct pipe_blend_state)); - blend.rt[0].blend_enable = 1; /* XXX why? */ + blend.rt[0].blend_enable = 0; blend.rt[0].colormask = PIPE_MASK_RGBA; blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c index f05a5e68c6..64207d97ba 100644 --- a/src/gallium/state_trackers/vega/vg_context.c +++ b/src/gallium/state_trackers/vega/vg_context.c @@ -286,8 +286,6 @@ static void update_clip_state(struct vg_context *ctx) renderer_draw_quad(ctx->renderer, minx, miny, maxx, maxy, 0.0f); } - blend->rt[0].colormask = PIPE_MASK_R; /*enable colorwrites*/ - /* XXX really only for red channel? */ cso_restore_blend(ctx->cso_context); cso_restore_fragment_shader(ctx->cso_context); @@ -311,7 +309,7 @@ void vg_validate_state(struct vg_context *ctx) blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - /* could disable blending ? */ + blend->rt[0].blend_enable = 0; break; case VG_BLEND_SRC_OVER: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; @@ -345,7 +343,7 @@ void vg_validate_state(struct vg_context *ctx) blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - /* could disable blending ? */ + blend->rt[0].blend_enable = 0; break; case VG_BLEND_ADDITIVE: blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; -- cgit v1.2.3 From 0d051af6127d206d165a1034ca0795ce8fdcd389 Mon Sep 17 00:00:00 2001 From: Igor Oliveira Date: Mon, 25 Jan 2010 09:53:53 -0700 Subject: vega: fix incorrect samplers, textures indexes in blend_bind_samplers() Fixes fd.o bug 25863. Signed-off-by: Brian Paul --- src/gallium/state_trackers/vega/shader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c index d9074a377b..91909da2c0 100644 --- a/src/gallium/state_trackers/vega/shader.c +++ b/src/gallium/state_trackers/vega/shader.c @@ -135,8 +135,8 @@ static VGint blend_bind_samplers(struct vg_context *ctx, textures[2] = stfb->blend_texture; if (!samplers[0] || !textures[0]) { - samplers[1] = samplers[2]; - textures[1] = textures[2]; + samplers[0] = samplers[2]; + textures[0] = textures[2]; } if (!samplers[1] || !textures[1]) { samplers[1] = samplers[0]; -- cgit v1.2.3 From 5fae36147e1067ac8b1eb5bcade2f9b1dbf29aa4 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Mon, 25 Jan 2010 19:27:05 +0100 Subject: st/mesa: handle EXT_draw_buffers2 per rendertarget blend enables / colormasks uses the new gallium per-rt blend functionality --- src/gallium/state_trackers/dri/dri_extensions.c | 5 ++ src/mesa/state_tracker/st_atom_blend.c | 93 ++++++++++++++++--------- src/mesa/state_tracker/st_extensions.c | 10 +++ 3 files changed, 77 insertions(+), 31 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/dri/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c index 8b014a2a8b..1259813a41 100644 --- a/src/gallium/state_trackers/dri/dri_extensions.c +++ b/src/gallium/state_trackers/dri/dri_extensions.c @@ -50,6 +50,7 @@ #define need_GL_EXT_blend_func_separate #define need_GL_EXT_blend_minmax #define need_GL_EXT_cull_vertex +#define need_GL_EXT_draw_buffers2 #define need_GL_EXT_fog_coord #define need_GL_EXT_framebuffer_object #define need_GL_EXT_multi_draw_arrays @@ -98,6 +99,7 @@ static const struct dri_extension card_extensions[] = { {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, {"GL_EXT_blend_subtract", NULL}, {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_draw_buffers2", GL_EXT_draw_buffers2_functions}, {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, @@ -130,6 +132,9 @@ dri_init_extensions(struct dri_context *ctx) /* The card_extensions list should be pruned according to the * capabilities of the pipe_screen. This is actually something * that can/should be done inside st_create_context(). + * XXX Not pruning is very bogus. Always all these extensions above + * will be advertized, regardless what st_init_extensions + * (which depends on the pipe cap bits) does. */ driInitExtensions(ctx->st->ctx, card_extensions, GL_TRUE); } diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index 75c1418335..809b10d479 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -152,14 +152,40 @@ translate_logicop(GLenum logicop) } } +static boolean +colormask_perrt(GLcontext *ctx) +{ + /* XXX this is ugly beyond belief */ + unsigned i; + for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) { + if (!TEST_EQ_4V(ctx->Color.ColorMask[0], ctx->Color.ColorMask[i])) { + return true; + } + } + return false; +} static void update_blend( struct st_context *st ) { struct pipe_blend_state *blend = &st->state.blend; + unsigned num_state = 1; + unsigned i; memset(blend, 0, sizeof(*blend)); + if ((st->ctx->Color.BlendEnabled && + (st->ctx->Color.BlendEnabled != ((1 << st->ctx->Const.MaxDrawBuffers) - 1))) || + colormask_perrt(st->ctx)) { + num_state = st->ctx->Const.MaxDrawBuffers; + blend->independent_blend_enable = 1; + } + /* Note it is impossible to correctly deal with EXT_blend_logic_op and + EXT_draw_buffers2/EXT_blend_equation_separate at the same time. + These combinations would require support for per-rt logicop enables + and separate alpha/rgb logicop/blend support respectively. Neither + possible in gallium nor most hardware. Assume these combinations + don't happen. */ if (st->ctx->Color.ColorLogicOpEnabled || (st->ctx->Color.BlendEnabled && st->ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) { @@ -169,30 +195,33 @@ update_blend( struct st_context *st ) } else if (st->ctx->Color.BlendEnabled) { /* blending enabled */ - blend->rt[0].blend_enable = 1; - - blend->rt[0].rgb_func = translate_blend(st->ctx->Color.BlendEquationRGB); - if (st->ctx->Color.BlendEquationRGB == GL_MIN || - st->ctx->Color.BlendEquationRGB == GL_MAX) { - /* Min/max are special */ - blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; - } - else { - blend->rt[0].rgb_src_factor = translate_blend(st->ctx->Color.BlendSrcRGB); - blend->rt[0].rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB); - } + for (i = 0; i < num_state; i++) { - blend->rt[0].alpha_func = translate_blend(st->ctx->Color.BlendEquationA); - if (st->ctx->Color.BlendEquationA == GL_MIN || - st->ctx->Color.BlendEquationA == GL_MAX) { - /* Min/max are special */ - blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; - } - else { - blend->rt[0].alpha_src_factor = translate_blend(st->ctx->Color.BlendSrcA); - blend->rt[0].alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA); + blend->rt[i].blend_enable = (st->ctx->Color.BlendEnabled >> i) & 0x1; + + blend->rt[i].rgb_func = translate_blend(st->ctx->Color.BlendEquationRGB); + if (st->ctx->Color.BlendEquationRGB == GL_MIN || + st->ctx->Color.BlendEquationRGB == GL_MAX) { + /* Min/max are special */ + blend->rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + } + else { + blend->rt[i].rgb_src_factor = translate_blend(st->ctx->Color.BlendSrcRGB); + blend->rt[i].rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB); + } + + blend->rt[i].alpha_func = translate_blend(st->ctx->Color.BlendEquationA); + if (st->ctx->Color.BlendEquationA == GL_MIN || + st->ctx->Color.BlendEquationA == GL_MAX) { + /* Min/max are special */ + blend->rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + } + else { + blend->rt[i].alpha_src_factor = translate_blend(st->ctx->Color.BlendSrcA); + blend->rt[i].alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA); + } } } else { @@ -200,14 +229,16 @@ update_blend( struct st_context *st ) } /* Colormask - maybe reverse these bits? */ - if (st->ctx->Color.ColorMask[0][0]) - blend->rt[0].colormask |= PIPE_MASK_R; - if (st->ctx->Color.ColorMask[0][1]) - blend->rt[0].colormask |= PIPE_MASK_G; - if (st->ctx->Color.ColorMask[0][2]) - blend->rt[0].colormask |= PIPE_MASK_B; - if (st->ctx->Color.ColorMask[0][3]) - blend->rt[0].colormask |= PIPE_MASK_A; + for (i = 0; i < num_state; i++) { + if (st->ctx->Color.ColorMask[i][0]) + blend->rt[i].colormask |= PIPE_MASK_R; + if (st->ctx->Color.ColorMask[i][1]) + blend->rt[i].colormask |= PIPE_MASK_G; + if (st->ctx->Color.ColorMask[i][2]) + blend->rt[i].colormask |= PIPE_MASK_B; + if (st->ctx->Color.ColorMask[i][3]) + blend->rt[i].colormask |= PIPE_MASK_A; + } if (st->ctx->Color.DitherFlag) blend->dither = 1; diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 2a5fb27d8f..a7411c8643 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -315,4 +315,14 @@ void st_init_extensions(struct st_context *st) if (st->pipe->render_condition) { ctx->Extensions.NV_conditional_render = GL_TRUE; } + + if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_ENABLE)) { + ctx->Extensions.EXT_draw_buffers2 = GL_TRUE; + } + +#if 0 /* not yet */ + if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC)) { + ctx->Extensions.ARB_draw_buffers_blend = GL_TRUE; + } +#endif } -- cgit v1.2.3 From 6749310d3f60df70ad8f82db986871ab9496793b Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 25 Jan 2010 20:07:43 +0100 Subject: st/xorg: Fix crash on resize with libkms --- src/gallium/state_trackers/xorg/xorg_driver.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index 0ff6c52915..e4ad789e9b 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -1066,12 +1066,22 @@ drv_bind_front_buffer_kms(ScrnInfoPtr pScrn) goto err_destroy; pScreen->ModifyPixmapHeader(rootPixmap, - pScreen->width, - pScreen->height, + pScrn->virtualX, + pScrn->virtualY, pScreen->rootDepth, pScrn->bitsPerPixel, stride, ptr); + + /* This a hack to work around EnableDisableFBAccess setting the pointer + * the real fix would be to replace pScrn->EnableDisableFBAccess hook + * and set the rootPixmap->devPrivate.ptr to something valid before that. + * + * But in its infinit visdome something uses either this some times before + * that, so our hook doesn't get called before the crash happens. + */ + pScrn->pixmapPrivate.ptr = ptr; + return TRUE; err_destroy: -- cgit v1.2.3 From a1717970e78d897f527273278bf1346cc86a5741 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 26 Jan 2010 17:13:51 +0800 Subject: egl: Remove _eglGetCurrentSurface and _eglGetCurrentDisplay. They have little use in drivers since drivers need to work for multiple current contexts. --- src/egl/drivers/xdri/egl_xdri.c | 3 +- src/egl/main/eglapi.c | 4 +-- src/egl/main/eglcurrent.c | 37 ------------------------- src/egl/main/eglcurrent.h | 8 ------ src/gallium/state_trackers/egl/common/egl_g3d.c | 7 +++-- 5 files changed, 7 insertions(+), 52 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index df251d908b..e13d884e71 100644 --- a/src/egl/drivers/xdri/egl_xdri.c +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -574,8 +574,7 @@ xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw) struct xdri_egl_surface *xdri_surf = lookup_surface(draw); /* swapBuffers does not flush commands */ - if (draw == _eglGetCurrentSurface(EGL_DRAW) && - xdri_driver->FlushCurrentContext) + if (draw->Binding && xdri_driver->FlushCurrentContext) xdri_driver->FlushCurrentContext(); xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable, 0, 0, 0); diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 2e5027a32e..492a14180a 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -629,8 +629,8 @@ eglWaitNative(EGLint engine) EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void) { - _EGLDisplay *dpy = _eglGetCurrentDisplay(); - return _eglGetDisplayHandle(dpy); + _EGLContext *ctx = _eglGetCurrentContext(); + return (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY; } diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c index b3be2305fd..696d04e8ba 100644 --- a/src/egl/main/eglcurrent.c +++ b/src/egl/main/eglcurrent.c @@ -248,43 +248,6 @@ _eglGetCurrentContext(void) } -/** - * Return the display of the currently bound context, or NULL. - */ -_EGLDisplay * -_eglGetCurrentDisplay(void) -{ - _EGLThreadInfo *t = _eglGetCurrentThread(); - _EGLContext *ctx = t->CurrentContexts[t->CurrentAPIIndex]; - if (ctx) - return ctx->Resource.Display; - else - return NULL; -} - - -/** - * Return the read or write surface of the currently bound context, or NULL. - */ -_EGLSurface * -_eglGetCurrentSurface(EGLint readdraw) -{ - _EGLThreadInfo *t = _eglGetCurrentThread(); - _EGLContext *ctx = t->CurrentContexts[t->CurrentAPIIndex]; - if (ctx) { - switch (readdraw) { - case EGL_DRAW: - return ctx->DrawSurface; - case EGL_READ: - return ctx->ReadSurface; - default: - return NULL; - } - } - return NULL; -} - - /** * Record EGL error code. */ diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h index b8c2bda485..c169c93e94 100644 --- a/src/egl/main/eglcurrent.h +++ b/src/egl/main/eglcurrent.h @@ -80,14 +80,6 @@ PUBLIC _EGLContext * _eglGetCurrentContext(void); -PUBLIC _EGLDisplay * -_eglGetCurrentDisplay(void); - - -PUBLIC _EGLSurface * -_eglGetCurrentSurface(EGLint readdraw); - - PUBLIC EGLBoolean _eglError(EGLint errCode, const char *msg); diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index d073f226f2..aa4f012216 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -1037,14 +1037,15 @@ egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) static EGLBoolean egl_g3d_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine) { - _EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW); - struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + _EGLContext *ctx = _eglGetCurrentContext(); if (engine != EGL_CORE_NATIVE_ENGINE) return _eglError(EGL_BAD_PARAMETER, "eglWaitNative"); - if (gsurf) + if (ctx && ctx->DrawSurface) { + struct egl_g3d_surface *gsurf = egl_g3d_surface(ctx->DrawSurface); gsurf->native->wait(gsurf->native); + } return EGL_TRUE; } -- cgit v1.2.3 From 4030cd5a2d2cea6e0eab602ce6fdd9a558db6275 Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Thu, 28 Jan 2010 00:20:22 -0800 Subject: st/dri: Remove unnecessary headers. --- src/gallium/state_trackers/dri/dri_drawable.c | 1 - src/gallium/state_trackers/dri/dri_screen.c | 4 ---- 2 files changed, 5 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index 28fd8decf1..1f456cb829 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -35,7 +35,6 @@ #include "pipe/p_context.h" #include "pipe/p_screen.h" -#include "pipe/p_inlines.h" #include "main/mtypes.h" #include "main/renderbuffer.h" #include "state_tracker/drm_api.h" diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index cdc8eb1b12..a412b81256 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -37,14 +37,10 @@ #include "dri_context.h" #include "dri_drawable.h" -#include "pipe/p_context.h" #include "pipe/p_screen.h" -#include "pipe/p_inlines.h" #include "pipe/p_format.h" #include "state_tracker/drm_api.h" #include "state_tracker/dri1_api.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_cb_fbo.h" PUBLIC const char __driConfigOptions[] = DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE -- cgit v1.2.3 From 347cd2b0d507dad538859ad2d75a005821bc2461 Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Thu, 28 Jan 2010 00:25:20 -0800 Subject: st/xorg: Remove unnecessary headers. --- src/gallium/state_trackers/xorg/xorg_crtc.c | 1 - src/gallium/state_trackers/xorg/xorg_dri2.c | 1 - src/gallium/state_trackers/xorg/xorg_exa.c | 1 - src/gallium/state_trackers/xorg/xorg_renderer.c | 1 - src/gallium/state_trackers/xorg/xorg_xv.c | 2 -- 5 files changed, 6 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index 650d2c0d1d..2786558b76 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -50,7 +50,6 @@ #endif #include "pipe/p_inlines.h" -#include "util/u_format.h" #include "util/u_rect.h" #ifdef HAVE_LIBKMS diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 11b81c9ce2..59588f0ff7 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -41,7 +41,6 @@ #include "pipe/p_inlines.h" #include "util/u_format.h" -#include "util/u_rect.h" /* Make all the #if cases in the code esier to read */ #ifndef DRI2INFOREC_VERSION diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index c91dee7346..70af0c5fed 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -42,7 +42,6 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "util/u_format.h" #include "util/u_rect.h" #include "util/u_math.h" #include "util/u_debug.h" diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c index 8f729b565b..db3330bc40 100644 --- a/src/gallium/state_trackers/xorg/xorg_renderer.c +++ b/src/gallium/state_trackers/xorg/xorg_renderer.c @@ -5,7 +5,6 @@ #include "cso_cache/cso_context.h" #include "util/u_draw_quad.h" -#include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_rect.h" diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c index 7bcf77e1d3..a3bcd7cb4c 100644 --- a/src/gallium/state_trackers/xorg/xorg_xv.c +++ b/src/gallium/state_trackers/xorg/xorg_xv.c @@ -12,8 +12,6 @@ #include "pipe/p_screen.h" -#include "util/u_format.h" - /*XXX get these from pipe's texture limits */ #define IMAGE_MAX_WIDTH 2048 #define IMAGE_MAX_HEIGHT 2048 -- cgit v1.2.3 From 17330479b39409a63a06ec9e6b0f8e28b585db12 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 27 Jan 2010 23:51:54 +0800 Subject: egl: eglMakeCurrent should accept an uninitialized display. When no context or surface are given, the display is allowed to be uninitialized. Most drivers cannot handle an uninitialized display. But they are updated to at least throw a fatal message. --- src/egl/drivers/glx/egl_glx.c | 64 +++++++++++-------------- src/egl/drivers/xdri/egl_xdri.c | 53 ++++++++++++++------ src/egl/main/eglapi.c | 18 +++++-- src/egl/main/eglapi.h | 1 + src/egl/main/eglcontext.c | 23 +++++---- src/gallium/state_trackers/egl/common/egl_g3d.c | 40 ++++++++++++---- 6 files changed, 124 insertions(+), 75 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index 89a4353f8a..5efb72e875 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -103,6 +103,8 @@ struct GLX_egl_surface Drawable drawable; GLXDrawable glx_drawable; + + void (*destroy)(Display *, GLXDrawable); }; @@ -630,6 +632,21 @@ GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, } +/** + * Destroy a surface. The display is allowed to be uninitialized. + */ +static void +destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) +{ + struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf); + + if (GLX_surf->destroy) + GLX_surf->destroy(disp->NativeDisplay, GLX_surf->glx_drawable); + + free(GLX_surf); +} + + /** * Called via eglMakeCurrent(), drv->API.MakeCurrent(). */ @@ -712,6 +729,9 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, return NULL; } + if (GLX_dpy->have_1_3 && !GLX_dpy->glx_window_quirk) + GLX_surf->destroy = glXDestroyWindow; + get_drawable_size(GLX_dpy->dpy, window, &width, &height); GLX_surf->Base.Width = width; GLX_surf->Base.Height = height; @@ -769,6 +789,9 @@ GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, return NULL; } + GLX_surf->destroy = (GLX_dpy->have_1_3) ? + glXDestroyPixmap : glXDestroyGLXPixmap; + get_drawable_size(GLX_dpy->dpy, pixmap, &width, &height); GLX_surf->Base.Width = width; GLX_surf->Base.Height = height; @@ -833,47 +856,18 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, return NULL; } + GLX_surf->destroy = (GLX_dpy->have_1_3) ? + glXDestroyPbuffer : GLX_dpy->glXDestroyGLXPbufferSGIX; + return &GLX_surf->Base; } + static EGLBoolean GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) { - struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); - if (!_eglIsSurfaceBound(surf)) { - struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf); - - if (GLX_dpy->have_1_3) { - switch (surf->Type) { - case EGL_WINDOW_BIT: - if (!GLX_dpy->glx_window_quirk) - glXDestroyWindow(GLX_dpy->dpy, GLX_surf->glx_drawable); - break; - case EGL_PBUFFER_BIT: - glXDestroyPbuffer(GLX_dpy->dpy, GLX_surf->glx_drawable); - break; - case EGL_PIXMAP_BIT: - glXDestroyPixmap(GLX_dpy->dpy, GLX_surf->glx_drawable); - break; - default: - break; - } - } - else { - switch (surf->Type) { - case EGL_PBUFFER_BIT: - GLX_dpy->glXDestroyGLXPbufferSGIX(GLX_dpy->dpy, - GLX_surf->glx_drawable); - break; - case EGL_PIXMAP_BIT: - glXDestroyGLXPixmap(GLX_dpy->dpy, GLX_surf->glx_drawable); - break; - default: - break; - } - } - free(surf); - } + if (!_eglIsSurfaceBound(surf)) + destroy_surface(disp, surf); return EGL_TRUE; } diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index e13d884e71..26fe95b043 100644 --- a/src/egl/drivers/xdri/egl_xdri.c +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -419,19 +419,47 @@ xdri_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, } -static EGLBoolean -xdri_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) +/** + * 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); - if (!_eglIsContextBound(ctx)) { - xdri_ctx->driContext->destroyContext(xdri_ctx->driContext, - xdri_dpy->psc, xdri_dpy->dpy); - free(xdri_ctx->dummy_gc); - free(xdri_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; } @@ -539,13 +567,8 @@ xdri_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf static EGLBoolean xdri_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface) { - struct xdri_egl_surface *xdri_surf = lookup_surface(surface); - - if (!_eglIsSurfaceBound(&xdri_surf->Base)) { - xdri_surf->driDrawable->destroyDrawable(xdri_surf->driDrawable); - free(xdri_surf); - } - + if (!_eglIsSurfaceBound(surface)) + destroy_surface(dpy, surface); return EGL_TRUE; } diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 2c26dfada8..d0f9749f84 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -394,9 +394,19 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, _EGLSurface *read_surf = _eglLookupSurface(read, disp); _EGLDriver *drv; - drv = _eglCheckDisplay(disp, __FUNCTION__); + if (!disp) + return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); + drv = disp->Driver; + + /* display is allowed to be uninitialized under certain condition */ + if (!disp->Initialized) { + if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE || + ctx != EGL_NO_CONTEXT) + return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); + } if (!drv) - return EGL_FALSE; + return EGL_TRUE; + if (!context && ctx != EGL_NO_CONTEXT) return _eglError(EGL_BAD_CONTEXT, __FUNCTION__); if ((!draw_surf && draw != EGL_NO_SURFACE) || @@ -994,9 +1004,7 @@ eglReleaseThread(void) if (ctx) { _EGLDisplay *disp = ctx->Resource.Display; _EGLDriver *drv = disp->Driver; - /* what if display is not initialized? */ - if (disp->Initialized) - (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); + (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); } } } diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index db31c7cf93..a7600820f3 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -23,6 +23,7 @@ typedef EGLBoolean (*GetConfigAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLC /* context funcs */ typedef _EGLContext *(*CreateContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, _EGLContext *share_list, const EGLint *attrib_list); typedef EGLBoolean (*DestroyContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx); +/* this is the only function (other than Initialize) that may be called with an uninitialized display */ typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx); typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value); diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index 4a9a47204c..60d2efd44b 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -321,16 +321,19 @@ _eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, if (!_eglBindContext(&ctx, &draw, &read)) return EGL_FALSE; - /* avoid double destroy */ - if (read && read == draw) - read = NULL; - - if (ctx && !_eglIsContextLinked(ctx)) - drv->API.DestroyContext(drv, dpy, ctx); - if (draw && !_eglIsSurfaceLinked(draw)) - drv->API.DestroySurface(drv, dpy, draw); - if (read && !_eglIsSurfaceLinked(read)) - drv->API.DestroySurface(drv, dpy, read); + /* nothing we can do if the display is uninitialized */ + if (dpy->Initialized) { + /* avoid double destroy */ + if (read && read == draw) + read = NULL; + + if (ctx && !_eglIsContextLinked(ctx)) + drv->API.DestroyContext(drv, dpy, ctx); + if (draw && !_eglIsSurfaceLinked(draw)) + drv->API.DestroySurface(drv, dpy, draw); + if (read && !_eglIsSurfaceLinked(read)) + drv->API.DestroySurface(drv, dpy, read); + } return EGL_TRUE; } diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index aa4f012216..657c771a6b 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -672,21 +672,30 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, return &gctx->base; } -static EGLBoolean -egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) +/** + * Destroy a context. + */ +static void +destroy_context(_EGLDisplay *dpy, _EGLContext *ctx) { struct egl_g3d_context *gctx = egl_g3d_context(ctx); - if (_eglIsContextBound(&gctx->base)) - return EGL_TRUE; + /* FIXME a context might live longer than its display */ + if (!dpy->Initialized) + _eglLog(_EGL_FATAL, "destroy a context with an unitialized display"); egl_g3d_realloc_context(dpy, &gctx->base); - - /* it will destroy pipe context */ + /* it will destroy the associated pipe context */ gctx->stapi->st_destroy_context(gctx->st_ctx); free(gctx); +} +static EGLBoolean +egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) +{ + if (!_eglIsContextBound(ctx)) + destroy_context(dpy, ctx); return EGL_TRUE; } @@ -817,17 +826,28 @@ egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, return &gsurf->base; } -static EGLBoolean -egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) +/** + * Destroy a surface. + */ +static void +destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf) { struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - if (_eglIsSurfaceBound(&gsurf->base)) - return EGL_TRUE; + /* FIXME a surface might live longer than its display */ + if (!dpy->Initialized) + _eglLog(_EGL_FATAL, "destroy a surface with an unitialized display"); pipe_surface_reference(&gsurf->render_surface, NULL); gsurf->native->destroy(gsurf->native); free(gsurf); +} + +static EGLBoolean +egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) +{ + if (!_eglIsSurfaceBound(surf)) + destroy_surface(dpy, surf); return EGL_TRUE; } -- cgit v1.2.3 From 6baa2c8d022e5dd1e305e7da2925c1e6f9370f35 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 28 Jan 2010 16:57:49 +0800 Subject: egl: Migrate drivers to use _eglBindContext. _eglMakeCurrent is a big hammer that is not easy to use. Migrate drivers to use _eglBindContext and un-export _eglMakeCurrent. --- src/egl/drivers/glx/egl_glx.c | 20 ++++++++++++++++---- src/egl/drivers/xdri/egl_xdri.c | 21 ++++++++++++--------- src/egl/main/eglcontext.c | 23 ++--------------------- src/egl/main/eglcontext.h | 2 +- src/gallium/state_trackers/egl/common/egl_g3d.c | 21 +++++++++++---------- 5 files changed, 42 insertions(+), 45 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index 5efb72e875..1c38db6491 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -660,8 +660,10 @@ GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, struct GLX_egl_context *GLX_ctx = GLX_egl_context(ctx); GLXDrawable ddraw, rdraw; GLXContext cctx; + EGLBoolean ret = EGL_FALSE; - if (!_eglMakeCurrent(drv, disp, dsurf, rsurf, ctx)) + /* bind the new context and return the "orphaned" one */ + if (!_eglBindContext(&ctx, &dsurf, &rsurf)) return EGL_FALSE; ddraw = (GLX_dsurf) ? GLX_dsurf->glx_drawable : None; @@ -669,11 +671,21 @@ GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, cctx = (GLX_ctx) ? GLX_ctx->context : NULL; if (GLX_dpy->have_make_current_read) - return glXMakeContextCurrent(GLX_dpy->dpy, ddraw, rdraw, cctx); + ret = glXMakeContextCurrent(GLX_dpy->dpy, ddraw, rdraw, cctx); else if (ddraw == rdraw) - return glXMakeCurrent(GLX_dpy->dpy, ddraw, cctx); + ret = glXMakeCurrent(GLX_dpy->dpy, ddraw, cctx); - return EGL_FALSE; + if (ret) { + if (dsurf && !_eglIsSurfaceLinked(dsurf)) + destroy_surface(disp, dsurf); + if (rsurf && rsurf != dsurf && !_eglIsSurfaceLinked(rsurf)) + destroy_surface(disp, rsurf); + } + else { + _eglBindContext(&ctx, &dsurf, &rsurf); + } + + return ret; } /** Get size of given window */ diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index 26fe95b043..2ca9ea8a5b 100644 --- a/src/egl/drivers/xdri/egl_xdri.c +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -475,17 +475,13 @@ xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d, 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); - _EGLContext *old = _eglGetCurrentContext(); - /* an unlinked context will be invalid after context switch */ - if (!_eglIsContextLinked(old)) - old = NULL; - - if (!_eglMakeCurrent(drv, dpy, d, r, context)) + /* bind the new context and return the "orphaned" one */ + if (!_eglBindContext(&context, &d, &r)) return EGL_FALSE; /* flush before context switch */ - if (old && old != context && xdri_driver->FlushCurrentContext) + if (context && xdri_driver->FlushCurrentContext) xdri_driver->FlushCurrentContext(); /* the symbol is defined in libGL.so */ @@ -498,11 +494,18 @@ xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d, return EGL_FALSE; } } - else if (old) { - xdri_ctx = lookup_context(old); + 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; } diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index 60d2efd44b..4496f76ece 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -310,32 +310,13 @@ _eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read) /** - * Drivers will typically call this to do the error checking and - * update the various flags. - * Then, the driver will do its device-dependent Make-Current stuff. + * Just a placeholder/demo function. Drivers should override this. */ EGLBoolean _eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx) { - if (!_eglBindContext(&ctx, &draw, &read)) - return EGL_FALSE; - - /* nothing we can do if the display is uninitialized */ - if (dpy->Initialized) { - /* avoid double destroy */ - if (read && read == draw) - read = NULL; - - if (ctx && !_eglIsContextLinked(ctx)) - drv->API.DestroyContext(drv, dpy, ctx); - if (draw && !_eglIsSurfaceLinked(draw)) - drv->API.DestroySurface(drv, dpy, draw); - if (read && !_eglIsSurfaceLinked(read)) - drv->API.DestroySurface(drv, dpy, read); - } - - return EGL_TRUE; + return EGL_FALSE; } diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h index 84d8deed51..4811e3bb7a 100644 --- a/src/egl/main/eglcontext.h +++ b/src/egl/main/eglcontext.h @@ -51,7 +51,7 @@ PUBLIC EGLBoolean _eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read); -PUBLIC EGLBoolean +extern EGLBoolean _eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx); diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index 657c771a6b..f8334217c4 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -856,18 +856,14 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx) { struct egl_g3d_context *gctx = egl_g3d_context(ctx); + struct egl_g3d_surface *gdraw = egl_g3d_surface(draw); struct egl_g3d_context *old_gctx; - EGLint api; EGLBoolean ok = EGL_TRUE; - /* find the old context */ - api = (gctx) ? gctx->base.ClientAPI : eglQueryAPI(); - old_gctx = egl_g3d_get_current_context(api); - if (old_gctx && !_eglIsContextLinked(&old_gctx->base)) - old_gctx = NULL; - - if (!_eglMakeCurrent(drv, dpy, draw, read, ctx)) + /* bind the new context and return the "orphaned" one */ + if (!_eglBindContext(&ctx, &draw, &read)) return EGL_FALSE; + old_gctx = egl_g3d_context(ctx); if (old_gctx) { /* flush old context */ @@ -883,8 +879,6 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy, } if (gctx) { - struct egl_g3d_surface *gdraw = egl_g3d_surface(draw); - ok = egl_g3d_realloc_context(dpy, &gctx->base); if (ok) { ok = gctx->stapi->st_make_current(gctx->st_ctx, @@ -904,6 +898,13 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy, old_gctx->base.WindowRenderBuffer = EGL_NONE; } + if (ctx && !_eglIsContextLinked(ctx)) + destroy_context(dpy, ctx); + if (draw && !_eglIsSurfaceLinked(draw)) + destroy_surface(dpy, draw); + if (read && read != draw && !_eglIsSurfaceLinked(read)) + destroy_surface(dpy, read); + return ok; } -- cgit v1.2.3 From d96bb01d2db4d07ab7e4b6a50da2f96787180a4d Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 11 Jan 2010 20:50:57 +0100 Subject: regress: Fix shader header. --- .../state_trackers/python/tests/regress/fragment-shader/frag-slt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh index f2a1521cbf..d58b7886a1 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh @@ -1,4 +1,4 @@ -FRAG1.1 +FRAG DCL IN[0], COLOR, LINEAR DCL OUT[0], COLOR -- cgit v1.2.3 From 91d58c3520452798bd1542f86936e0f408182fbf Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 21 Jan 2010 20:02:44 +0100 Subject: python: Link to ws2_32 on windows. --- src/gallium/state_trackers/python/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript index 8498a90812..527e065cd9 100644 --- a/src/gallium/state_trackers/python/SConscript +++ b/src/gallium/state_trackers/python/SConscript @@ -21,6 +21,7 @@ if 'python' in env['statetrackers']: 'gdi32', 'user32', 'kernel32', + 'ws2_32', ]) else: env.Append(LIBS = [ -- cgit v1.2.3 From 4771e536e16699a0488b68e153de3478dfbc55d0 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 21 Jan 2010 20:03:13 +0100 Subject: regress: Add two-dimension constant buffer test. --- .../tests/regress/fragment-shader/frag-cb-2d.sh | 9 +++++ .../regress/fragment-shader/fragment-shader.py | 38 ++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh new file mode 100644 index 0000000000..f70a5146f4 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh @@ -0,0 +1,9 @@ +FRAG + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR +DCL CONST[1][1..2] + +MAD OUT[0], IN[0], CONST[1][2], CONST[1][1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py index 8d3bf9d4d7..6a0c1f824b 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py @@ -26,6 +26,7 @@ # ########################################################################## +import struct from gallium import * @@ -146,6 +147,42 @@ def test(dev, name): fs = Shader(file('frag-' + name + '.sh', 'rt').read()) ctx.set_fragment_shader(fs) + constbuf0 = dev.buffer_create(16, + (PIPE_BUFFER_USAGE_CONSTANT | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE), + 4 * 4 * 4) + + cbdata = '' + cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5) + cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5) + cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5) + cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5) + + constbuf0.write(cbdata, 0) + + ctx.set_constant_buffer(PIPE_SHADER_FRAGMENT, + 0, + constbuf0) + + constbuf1 = dev.buffer_create(64, + (PIPE_BUFFER_USAGE_CONSTANT | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE), + 4 * 4 * 4) + + cbdata = '' + cbdata += struct.pack('4f', 0.1, 0.1, 0.1, 0.1) + cbdata += struct.pack('4f', 0.25, 0.25, 0.25, 0.25) + cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5) + cbdata += struct.pack('4f', 0.75, 0.75, 0.75, 0.75) + + constbuf1.write(cbdata, 0) + + ctx.set_constant_buffer(PIPE_SHADER_FRAGMENT, + 1, + constbuf1) + xy = [ -0.8, -0.8, 0.8, -0.8, @@ -184,6 +221,7 @@ def main(): tests = [ 'abs', 'add', + 'cb-2d', 'dp3', 'dp4', 'dst', -- cgit v1.2.3 From 44ac4c4e2c7890236ee7e9cd0cf82b58710d57ef Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 22 Jan 2010 09:40:33 +0100 Subject: regress: Add fragment shader test for one-dimensional constant buffers. --- .../python/tests/regress/fragment-shader/frag-cb-1d.sh | 13 +++++++++++++ .../python/tests/regress/fragment-shader/fragment-shader.py | 11 ++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh new file mode 100644 index 0000000000..85fb9ea4e7 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh @@ -0,0 +1,13 @@ +FRAG + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR +DCL CONST[1] +DCL CONST[3] +DCL TEMP[0..1] + +ADD TEMP[0], IN[0], CONST[1] +RCP TEMP[1], CONST[3].xxxx +MUL OUT[0], TEMP[0], TEMP[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py index 6a0c1f824b..9e668d2ac6 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py @@ -147,17 +147,17 @@ def test(dev, name): fs = Shader(file('frag-' + name + '.sh', 'rt').read()) ctx.set_fragment_shader(fs) - constbuf0 = dev.buffer_create(16, + constbuf0 = dev.buffer_create(64, (PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE), 4 * 4 * 4) cbdata = '' - cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5) - cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5) - cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5) - cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5) + cbdata += struct.pack('4f', 0.4, 0.0, 0.0, 1.0) + cbdata += struct.pack('4f', 1.0, 1.0, 1.0, 1.0) + cbdata += struct.pack('4f', 2.0, 2.0, 2.0, 2.0) + cbdata += struct.pack('4f', 4.0, 8.0, 16.0, 32.0) constbuf0.write(cbdata, 0) @@ -221,6 +221,7 @@ def main(): tests = [ 'abs', 'add', + 'cb-1d', 'cb-2d', 'dp3', 'dp4', -- cgit v1.2.3 From 333c035a519a36efd19d2ab227924feb8b0f4c25 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 25 Jan 2010 12:42:17 +0100 Subject: regress: Add vertex shaders tests for constant buffers. --- .../tests/regress/vertex-shader/vert-cb-1d.sh | 16 +++++++++ .../tests/regress/vertex-shader/vert-cb-2d.sh | 12 +++++++ .../tests/regress/vertex-shader/vertex-shader.py | 40 ++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh create mode 100644 src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh new file mode 100644 index 0000000000..b41fe5dd38 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh @@ -0,0 +1,16 @@ +VERT + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR +DCL CONST[1] +DCL CONST[3] +DCL TEMP[0..1] + +MOV OUT[0], IN[0] +ADD TEMP[0], IN[1], CONST[1] +RCP TEMP[1], CONST[3].xxxx +MUL OUT[1], TEMP[0], TEMP[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh new file mode 100644 index 0000000000..45f5e6b729 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh @@ -0,0 +1,12 @@ +VERT + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR +DCL CONST[1][1..2] + +MOV OUT[0], IN[0] +MAD OUT[1], IN[1], CONST[1][2], CONST[1][1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py index 01bf5a3210..96503778ae 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py @@ -27,6 +27,8 @@ ########################################################################## +import struct + from gallium import * def make_image(surface): @@ -143,6 +145,42 @@ def test(dev, name): ''') ctx.set_fragment_shader(fs) + constbuf0 = dev.buffer_create(64, + (PIPE_BUFFER_USAGE_CONSTANT | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE), + 4 * 4 * 4) + + cbdata = '' + cbdata += struct.pack('4f', 0.4, 0.0, 0.0, 1.0) + cbdata += struct.pack('4f', 1.0, 1.0, 1.0, 1.0) + cbdata += struct.pack('4f', 2.0, 2.0, 2.0, 2.0) + cbdata += struct.pack('4f', 4.0, 8.0, 16.0, 32.0) + + constbuf0.write(cbdata, 0) + + ctx.set_constant_buffer(PIPE_SHADER_VERTEX, + 0, + constbuf0) + + constbuf1 = dev.buffer_create(64, + (PIPE_BUFFER_USAGE_CONSTANT | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE), + 4 * 4 * 4) + + cbdata = '' + cbdata += struct.pack('4f', 0.1, 0.1, 0.1, 0.1) + cbdata += struct.pack('4f', 0.25, 0.25, 0.25, 0.25) + cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5) + cbdata += struct.pack('4f', 0.75, 0.75, 0.75, 0.75) + + constbuf1.write(cbdata, 0) + + ctx.set_constant_buffer(PIPE_SHADER_VERTEX, + 1, + constbuf1) + xy = [ 0.0, 0.8, -0.2, 0.4, @@ -213,6 +251,8 @@ def main(): 'add', 'arl', 'arr', + 'cb-1d', + 'cb-2d', 'dp3', 'dp4', 'dst', -- cgit v1.2.3 From c75e238434f64657e96f09e0215f02cefa6ad6d6 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 28 Jan 2010 17:59:26 +0100 Subject: st/xorg: Update to new libkms interface but be backwards compatible --- src/gallium/state_trackers/xorg/xorg_crtc.c | 4 ++++ src/gallium/state_trackers/xorg/xorg_driver.c | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index 2786558b76..2395d54975 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -242,7 +242,11 @@ crtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image) unsigned attr[8]; attr[0] = KMS_BO_TYPE; +#ifdef KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8 + attr[1] = KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8; +#else attr[1] = KMS_BO_TYPE_CURSOR; +#endif attr[2] = KMS_WIDTH; attr[3] = 64; attr[4] = KMS_HEIGHT; diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index e4ad789e9b..f53a879a14 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -1008,7 +1008,11 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn) int ret; attr[0] = KMS_BO_TYPE; +#ifdef KMS_BO_TYPE_SCANOUT_X8R8G8B8 + attr[1] = KMS_BO_TYPE_SCANOUT_X8R8G8B8; +#else attr[1] = KMS_BO_TYPE_SCANOUT; +#endif attr[2] = KMS_WIDTH; attr[3] = pScrn->virtualX; attr[4] = KMS_HEIGHT; -- cgit v1.2.3 From 00e1790f3230de550121591d611b47da299ae15c Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sat, 30 Jan 2010 22:45:54 +0800 Subject: egl: Rename Binding to CurrentContext in _EGLSurface. A context can be bound to a surface just like it can be bound to a thread. CurrentContext is a more consistent name. --- src/egl/drivers/xdri/egl_xdri.c | 2 +- src/egl/main/eglcontext.c | 16 ++++++++-------- src/egl/main/eglsurface.h | 14 +++++++------- src/gallium/state_trackers/egl/common/egl_g3d.c | 4 ++-- 4 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index 10f7a31f5b..9c21576539 100644 --- a/src/egl/drivers/xdri/egl_xdri.c +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -600,7 +600,7 @@ xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw) struct xdri_egl_surface *xdri_surf = lookup_surface(draw); /* swapBuffers does not flush commands */ - if (draw->Binding && xdri_driver->FlushCurrentContext) + if (draw->CurrentContext && xdri_driver->FlushCurrentContext) xdri_driver->FlushCurrentContext(); xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable, 0, 0, 0); diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index ee9d60e17a..37c4b25b68 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -150,13 +150,13 @@ _eglBindContextToSurfaces(_EGLContext *ctx, { _EGLSurface *newDraw = *draw, *newRead = *read; - if (newDraw->Binding) - newDraw->Binding->DrawSurface = NULL; - newDraw->Binding = ctx; + if (newDraw->CurrentContext) + newDraw->CurrentContext->DrawSurface = NULL; + newDraw->CurrentContext = ctx; - if (newRead->Binding) - newRead->Binding->ReadSurface = NULL; - newRead->Binding = ctx; + if (newRead->CurrentContext) + newRead->CurrentContext->ReadSurface = NULL; + newRead->CurrentContext = ctx; if (ctx) { *draw = ctx->DrawSurface; @@ -238,8 +238,8 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) * * The latter is more restrictive so we can check only the latter case. */ - if ((draw->Binding && draw->Binding != ctx) || - (read->Binding && read->Binding != ctx)) + if ((draw->CurrentContext && draw->CurrentContext != ctx) || + (read->CurrentContext && read->CurrentContext != ctx)) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); /* simply require the configs to be equal */ diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h index 4062b990fa..eee66f6d86 100644 --- a/src/egl/main/eglsurface.h +++ b/src/egl/main/eglsurface.h @@ -14,9 +14,8 @@ struct _egl_surface /* A surface is a display resource */ _EGLResource Resource; - /* The bound status of the surface */ - _EGLContext *Binding; - EGLBoolean BoundToTexture; + /* The context that is currently bound to the surface */ + _EGLContext *CurrentContext; _EGLConfig *Config; @@ -26,6 +25,9 @@ struct _egl_surface EGLint MipmapTexture, MipmapLevel; EGLint SwapInterval; + /* True if the surface is bound to an OpenGL ES texture */ + EGLBoolean BoundToTexture; + /* If type == EGL_SCREEN_BIT: */ EGLint VisibleRefCount; /* number of screens I'm displayed on */ @@ -100,14 +102,12 @@ _eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy, /** - * Return true if the surface is bound to a thread. - * A surface bound to a texutre is not considered bound by - * this function. + * Return true if there is a context bound to the surface. */ static INLINE EGLBoolean _eglIsSurfaceBound(_EGLSurface *surf) { - return (surf->Binding != NULL); + return (surf->CurrentContext != NULL); } diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index f8334217c4..3f520851c4 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -1129,8 +1129,8 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, } /* flush properly if the surface is bound */ - if (gsurf->base.Binding) { - gctx = egl_g3d_context(gsurf->base.Binding); + if (gsurf->base.CurrentContext) { + gctx = egl_g3d_context(gsurf->base.CurrentContext); gctx->stapi->st_flush(gctx->st_ctx, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); } -- cgit v1.2.3 From 5714e674c75652c195482a8e607a2d624a5e524e Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sat, 30 Jan 2010 23:13:18 +0800 Subject: st/egl: eglBindTexImage should bind to an OpenGL ES texture. The spec says that it only works with OpenGL ES. --- src/gallium/state_trackers/egl/common/egl_g3d.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index 3f520851c4..f4c4032086 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -1135,8 +1135,7 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); } - /* XXX change to EGL_OPENGL_ES_API once OpenGL ES is merged */ - gctx = egl_g3d_get_current_context(EGL_OPENGL_API); + gctx = egl_g3d_get_current_context(EGL_OPENGL_ES_API); if (gctx) { if (!gsurf->render_surface) return EGL_FALSE; @@ -1163,9 +1162,8 @@ egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, if (gsurf->render_surface) { _EGLThreadInfo *t = _eglGetCurrentThread(); - /* XXX change to EGL_OPENGL_ES_API once OpenGL ES is merged */ struct egl_g3d_context *gctx = egl_g3d_context( - t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_API)]); + t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_ES_API)]); /* what if the context the surface binds to is no longer current? */ if (gctx) -- cgit v1.2.3 From 6d12c7083e81625e1468351ef5e24e9168f0d549 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sun, 31 Jan 2010 01:18:18 +0800 Subject: st/egl: Remove egl_g3d_get_current_context. There is now _eglGetAPIContext that can return the current context of the given API. --- src/gallium/state_trackers/egl/common/egl_g3d.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index f4c4032086..e8f46e56bc 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -243,17 +243,6 @@ egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx) return EGL_TRUE; } -/** - * Return the current context of the given API. - */ -static struct egl_g3d_context * -egl_g3d_get_current_context(EGLint api) -{ - _EGLThreadInfo *t = _eglGetCurrentThread(); - EGLint api_index = _eglConvertApiToIndex(api); - return egl_g3d_context(t->CurrentContexts[api_index]); -} - /** * Return the state tracker for the given context. */ @@ -1098,7 +1087,8 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer) { struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - struct egl_g3d_context *gctx; + _EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API); + struct egl_g3d_context *gctx = egl_g3d_context(ctx); enum pipe_format target_format; int target; @@ -1135,7 +1125,6 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); } - gctx = egl_g3d_get_current_context(EGL_OPENGL_ES_API); if (gctx) { if (!gsurf->render_surface) return EGL_FALSE; @@ -1161,9 +1150,8 @@ egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage"); if (gsurf->render_surface) { - _EGLThreadInfo *t = _eglGetCurrentThread(); - struct egl_g3d_context *gctx = egl_g3d_context( - t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_ES_API)]); + _EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API); + struct egl_g3d_context *gctx = egl_g3d_context(ctx); /* what if the context the surface binds to is no longer current? */ if (gctx) -- cgit v1.2.3 From 66f0517695668ba9a30618015a94bfea4ba08a9b Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sun, 31 Jan 2010 01:25:59 +0800 Subject: st/egl: Do not ignore configs without a renderable type. Configs without a renderable type are still informative for programs such as eglinfo. --- src/gallium/state_trackers/egl/common/egl_g3d.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index e8f46e56bc..6c8f3b9f79 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -464,18 +464,18 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) struct egl_g3d_config *gconf; EGLBoolean valid; + gconf = CALLOC_STRUCT(egl_g3d_config); + if (!gconf) + continue; + + _eglInitConfig(&gconf->base, id); + api_mask = get_mode_api_mask(&native_configs[i]->mode, gdrv->api_mask); if (!api_mask) { _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x", native_configs[i]->mode.visualID); - continue; } - gconf = CALLOC_STRUCT(egl_g3d_config); - if (!gconf) - continue; - - _eglInitConfig(&gconf->base, id); valid = _eglConfigFromContextModesRec(&gconf->base, &native_configs[i]->mode, api_mask, api_mask); if (valid) { -- cgit v1.2.3