From 53db19b57d41a5e6beea5cb5dff4f7f638ca7b50 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 24 Aug 2009 10:50:07 -0600 Subject: mesa: _mesa_layout_parameters() returns a boolean value --- src/mesa/shader/prog_parameter_layout.c | 12 ++++++++---- src/mesa/shader/prog_parameter_layout.h | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/shader/prog_parameter_layout.c b/src/mesa/shader/prog_parameter_layout.c index 8f2b306220..1c37b3a7a5 100644 --- a/src/mesa/shader/prog_parameter_layout.c +++ b/src/mesa/shader/prog_parameter_layout.c @@ -106,7 +106,11 @@ copy_indirect_accessed_array(struct gl_program_parameter_list *src, } -int +/** + * XXX description??? + * \return GL_TRUE for success, GL_FALSE for failure + */ +GLboolean _mesa_layout_parameters(struct asm_parser_state *state) { struct gl_program_parameter_list *layout; @@ -128,12 +132,12 @@ _mesa_layout_parameters(struct asm_parser_state *state) */ if (!inst->SrcReg[i].Symbol->pass1_done) { const int new_begin = - copy_indirect_accessed_array(state->prog->Parameters, layout, + copy_indirect_accessed_array(state->prog->Parameters, layout, inst->SrcReg[i].Symbol->param_binding_begin, inst->SrcReg[i].Symbol->param_binding_length); if (new_begin < 0) { - return 0; + return GL_FALSE; } inst->SrcReg[i].Symbol->param_binding_begin = new_begin; @@ -209,5 +213,5 @@ _mesa_layout_parameters(struct asm_parser_state *state) _mesa_free_parameter_list(state->prog->Parameters); state->prog->Parameters = layout; - return 1; + return GL_TRUE; } diff --git a/src/mesa/shader/prog_parameter_layout.h b/src/mesa/shader/prog_parameter_layout.h index 1686170bab..99a7b6c726 100644 --- a/src/mesa/shader/prog_parameter_layout.h +++ b/src/mesa/shader/prog_parameter_layout.h @@ -36,6 +36,7 @@ extern unsigned _mesa_combine_swizzles(unsigned base, unsigned applied); struct asm_parser_state; -extern int _mesa_layout_parameters(struct asm_parser_state *state); + +extern GLboolean _mesa_layout_parameters(struct asm_parser_state *state); #endif /* PROG_PARAMETER_LAYOUT_H */ -- cgit v1.2.3 From 99939982ec76cb1fee84da9027375c55888dca20 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 10 Jul 2009 15:21:42 +0800 Subject: glapi: Protect _glapi_check_multithread by a mutex. Multiple threads might call _glapi_check_multithread at roughly the same time. It is possbile that all of them are wrongly regarded as firstCall if there is no mutex. This bug causes xeglthreads to crash sometimes. Acked-by: Ian Romanick Signed-off-by: Chia-I Wu --- src/mesa/glapi/glapi.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c index 2b105d0f17..30aec209e7 100644 --- a/src/mesa/glapi/glapi.c +++ b/src/mesa/glapi/glapi.c @@ -198,6 +198,7 @@ PUBLIC const void *_glapi_Context = NULL; #if defined(THREADS) +_glthread_DECLARE_STATIC_MUTEX(ThreadCheckMutex); static GLboolean ThreadSafe = GL_FALSE; /**< In thread-safe mode? */ _glthread_TSD _gl_DispatchTSD; /**< Per-thread dispatch pointer */ static _glthread_TSD ContextTSD; /**< Per-thread context pointer */ @@ -231,23 +232,23 @@ void _glapi_check_multithread(void) { #if defined(THREADS) && !defined(GLX_USE_TLS) - if (!ThreadSafe) { - static unsigned long knownID; - static GLboolean firstCall = GL_TRUE; - if (firstCall) { - knownID = _glthread_GetID(); - firstCall = GL_FALSE; - } - else if (knownID != _glthread_GetID()) { - ThreadSafe = GL_TRUE; - _glapi_set_dispatch(NULL); - _glapi_set_context(NULL); - } + static unsigned long knownID; + static GLboolean firstCall = GL_TRUE; + + if (ThreadSafe) + return; + + _glthread_LOCK_MUTEX(ThreadCheckMutex); + if (firstCall) { + knownID = _glthread_GetID(); + firstCall = GL_FALSE; } - else if (!_glapi_get_dispatch()) { - /* make sure that this thread's dispatch pointer isn't null */ + else if (knownID != _glthread_GetID()) { + ThreadSafe = GL_TRUE; _glapi_set_dispatch(NULL); + _glapi_set_context(NULL); } + _glthread_UNLOCK_MUTEX(ThreadCheckMutex); #endif } -- cgit v1.2.3 From fc2feea685d86c520fb01199caa5a46eae20c7aa Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 10 Jul 2009 17:35:11 +0800 Subject: glapi: Fix a race in accessing context/dispatch TSD. If multiple threads set/get a TSD at roughly same time for the first time, glthread might (wrongly) initialize it more than once. This patch solves the race by initializing context/dispatch TSDs early. Acked-by: Ian Romanick Signed-off-by: Chia-I Wu --- src/mesa/glapi/glapi.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c index 30aec209e7..b9ab9c07be 100644 --- a/src/mesa/glapi/glapi.c +++ b/src/mesa/glapi/glapi.c @@ -240,6 +240,10 @@ _glapi_check_multithread(void) _glthread_LOCK_MUTEX(ThreadCheckMutex); if (firstCall) { + /* initialize TSDs */ + (void) _glthread_GetTSD(&ContextTSD); + (void) _glthread_GetTSD(&_gl_DispatchTSD); + knownID = _glthread_GetID(); firstCall = GL_FALSE; } -- cgit v1.2.3 From 3076d1617db67d49ff773096123c1fa47af58272 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 14 Jul 2009 13:17:25 +0800 Subject: glapi: Static mutex does not work on WIN32_THREADS. This re-introduces the race in _glapi_check_multithread, but avoids a crash on windows. Signed-off-by: Chia-I Wu --- src/mesa/glapi/glapi.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c index b9ab9c07be..e36fccb354 100644 --- a/src/mesa/glapi/glapi.c +++ b/src/mesa/glapi/glapi.c @@ -198,7 +198,16 @@ PUBLIC const void *_glapi_Context = NULL; #if defined(THREADS) +#ifdef WIN32_THREADS +/* _glthread_DECLARE_STATIC_MUTEX is broken on windows. There will be race! */ +#define CHECK_MULTITHREAD_LOCK() +#define CHECK_MULTITHREAD_UNLOCK() +#else _glthread_DECLARE_STATIC_MUTEX(ThreadCheckMutex); +#define CHECK_MULTITHREAD_LOCK() _glthread_LOCK_MUTEX(ThreadCheckMutex) +#define CHECK_MULTITHREAD_UNLOCK() _glthread_UNLOCK_MUTEX(ThreadCheckMutex) +#endif + static GLboolean ThreadSafe = GL_FALSE; /**< In thread-safe mode? */ _glthread_TSD _gl_DispatchTSD; /**< Per-thread dispatch pointer */ static _glthread_TSD ContextTSD; /**< Per-thread context pointer */ @@ -238,7 +247,7 @@ _glapi_check_multithread(void) if (ThreadSafe) return; - _glthread_LOCK_MUTEX(ThreadCheckMutex); + CHECK_MULTITHREAD_LOCK(); if (firstCall) { /* initialize TSDs */ (void) _glthread_GetTSD(&ContextTSD); @@ -252,7 +261,7 @@ _glapi_check_multithread(void) _glapi_set_dispatch(NULL); _glapi_set_context(NULL); } - _glthread_UNLOCK_MUTEX(ThreadCheckMutex); + CHECK_MULTITHREAD_UNLOCK(); #endif } -- cgit v1.2.3 From 17090cf3efb0db8fa01b502a9c0df27cbd1a67da Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 10 Jul 2009 15:28:55 +0800 Subject: glapi: Fix a possible race in getting current context/dispatch. There is a possbile race that _glapi_Context is reset by another thread after it is tested in GET_CURRENT_CONTEXT but before it is returned. We definitely do not want a lock here to solve the race. To have correct results even under a race, no other threads should reset _glapi_Context (or _glapi_Dispatch). This patch adds a new global variable _glapi_SingleThreaded. Since _glapi_Context or _glapi_Dispatch are no longer reset, _glapi_SingleThreaded is tested instead, before accessing them. DRI drivers compiled with this patch applied will not work with existing libGL.so because of the missing new symbol. If this turns out to be a real problem, this patch should be reverted. Signed-off-by: Chia-I Wu --- src/mesa/glapi/glapi.c | 75 +++++++++++++++++++++++------------------------ src/mesa/glapi/glapi.h | 5 +++- src/mesa/glapi/glthread.h | 2 +- 3 files changed, 41 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c index e36fccb354..4bb10df1d8 100644 --- a/src/mesa/glapi/glapi.c +++ b/src/mesa/glapi/glapi.c @@ -160,26 +160,20 @@ static GLint NoOpUnused(void) * the variables \c _glapi_Dispatch and \c _glapi_Context are used for this * purpose. * - * In the "normal" threaded case, the variables \c _glapi_Dispatch and - * \c _glapi_Context will be \c NULL if an application is detected as being - * multithreaded. Single-threaded applications will use \c _glapi_Dispatch - * and \c _glapi_Context just like the case without any threading support. - * When \c _glapi_Dispatch and \c _glapi_Context are \c NULL, the thread state - * data \c _gl_DispatchTSD and \c ContextTSD are used. Drivers and the - * static dispatch functions access these variables via \c _glapi_get_dispatch - * and \c _glapi_get_context. + * In the "normal" threaded case, the variable \c _glapi_SingleThreaded will be + * \c GL_FALSE if an application is detected as being multithreaded. + * Single-threaded applications will use \c _glapi_Dispatch and \c + * _glapi_Context just like the case without any threading support. When \c + * _glapi_SingleThreaded is \c GL_FALSE, the thread state data \c + * _gl_DispatchTSD and \c ContextTSD are used. Drivers and the static dispatch + * functions access these variables via \c _glapi_get_dispatch and \c + * _glapi_get_context. * - * There is a race condition in setting \c _glapi_Dispatch to \c NULL. It is - * possible for the original thread to be setting it at the same instant a new - * thread, perhaps running on a different processor, is clearing it. Because - * of that, \c ThreadSafe, which can only ever be changed to \c GL_TRUE, is - * used to determine whether or not the application is multithreaded. - * * In the TLS case, the variables \c _glapi_Dispatch and \c _glapi_Context are * hardcoded to \c NULL. Instead the TLS variables \c _glapi_tls_Dispatch and - * \c _glapi_tls_Context are used. Having \c _glapi_Dispatch and - * \c _glapi_Context be hardcoded to \c NULL maintains binary compatability - * between TLS enabled loaders and non-TLS DRI drivers. + * \c _glapi_tls_Context are used. The variable \c _glapi_SingleThreaded, + * though not used, is defined and hardcoded to \c GL_FALSE to maintain binary + * compatability between TLS enabled loaders and non-TLS DRI drivers. */ /*@{*/ #if defined(GLX_USE_TLS) @@ -194,6 +188,9 @@ PUBLIC __thread void * _glapi_tls_Context PUBLIC const struct _glapi_table *_glapi_Dispatch = NULL; PUBLIC const void *_glapi_Context = NULL; +/* Unused, but maintain binary compatability with non-TLS DRI drivers */ +GLboolean _glapi_SingleThreaded = GL_FALSE; + #else #if defined(THREADS) @@ -208,9 +205,9 @@ _glthread_DECLARE_STATIC_MUTEX(ThreadCheckMutex); #define CHECK_MULTITHREAD_UNLOCK() _glthread_UNLOCK_MUTEX(ThreadCheckMutex) #endif -static GLboolean ThreadSafe = GL_FALSE; /**< In thread-safe mode? */ -_glthread_TSD _gl_DispatchTSD; /**< Per-thread dispatch pointer */ -static _glthread_TSD ContextTSD; /**< Per-thread context pointer */ +GLboolean _glapi_SingleThreaded = GL_TRUE; /**< In single-thread mode? */ +_glthread_TSD _gl_DispatchTSD; /**< Per-thread dispatch pointer */ +static _glthread_TSD ContextTSD; /**< Per-thread context pointer */ #if defined(WIN32_THREADS) void FreeTSD(_glthread_TSD *p); @@ -244,7 +241,7 @@ _glapi_check_multithread(void) static unsigned long knownID; static GLboolean firstCall = GL_TRUE; - if (ThreadSafe) + if (!_glapi_SingleThreaded) return; CHECK_MULTITHREAD_LOCK(); @@ -257,9 +254,12 @@ _glapi_check_multithread(void) firstCall = GL_FALSE; } else if (knownID != _glthread_GetID()) { - ThreadSafe = GL_TRUE; - _glapi_set_dispatch(NULL); - _glapi_set_context(NULL); + /* + * switch to thread-safe mode. _glapi_Context and _glapi_Dispatch are no + * longer accessed after this point, except for raced by the first + * thread. Because of the race, they cannot be reset to NULL. + */ + _glapi_SingleThreaded = GL_FALSE; } CHECK_MULTITHREAD_UNLOCK(); #endif @@ -279,8 +279,10 @@ _glapi_set_context(void *context) #if defined(GLX_USE_TLS) _glapi_tls_Context = context; #elif defined(THREADS) + if (_glapi_SingleThreaded) + _glapi_Context = context; + /* always update TSD because we might switch to it at any time */ _glthread_SetTSD(&ContextTSD, context); - _glapi_Context = (ThreadSafe) ? NULL : context; #else _glapi_Context = context; #endif @@ -299,12 +301,8 @@ _glapi_get_context(void) #if defined(GLX_USE_TLS) return _glapi_tls_Context; #elif defined(THREADS) - if (ThreadSafe) { - return _glthread_GetTSD(&ContextTSD); - } - else { - return _glapi_Context; - } + return (_glapi_SingleThreaded) + ? _glapi_Context : _glthread_GetTSD(&ContextTSD); #else return _glapi_Context; #endif @@ -519,8 +517,9 @@ _glapi_set_dispatch(struct _glapi_table *dispatch) #if defined(GLX_USE_TLS) _glapi_tls_Dispatch = dispatch; #elif defined(THREADS) + if (_glapi_SingleThreaded) + _glapi_Dispatch = dispatch; _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch); - _glapi_Dispatch = (ThreadSafe) ? NULL : dispatch; #else /*THREADS*/ _glapi_Dispatch = dispatch; #endif /*THREADS*/ @@ -534,17 +533,15 @@ _glapi_set_dispatch(struct _glapi_table *dispatch) PUBLIC struct _glapi_table * _glapi_get_dispatch(void) { - struct _glapi_table * api; #if defined(GLX_USE_TLS) - api = _glapi_tls_Dispatch; + return _glapi_tls_Dispatch; #elif defined(THREADS) - api = (ThreadSafe) - ? (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD) - : _glapi_Dispatch; + return (_glapi_SingleThreaded) + ? _glapi_Dispatch + : (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD); #else - api = _glapi_Dispatch; + return _glapi_Dispatch; #endif - return api; } diff --git a/src/mesa/glapi/glapi.h b/src/mesa/glapi/glapi.h index 8f2cf66218..b2a1fe6ee9 100644 --- a/src/mesa/glapi/glapi.h +++ b/src/mesa/glapi/glapi.h @@ -94,7 +94,10 @@ extern void *_glapi_Context; extern struct _glapi_table *_glapi_Dispatch; # ifdef THREADS -# define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context()) +/* this variable is here only for quick access to current context/dispatch */ +extern GLboolean _glapi_SingleThreaded; +# define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) \ + ((_glapi_SingleThreaded) ? _glapi_Context : _glapi_get_context()) # else # define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) _glapi_Context # endif diff --git a/src/mesa/glapi/glthread.h b/src/mesa/glapi/glthread.h index 8ec933a851..a36bea7176 100644 --- a/src/mesa/glapi/glthread.h +++ b/src/mesa/glapi/glthread.h @@ -322,7 +322,7 @@ extern __thread struct _glapi_table * _glapi_tls_Dispatch #elif !defined(GL_CALL) # if defined(THREADS) # define GET_DISPATCH() \ - ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \ + ((__builtin_expect(_glapi_SingleThreaded, 1)) \ ? _glapi_Dispatch : _glapi_get_dispatch()) # else # define GET_DISPATCH() _glapi_Dispatch -- cgit v1.2.3 From 58ac57c2b7b40b64df2a867d4b9d4e5c5bc13c47 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sun, 16 Aug 2009 08:51:58 +0800 Subject: egl_xdri: Revive the driver. egl_xdri does not compile for some time. This commit revives the driver. It no longer depends on libGL.so for GLX related functions. Instead, it uses code from src/glx/ directly. Both DRI and DRI2 are supported. Signed-off-by: Chia-I Wu --- src/egl/drivers/xdri/Makefile | 15 +- src/egl/drivers/xdri/driinit.c | 67 +++ src/egl/drivers/xdri/driinit.h | 9 + src/egl/drivers/xdri/egl_xdri.c | 1054 +++++++++------------------------------ src/egl/drivers/xdri/glxinit.c | 626 +++++++++++++++++++++++ src/egl/drivers/xdri/glxinit.h | 14 + 6 files changed, 953 insertions(+), 832 deletions(-) create mode 100644 src/egl/drivers/xdri/driinit.c create mode 100644 src/egl/drivers/xdri/driinit.h create mode 100644 src/egl/drivers/xdri/glxinit.c create mode 100644 src/egl/drivers/xdri/glxinit.h (limited to 'src') diff --git a/src/egl/drivers/xdri/Makefile b/src/egl/drivers/xdri/Makefile index 8a14027fc7..4c1fc9071c 100644 --- a/src/egl/drivers/xdri/Makefile +++ b/src/egl/drivers/xdri/Makefile @@ -16,19 +16,24 @@ INCLUDE_DIRS = \ $(shell pkg-config --cflags-only-I libdrm) \ -I$(TOP)/include \ -I$(TOP)/include/GL/internal \ + -I$(TOP)/src/mesa \ -I$(TOP)/src/mesa/glapi \ - -I$(TOP)/src/mesa/drivers/dri/common \ -I$(TOP)/src/egl/main \ -I$(TOP)/src/glx/x11 -SOURCES = egl_xdri.c +HEADERS = glxinit.h driinit.h +SOURCES = egl_xdri.c glxinit.c driinit.c + +DRI_SOURCES = dri_common.c XF86dri.c dri2.c dri2_glx.c dri_glx.c +DRI_SOURCES := $(addprefix ../../../glx/x11/,$(DRI_SOURCES)) + +SOURCES += $(DRI_SOURCES) OBJECTS = $(SOURCES:.c=.o) DRM_LIB = `pkg-config --libs libdrm` -MISC_LIBS = -ldl -lXext -lGL - +CFLAGS += -DGLX_DIRECT_RENDERING .c.o: $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ @@ -50,7 +55,7 @@ $(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(OBJECTS) -major 1 -minor 0 \ -L$(TOP)/$(LIB_DIR) \ -install $(TOP)/$(LIB_DIR) \ - $(OBJECTS) $(DRM_LIB) $(MISC_LIBS) + $(OBJECTS) $(DRM_LIB) $(GL_LIB_DEPS) install: $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) diff --git a/src/egl/drivers/xdri/driinit.c b/src/egl/drivers/xdri/driinit.c new file mode 100644 index 0000000000..12da1bcd24 --- /dev/null +++ b/src/egl/drivers/xdri/driinit.c @@ -0,0 +1,67 @@ +/** + * DRI initialization. The DRI loaders are defined in src/glx/x11/. + */ + +#include + +#include "glxclient.h" +#include "driinit.h" + +/* for __DRI_SYSTEM_TIME extension */ +_X_HIDDEN int +__glXGetUST(int64_t * ust) +{ + struct timeval tv; + + if (ust == NULL) { + return -EFAULT; + } + + if (gettimeofday(&tv, NULL) == 0) { + ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec; + return 0; + } + else { + return -errno; + } +} + +_X_HIDDEN GLboolean +__driGetMscRateOML(__DRIdrawable * draw, + int32_t * numerator, int32_t * denominator, void *private) +{ + return GL_FALSE; +} + +/* ignore glx extensions */ +_X_HIDDEN void +__glXEnableDirectExtension(__GLXscreenConfigs * psc, const char *name) +{ +} + +_X_HIDDEN __GLXDRIdisplay * +__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version) +{ + __GLXDRIdisplay *driDisplay; + int ver = 0; + + /* try DRI2 first */ + driDisplay = dri2CreateDisplay(dpyPriv->dpy); + if (driDisplay) { + /* fill in the required field */ + dpyPriv->dri2Display = driDisplay; + ver = 2; + } + else { + /* try DRI */ + driDisplay = driCreateDisplay(dpyPriv->dpy); + if (driDisplay) { + dpyPriv->driDisplay = driDisplay; + ver = 1; + } + } + + if (version) + *version = ver; + return driDisplay; +} diff --git a/src/egl/drivers/xdri/driinit.h b/src/egl/drivers/xdri/driinit.h new file mode 100644 index 0000000000..6ea05cebef --- /dev/null +++ b/src/egl/drivers/xdri/driinit.h @@ -0,0 +1,9 @@ +#ifndef DRIINIT_INCLUDED +#define DRIINIT_INCLUDED + +#include "glxclient.h" + +extern __GLXDRIdisplay * +__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version); + +#endif /* DRIINIT_INCLUDED */ diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index d8d29fcef4..518091a2d1 100644 --- a/src/egl/drivers/xdri/egl_xdri.c +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -39,63 +39,40 @@ * Authors: Brian Paul */ - #include -#include -#include -#include -#include -#include "dlfcn.h" +#include #include -#include -#include "xf86dri.h" -#include "glxclient.h" -#include "dri_util.h" -#include "drm_sarea.h" -#define _EGL_PLATFORM_X +#include "glxinit.h" +#include "driinit.h" +#include "glapi/glapi.h" /* for glapi functions */ #include "eglconfig.h" #include "eglcontext.h" #include "egldisplay.h" #include "egldriver.h" #include "eglglobals.h" -#include "eglhash.h" #include "egllog.h" #include "eglsurface.h" -#include - -typedef void (*glGetIntegerv_t)(GLenum, GLint *); -typedef void (*glBindTexture_t)(GLenum, GLuint); -typedef void (*glCopyTexImage2D_t)(GLenum, GLint, GLenum, GLint, GLint, - GLint, GLint, GLint); - - #define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T)) - /** subclass of _EGLDriver */ struct xdri_egl_driver { _EGLDriver Base; /**< base class */ - - const char *dri_driver_name; /**< name of DRI driver to load */ - void *dri_driver_handle; /**< returned by dlopen(dri_driver_name) */ - - __GLXdisplayPrivate *glx_priv; +}; - /* XXX we're not actually using these at this time: */ - int chipset; - int minor; - int drmFD; +/** driver data of _EGLDisplay */ +struct xdri_egl_display +{ + Display *dpy; + __GLXdisplayPrivate *dpyPriv; + __GLXDRIdisplay *driDisplay; - __DRIframebuffer framebuffer; - drm_handle_t hSAREA; - drmAddress pSAREA; - char *busID; - drm_magic_t magic; + __GLXscreenConfigs *psc; + EGLint scr; }; @@ -104,9 +81,10 @@ struct xdri_egl_context { _EGLContext Base; /**< base class */ - __DRIcontext driContext; + /* just enough info to create dri contexts */ + GLXContext dummy_gc; - GLint bound_tex_object; + __GLXDRIcontext *driContext; }; @@ -115,8 +93,8 @@ struct xdri_egl_surface { _EGLSurface Base; /**< base class */ - __DRIid driDrawable; /**< DRI surface */ - drm_drawable_t hDrawable; + Drawable drawable; + __GLXDRIdrawable *driDrawable; }; @@ -131,46 +109,44 @@ struct xdri_egl_config /** cast wrapper */ -static struct xdri_egl_driver * +static INLINE struct xdri_egl_driver * xdri_egl_driver(_EGLDriver *drv) { return (struct xdri_egl_driver *) drv; } +static INLINE struct xdri_egl_display * +lookup_display(_EGLDisplay *dpy) +{ + return (struct xdri_egl_display *) dpy->DriverData; +} + + /** Map EGLSurface handle to xdri_egl_surface object */ -static struct xdri_egl_surface * -lookup_surface(EGLSurface surf) +static INLINE struct xdri_egl_surface * +lookup_surface(_EGLSurface *surface) { - _EGLSurface *surface = _eglLookupSurface(surf); return (struct xdri_egl_surface *) surface; } /** Map EGLContext handle to xdri_egl_context object */ -static struct xdri_egl_context * -lookup_context(EGLContext c) +static INLINE struct xdri_egl_context * +lookup_context(_EGLContext *context) { - _EGLContext *context = _eglLookupContext(c); return (struct xdri_egl_context *) context; } -static struct xdri_egl_context * -current_context(void) -{ - return (struct xdri_egl_context *) _eglGetCurrentContext(); -} /** Map EGLConfig handle to xdri_egl_config object */ -static struct xdri_egl_config * -lookup_config(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config) +static INLINE struct xdri_egl_config * +lookup_config(_EGLConfig *conf) { - _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); return (struct xdri_egl_config *) conf; } - /** Get size of given window */ static Status get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) @@ -188,22 +164,18 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) /** * Produce a set of EGL configs. - * Note that we get the list of GLcontextModes from the GLX library. - * This dependency on GLX lib will be removed someday. */ -static void -create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv) +static EGLint +create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id) { static const EGLint all_apis = (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENVG_BIT | EGL_OPENGL_BIT); - __GLXscreenConfigs *scrn = glx_priv->screenConfigs; - const __GLcontextModes *m; - int id = 1; + int id = first_id; - for (m = scrn->configs; m; m = m->next) { - /* EGL requires double-buffered configs */ + for (; m; m = m->next) { + /* add double buffered visual */ if (m->doubleBufferMode) { struct xdri_egl_config *config = CALLOC_STRUCT(xdri_egl_config); @@ -222,9 +194,7 @@ create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv) SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_TYPE, m->visualType); SET_CONFIG_ATTRIB(&config->Base, EGL_CONFORMANT, all_apis); SET_CONFIG_ATTRIB(&config->Base, EGL_RENDERABLE_TYPE, all_apis); - /* XXX only window rendering allowed ATM */ - SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE, - (EGL_WINDOW_BIT | EGL_PBUFFER_BIT)); + SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT); /* XXX possibly other things to init... */ @@ -234,431 +204,76 @@ create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv) _eglAddConfig(disp, &config->Base); } } -} - -/** - * Called via __DRIinterfaceMethods object - */ -static __DRIfuncPtr -dri_get_proc_address(const char * proc_name) -{ - return NULL; -} - - -static void -dri_context_modes_destroy(__GLcontextModes *modes) -{ - _eglLog(_EGL_DEBUG, "%s", __FUNCTION__); - - while (modes) { - __GLcontextModes * const next = modes->next; - free(modes); - modes = next; - } + return id; } /** - * Create a linked list of 'count' GLcontextModes. - * These are used during the client/server visual negotiation phase, - * then discarded. + * Called via eglInitialize(), xdri_dpy->API.Initialize(). */ -static __GLcontextModes * -dri_context_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; - - next = & head; - for (i = 0 ; i < count ; i++) { - *next = (__GLcontextModes *) calloc(1, size); - if (*next == NULL) { - dri_context_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; -} - - -static __DRIscreen * -dri_find_dri_screen(__DRInativeDisplay *ndpy, int scrn) -{ - __GLXdisplayPrivate *priv = __glXInitialize(ndpy); - __GLXscreenConfigs *scrnConf = priv->screenConfigs; - return &scrnConf->driScreen; -} - - -static GLboolean -dri_window_exists(__DRInativeDisplay *ndpy, __DRIid draw) -{ - return EGL_TRUE; -} - - -static GLboolean -dri_create_context(__DRInativeDisplay *ndpy, int screenNum, int configID, - void * contextID, drm_context_t * hw_context) -{ - assert(configID >= 0); - return XF86DRICreateContextWithConfig(ndpy, screenNum, - configID, contextID, hw_context); -} - - -static GLboolean -dri_destroy_context(__DRInativeDisplay * ndpy, int screen, __DRIid context) -{ - return XF86DRIDestroyContext(ndpy, screen, context); -} - - -static GLboolean -dri_create_drawable(__DRInativeDisplay * ndpy, int screen, - __DRIid drawable, drm_drawable_t * hHWDrawable) -{ - _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__); - - /* Create DRI drawable for given window ID (drawable) */ - if (!XF86DRICreateDrawable(ndpy, screen, drawable, hHWDrawable)) - return EGL_FALSE; - - return EGL_TRUE; -} - - -static GLboolean -dri_destroy_drawable(__DRInativeDisplay * ndpy, int screen, __DRIid drawable) -{ - _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__); - return XF86DRIDestroyDrawable(ndpy, screen, drawable); -} - - -static GLboolean -dri_get_drawable_info(__DRInativeDisplay *ndpy, int scrn, - __DRIid draw, unsigned int * index, unsigned int * stamp, - int * x, int * y, int * width, int * height, - int * numClipRects, drm_clip_rect_t ** pClipRects, - int * backX, int * backY, - int * numBackClipRects, - drm_clip_rect_t ** pBackClipRects) -{ - _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__); - - if (!XF86DRIGetDrawableInfo(ndpy, scrn, draw, index, stamp, - x, y, width, height, - numClipRects, pClipRects, - backX, backY, - numBackClipRects, pBackClipRects)) { - return EGL_FALSE; - } - - return EGL_TRUE; -} - - -/** - * Table of functions exported by the loader to the driver. - */ -static const __DRIinterfaceMethods interface_methods = { - dri_get_proc_address, - - dri_context_modes_create, - dri_context_modes_destroy, - - dri_find_dri_screen, - dri_window_exists, - - dri_create_context, - dri_destroy_context, - - dri_create_drawable, - dri_destroy_drawable, - dri_get_drawable_info, - - NULL,/*__eglGetUST,*/ - NULL,/*__eglGetMSCRate,*/ -}; - - - static EGLBoolean -init_drm(struct xdri_egl_driver *xdri_drv, _EGLDisplay *disp) +xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, + EGLint *minor, EGLint *major) { - __DRIversion ddx_version; - __DRIversion dri_version; - __DRIversion drm_version; - drmVersionPtr version; - drm_handle_t hFB; - int newlyopened; - int status; - int scrn = DefaultScreen(disp->Xdpy); - -#if 0 - createNewScreen = (PFNCREATENEWSCREENFUNC) - dlsym(xdri_drv->dri_driver_handle, createNewScreenName); - if (!createNewScreen) { - _eglLog(_EGL_WARNING, "XDRI: Couldn't find %s function in the driver.", - createNewScreenName); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: Found %s", createNewScreenName); - } -#endif - - /* - * Get the DRI X extension version. - */ - dri_version.major = 4; - dri_version.minor = 0; - dri_version.patch = 0; - - if (!XF86DRIOpenConnection(disp->Xdpy, scrn, - &xdri_drv->hSAREA, &xdri_drv->busID)) { - _eglLog(_EGL_WARNING, "XF86DRIOpenConnection failed"); - } - - xdri_drv->drmFD = drmOpenOnce(NULL, xdri_drv->busID, &newlyopened); - if (xdri_drv->drmFD < 0) { - perror("drmOpenOnce failed: "); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: drmOpenOnce returned %d", xdri_drv->drmFD); - } - - - if (drmGetMagic(xdri_drv->drmFD, &xdri_drv->magic)) { - perror("drmGetMagic failed: "); - return EGL_FALSE; - } - - version = drmGetVersion(xdri_drv->drmFD); - if (version) { - drm_version.major = version->version_major; - drm_version.minor = version->version_minor; - drm_version.patch = version->version_patchlevel; - drmFreeVersion(version); - _eglLog(_EGL_DEBUG, "XDRI: Got DRM version %d.%d.%d", - drm_version.major, - drm_version.minor, - drm_version.patch); - } - else { - drm_version.major = -1; - drm_version.minor = -1; - drm_version.patch = -1; - _eglLog(_EGL_WARNING, "XDRI: drmGetVersion() failed"); - return EGL_FALSE; - } - - /* Authenticate w/ server. - */ - if (!XF86DRIAuthConnection(disp->Xdpy, scrn, xdri_drv->magic)) { - _eglLog(_EGL_WARNING, "XDRI: XF86DRIAuthConnection() failed"); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: XF86DRIAuthConnection() success"); - } - - /* Get ddx version. - */ - { - char *driverName; - - /* - * Get device name (like "tdfx") and the ddx version - * numbers. We'll check the version in each DRI driver's - * "createNewScreen" function. - */ - if (!XF86DRIGetClientDriverName(disp->Xdpy, scrn, - &ddx_version.major, - &ddx_version.minor, - &ddx_version.patch, - &driverName)) { - _eglLog(_EGL_WARNING, "XDRI: XF86DRIGetClientDriverName failed"); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: XF86DRIGetClientDriverName returned %s", driverName); - } - } - - /* Get framebuffer info. - */ - { - int junk; - if (!XF86DRIGetDeviceInfo(disp->Xdpy, scrn, - &hFB, - &junk, - &xdri_drv->framebuffer.size, - &xdri_drv->framebuffer.stride, - &xdri_drv->framebuffer.dev_priv_size, - &xdri_drv->framebuffer.dev_priv)) { - _eglLog(_EGL_WARNING, "XDRI: XF86DRIGetDeviceInfo() failed"); - return EGL_FALSE; + struct xdri_egl_display *xdri_dpy; + __GLXdisplayPrivate *dpyPriv; + __GLXDRIdisplay *driDisplay; + __GLXscreenConfigs *psc; + EGLint first_id = 1; + int scr; + + xdri_dpy = CALLOC_STRUCT(xdri_egl_display); + if (!xdri_dpy) + return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + + xdri_dpy->dpy = (Display *) dpy->NativeDisplay; + if (!xdri_dpy->dpy) { + xdri_dpy->dpy = XOpenDisplay(NULL); + if (!xdri_dpy->dpy) { + free(xdri_dpy); + return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } - else { - _eglLog(_EGL_DEBUG, "XDRI: XF86DRIGetDeviceInfo() success"); - } - xdri_drv->framebuffer.width = DisplayWidth(disp->Xdpy, scrn); - xdri_drv->framebuffer.height = DisplayHeight(disp->Xdpy, scrn); - } - - /* Map the framebuffer region. (this may not be needed) - */ - status = drmMap(xdri_drv->drmFD, hFB, xdri_drv->framebuffer.size, - (drmAddressPtr) &xdri_drv->framebuffer.base); - if (status != 0) { - _eglLog(_EGL_WARNING, "XDRI: drmMap(framebuffer) failed"); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: drmMap(framebuffer) success"); } - /* Map the SAREA region. - */ - status = drmMap(xdri_drv->drmFD, xdri_drv->hSAREA, SAREA_MAX, &xdri_drv->pSAREA); - if (status != 0) { - _eglLog(_EGL_WARNING, "XDRI: drmMap(sarea) failed"); - return EGL_FALSE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: drmMap(sarea) success"); - } - - return EGL_TRUE; -} - - -/** - * Load the DRI driver named by "xdri_drv->dri_driver_name". - * Basically, dlopen() the library to set "xdri_drv->dri_driver_handle". - * - * Later, we'll call dlsym(createNewScreenName) to get a pointer to - * the driver's createNewScreen() function which is the bootstrap function. - * - * \return EGL_TRUE for success, EGL_FALSE for failure - */ -static EGLBoolean -load_dri_driver(struct xdri_egl_driver *xdri_drv) -{ - char filename[100]; - int flags = RTLD_NOW; - - /* try "egl_xxx_dri.so" first */ - snprintf(filename, sizeof(filename), "egl_%s.so", xdri_drv->dri_driver_name); - _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename); - xdri_drv->dri_driver_handle = dlopen(filename, flags); - if (xdri_drv->dri_driver_handle) { - _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename); - return EGL_TRUE; - } - else { - _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) fail (%s)", filename, dlerror()); + dpyPriv = __glXInitialize(xdri_dpy->dpy); + if (!dpyPriv) { + _eglLog(_EGL_WARNING, "failed to create GLX display"); + free(xdri_dpy); + return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } - /* try regular "xxx_dri.so" next */ - snprintf(filename, sizeof(filename), "%s.so", xdri_drv->dri_driver_name); - _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename); - xdri_drv->dri_driver_handle = dlopen(filename, flags); - if (xdri_drv->dri_driver_handle) { - _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename); - return EGL_TRUE; + driDisplay = __driCreateDisplay(dpyPriv, NULL); + if (!driDisplay) { + _eglLog(_EGL_WARNING, "failed to create DRI display"); + free(xdri_dpy); + return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } - _eglLog(_EGL_WARNING, "XDRI Could not open %s (%s)", filename, dlerror()); - return EGL_FALSE; -} - - -/** - * Called via eglInitialize(), xdri_drv->API.Initialize(). - */ -static EGLBoolean -xdri_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, - EGLint *minor, EGLint *major) -{ - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - _EGLDisplay *disp = _eglLookupDisplay(dpy); - static char name[100]; + scr = DefaultScreen(xdri_dpy->dpy); + psc = &dpyPriv->screenConfigs[scr]; - _eglLog(_EGL_DEBUG, "XDRI: eglInitialize"); + xdri_dpy->dpyPriv = dpyPriv; + xdri_dpy->driDisplay = driDisplay; + xdri_dpy->psc = psc; + xdri_dpy->scr = scr; - if (!disp->Xdpy) { - disp->Xdpy = XOpenDisplay(NULL); - if (!disp->Xdpy) { - _eglLog(_EGL_WARNING, "XDRI: XOpenDisplay failed"); - return EGL_FALSE; - } + psc->driScreen = driDisplay->createScreen(psc, scr, dpyPriv); + if (!psc->driScreen) { + _eglLog(_EGL_WARNING, "failed to create DRI screen #%d", scr); + free(xdri_dpy); + return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } -#if 0 - /* choose the DRI driver to load */ - xdri_drv->dri_driver_name = _eglChooseDRMDriver(0); - if (!load_dri_driver(xdri_drv)) - return EGL_FALSE; -#else - (void) load_dri_driver; -#endif - -#if 0 - if (!init_drm(xdri_drv, disp)) - return EGL_FALSE; -#else - (void) init_drm; -#endif - - /* - * NOTE: this call to __glXInitialize() bootstraps the whole GLX/DRI - * interface, loads the DRI driver, etc. - * This replaces the load_dri_driver() and init_drm() code above. - */ - xdri_drv->glx_priv = __glXInitialize(disp->Xdpy); - - create_configs(disp, xdri_drv->glx_priv); - - xdri_drv->Base.Initialized = EGL_TRUE; + /* add visuals and fbconfigs */ + first_id = create_configs(dpy, psc->visuals, first_id); + create_configs(dpy, psc->configs, first_id); - if (xdri_drv->dri_driver_name) - snprintf(name, sizeof(name), "X/DRI:%s", xdri_drv->dri_driver_name); - else - snprintf(name, sizeof(name), "X/DRI"); - xdri_drv->Base.Name = name; + dpy->DriverData = xdri_dpy; + dpy->ClientAPIsMask = (EGL_OPENGL_BIT | + EGL_OPENGL_ES_BIT | + EGL_OPENGL_ES2_BIT | + EGL_OPENVG_BIT); /* we're supporting EGL 1.4 */ *minor = 1; @@ -668,57 +283,37 @@ xdri_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, } -/* - * Do some clean-up that normally occurs in XCloseDisplay(). - * We do this here because we're about to unload a dynamic library - * that has added some per-display extension data and callbacks. - * If we don't do this here we'll crash in XCloseDisplay() because it'll - * try to call functions that went away when the driver library was unloaded. - */ -static void -FreeDisplayExt(Display *dpy) -{ - _XExtension *ext, *next; - - for (ext = dpy->ext_procs; ext; ext = next) { - next = ext->next; - if (ext->close_display) { - ext->close_display(dpy, &ext->codes); - ext->close_display = NULL; - } - if (ext->name) - Xfree(ext->name); - Xfree(ext); - } - dpy->ext_procs = NULL; - - _XFreeExtData (dpy->ext_data); - dpy->ext_data = NULL; -} - - /** * Called via eglTerminate(), drv->API.Terminate(). */ static EGLBoolean -xdri_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) +xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy) { - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - _EGLDisplay *disp = _eglLookupDisplay(dpy); + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + __GLXscreenConfigs *psc; - _eglLog(_EGL_DEBUG, "XDRI: eglTerminate"); + _eglReleaseDisplayResources(drv, dpy); + _eglCleanupDisplay(dpy); - _eglLog(_EGL_DEBUG, "XDRI: Closing %s", xdri_drv->dri_driver_name); - - FreeDisplayExt(disp->Xdpy); + psc = xdri_dpy->psc; + if (psc->driver_configs) { + unsigned int i; + for (i = 0; psc->driver_configs[i]; i++) + free((__DRIconfig *) psc->driver_configs[i]); + free(psc->driver_configs); + psc->driver_configs = NULL; + } + if (psc->driScreen) { + psc->driScreen->destroyScreen(psc); + free(psc->driScreen); + psc->driScreen = NULL; + } -#if 0 - /* this causes a segfault for some reason */ - dlclose(xdri_drv->dri_driver_handle); -#endif - xdri_drv->dri_driver_handle = NULL; + xdri_dpy->driDisplay->destroyDisplay(xdri_dpy->driDisplay); + __glXRelease(xdri_dpy->dpyPriv); - free((void*) xdri_drv->dri_driver_name); + free(xdri_dpy); + dpy->DriverData = NULL; return EGL_TRUE; } @@ -730,71 +325,77 @@ xdri_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) static _EGLProc xdri_eglGetProcAddress(const char *procname) { -#if 0 - _EGLDriver *drv = NULL; - - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - /*_EGLDisplay *disp = _eglLookupDisplay(dpy);*/ - _EGLProc *proc = xdri_drv->driScreen.getProcAddress(procname); - return proc; -#elif 1 - /* This is a bit of a hack to get at the gallium/Mesa state tracker - * function st_get_proc_address(). This will probably change at - * some point. - */ - _EGLProc (*st_get_proc_addr)(const char *procname); - st_get_proc_addr = dlsym(NULL, "st_get_proc_address"); - if (st_get_proc_addr) { - return st_get_proc_addr(procname); - } - return NULL; -#else - return NULL; -#endif + /* the symbol is defined in libGL.so */ + return (_EGLProc) _glapi_get_proc_address(procname); } /** * Called via eglCreateContext(), drv->API.CreateContext(). */ -static EGLContext -xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, - EGLContext share_list, const EGLint *attrib_list) -{ - _EGLDisplay *disp = _eglLookupDisplay(dpy); - struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config); - void *shared = NULL; +static _EGLContext * +xdri_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, + _EGLContext *share_list, const EGLint *attrib_list) +{ + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + struct xdri_egl_config *xdri_config = lookup_config(conf); + struct xdri_egl_context *shared = lookup_context(share_list); + __GLXscreenConfigs *psc = xdri_dpy->psc; int renderType = GLX_RGBA_BIT; + struct xdri_egl_context *xdri_ctx; - struct xdri_egl_context *xdri_ctx = CALLOC_STRUCT(xdri_egl_context); - if (!xdri_ctx) - return EGL_NO_CONTEXT; + xdri_ctx = CALLOC_STRUCT(xdri_egl_context); + if (!xdri_ctx) { + _eglError(EGL_BAD_ALLOC, "eglCreateContext"); + return NULL; + } - if (!_eglInitContext(drv, &xdri_ctx->Base, &xdri_config->Base, attrib_list)) { + xdri_ctx->dummy_gc = CALLOC_STRUCT(__GLXcontextRec); + if (!xdri_ctx->dummy_gc) { + _eglError(EGL_BAD_ALLOC, "eglCreateContext"); free(xdri_ctx); - return EGL_NO_CONTEXT; + return NULL; } - assert(xdri_config); - - { - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs; - xdri_ctx->driContext.private = - scrnConf->driScreen.createNewContext(disp->Xdpy, - xdri_config->mode, renderType, - shared, &xdri_ctx->driContext); + if (!_eglInitContext(drv, &xdri_ctx->Base, &xdri_config->Base, attrib_list)) { + free(xdri_ctx->dummy_gc); + free(xdri_ctx); + return NULL; } - if (!xdri_ctx->driContext.private) { - _eglLog(_EGL_DEBUG, "driScreen.createNewContext failed"); + xdri_ctx->driContext = + psc->driScreen->createContext(psc, + xdri_config->mode, + xdri_ctx->dummy_gc, + (shared) ? shared->dummy_gc : NULL, + renderType); + if (!xdri_ctx->driContext) { + free(xdri_ctx->dummy_gc); free(xdri_ctx); - return EGL_NO_CONTEXT; + return NULL; } - xdri_ctx->driContext.mode = xdri_config->mode; + /* fill in the required field */ + xdri_ctx->dummy_gc->driContext = xdri_ctx->driContext; - return _eglLinkContext(&xdri_ctx->Base, &disp); + return &xdri_ctx->Base; +} + + +static EGLBoolean +xdri_eglDestroyContext(_EGLDriver *drv, _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); + } + + return EGL_TRUE; } @@ -802,25 +403,32 @@ xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, * Called via eglMakeCurrent(), drv->API.MakeCurrent(). */ static EGLBoolean -xdri_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, - EGLSurface r, EGLContext context) +xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d, + _EGLSurface *r, _EGLContext *context) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); struct xdri_egl_context *xdri_ctx = lookup_context(context); - struct xdri_egl_surface *xdri_draw = lookup_surface(d); - struct xdri_egl_surface *xdri_read = lookup_surface(r); - __DRIid draw = xdri_draw ? xdri_draw->driDrawable : 0; - __DRIid read = xdri_read ? xdri_read->driDrawable : 0; - int scrn = DefaultScreen(disp->Xdpy); + struct xdri_egl_surface *draw = lookup_surface(d); + struct xdri_egl_surface *read = lookup_surface(r); if (!_eglMakeCurrent(drv, dpy, d, r, context)) return EGL_FALSE; + /* the symbol is defined in libGL.so */ + _glapi_check_multithread(); - if (xdri_ctx && - !xdri_ctx->driContext.bindContext(disp->Xdpy, scrn, draw, read, - &xdri_ctx->driContext)) { - return EGL_FALSE; + if (xdri_ctx) { + if (!xdri_ctx->driContext->bindContext(xdri_ctx->driContext, + draw->driDrawable, + read->driDrawable)) { + return EGL_FALSE; + } + } + else { + _EGLContext *old = _eglGetCurrentContext(); + if (old) { + xdri_ctx = lookup_context(old); + xdri_ctx->driContext->unbindContext(xdri_ctx->driContext); + } } return EGL_TRUE; @@ -830,307 +438,106 @@ xdri_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, /** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ -static EGLSurface -xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, +static _EGLSurface * +xdri_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); - struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config); + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + struct xdri_egl_config *xdri_config = lookup_config(conf); struct xdri_egl_surface *xdri_surf; - int scrn = DefaultScreen(disp->Xdpy); uint width, height; xdri_surf = CALLOC_STRUCT(xdri_egl_surface); - if (!xdri_surf) - return EGL_NO_SURFACE; + if (!xdri_surf) { + _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface"); + return NULL; + } if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_WINDOW_BIT, &xdri_config->Base, attrib_list)) { free(xdri_surf); - return EGL_FALSE; + return NULL; } - if (!XF86DRICreateDrawable(disp->Xdpy, scrn, window, &xdri_surf->hDrawable)) { + xdri_surf->driDrawable = + xdri_dpy->psc->driScreen->createDrawable(xdri_dpy->psc, + (XID) window, + (GLXDrawable) window, + xdri_config->mode); + if (!xdri_surf->driDrawable) { free(xdri_surf); - return EGL_FALSE; + return NULL; } - xdri_surf->driDrawable = window; + xdri_surf->drawable = (Drawable) window; - _eglLinkSurface(&xdri_surf->Base, disp); - - get_drawable_size(disp->Xdpy, window, &width, &height); + get_drawable_size(xdri_dpy->dpy, window, &width, &height); xdri_surf->Base.Width = width; xdri_surf->Base.Height = height; - _eglLog(_EGL_DEBUG, - "XDRI: CreateWindowSurface win 0x%x handle %d hDrawable %d", - (int) window, _eglGetSurfaceHandle(&xdri_surf->Base), - (int) xdri_surf->hDrawable); - - return _eglGetSurfaceHandle(&xdri_surf->Base); + return &xdri_surf->Base; } /** * Called via eglCreatePbufferSurface(), drv->API.CreatePbufferSurface(). */ -static EGLSurface -xdri_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, +static _EGLSurface * +xdri_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); - struct xdri_egl_surface *xdri_surf; - struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config); - int scrn = DefaultScreen(disp->Xdpy); - Window window; - - xdri_surf = CALLOC_STRUCT(xdri_egl_surface); - if (!xdri_surf) - return EGL_NO_SURFACE; - - if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_PBUFFER_BIT, - &xdri_config->Base, attrib_list)) { - free(xdri_surf); - return EGL_FALSE; - } - - /* Create a dummy X window */ - { - Window root = RootWindow(disp->Xdpy, scrn); - XSetWindowAttributes attr; - XVisualInfo *visInfo, visTemplate; - unsigned mask; - int nvis; - - visTemplate.visualid = xdri_config->mode->visualID; - visInfo = XGetVisualInfo(disp->Xdpy, VisualIDMask, &visTemplate, &nvis); - if (!visInfo) { - return EGL_NO_SURFACE; - } - - attr.background_pixel = 0; - attr.border_pixel = 0; - attr.colormap = XCreateColormap(disp->Xdpy, root, - visInfo->visual, AllocNone); - attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; - mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; - - window = XCreateWindow(disp->Xdpy, root, 0, 0, - xdri_surf->Base.Width, xdri_surf->Base.Height, - 0, visInfo->depth, InputOutput, - visInfo->visual, mask, &attr); - - /*XMapWindow(disp->Xdpy, window);*/ - XFree(visInfo); - - /* set hints and properties */ - /* - sizehints.width = xdri_surf->Base.Width; - sizehints.height = xdri_surf->Base.Height; - sizehints.flags = USPosition; - XSetNormalHints(disp->Xdpy, window, &sizehints); - */ - } - - if (!XF86DRICreateDrawable(disp->Xdpy, scrn, window, &xdri_surf->hDrawable)) { - free(xdri_surf); - return EGL_FALSE; - } - - xdri_surf->driDrawable = window; - - _eglLinkSurface(&xdri_surf->Base, disp); - - _eglLog(_EGL_DEBUG, - "XDRI: CreatePbufferSurface handle %d hDrawable %d", - _eglGetSurfaceHandle(&xdri_surf->Base), - (int) xdri_surf->hDrawable); - - return _eglGetSurfaceHandle(&xdri_surf->Base); + return NULL; } static EGLBoolean -xdri_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) +xdri_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface) { struct xdri_egl_surface *xdri_surf = lookup_surface(surface); - if (xdri_surf) { - _eglUnlinkSurface(&xdri_surf->Base); - if (!_eglIsSurfaceBound(&xdri_surf->Base)) { - /* - st_unreference_framebuffer(surf->Framebuffer); - */ - free(xdri_surf); - } - return EGL_TRUE; - } - else { - _eglError(EGL_BAD_SURFACE, "eglDestroySurface"); - return EGL_FALSE; + + if (!_eglIsSurfaceBound(&xdri_surf->Base)) { + xdri_surf->driDrawable->destroyDrawable(xdri_surf->driDrawable); + free(xdri_surf); } + + return EGL_TRUE; } static EGLBoolean -xdri_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, +xdri_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer) { - typedef int (*bind_teximage)(__DRInativeDisplay *dpy, - __DRIid surface, __DRIscreen *psc, - int buffer, int target, int format, - int level, int mipmap); - - bind_teximage egl_dri_bind_teximage; - - _EGLDisplay *disp = _eglLookupDisplay(dpy); - - struct xdri_egl_context *xdri_ctx = current_context(); - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - struct xdri_egl_surface *xdri_surf = lookup_surface(surface); - - __DRIid dri_surf = xdri_surf ? xdri_surf->driDrawable : 0; - - __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs; - __DRIscreen *psc = &scrnConf->driScreen; - - /* this call just does error checking */ - if (!_eglBindTexImage(drv, dpy, surface, buffer)) { - return EGL_FALSE; - } - - egl_dri_bind_teximage = - (bind_teximage) dlsym(NULL, "egl_dri_bind_teximage"); - if (egl_dri_bind_teximage) { - return egl_dri_bind_teximage(disp->Xdpy, dri_surf, psc, - buffer, - xdri_surf->Base.TextureTarget, - xdri_surf->Base.TextureFormat, - xdri_surf->Base.MipmapLevel, - xdri_surf->Base.MipmapTexture); - } - else { - /* fallback path based on glCopyTexImage() */ - /* Get/save currently bound 2D texobj name */ - glGetIntegerv_t glGetIntegerv_func = - (glGetIntegerv_t) dlsym(NULL, "glGetIntegerv"); - GLint curTexObj = 0; - if (glGetIntegerv_func) { - (*glGetIntegerv_func)(GL_TEXTURE_BINDING_2D, &curTexObj); - } - xdri_ctx->bound_tex_object = curTexObj; - } - return EGL_FALSE; } static EGLBoolean -xdri_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, +xdri_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer) { - typedef int (*release_teximage)(__DRInativeDisplay *dpy, - __DRIid surface, __DRIscreen *psc, - int buffer, int target, int format, - int level, int mipmap); - release_teximage egl_dri_release_teximage; - - _EGLDisplay *disp = _eglLookupDisplay(dpy); - - struct xdri_egl_context *xdri_ctx = current_context(); - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - struct xdri_egl_surface *xdri_surf = lookup_surface(surface); - - __DRIid dri_surf = xdri_surf ? xdri_surf->driDrawable : 0; - - __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs; - __DRIscreen *psc = &scrnConf->driScreen; - - /* this call just does error checking */ - if (!_eglReleaseTexImage(drv, dpy, surface, buffer)) { - return EGL_FALSE; - } - - egl_dri_release_teximage = - (release_teximage) dlsym(NULL, "egl_dri_release_teximage"); - if (egl_dri_release_teximage) { - return egl_dri_release_teximage(disp->Xdpy, dri_surf, psc, - buffer, - xdri_surf->Base.TextureTarget, - xdri_surf->Base.TextureFormat, - xdri_surf->Base.MipmapLevel, - xdri_surf->Base.MipmapTexture); - } - else { - /* fallback path based on glCopyTexImage() */ - glGetIntegerv_t glGetIntegerv_func = - (glGetIntegerv_t) dlsym(NULL, "glGetIntegerv"); - glBindTexture_t glBindTexture_func = - (glBindTexture_t) dlsym(NULL, "glBindTexture"); - glCopyTexImage2D_t glCopyTexImage2D_func = - (glCopyTexImage2D_t) dlsym(NULL, "glCopyTexImage2D"); - GLint curTexObj; - GLenum intFormat; - GLint level, width, height; - - if (xdri_surf->Base.TextureFormat == EGL_TEXTURE_RGBA) - intFormat = GL_RGBA; - else - intFormat = GL_RGB; - level = xdri_surf->Base.MipmapLevel; - width = xdri_surf->Base.Width >> level; - height = xdri_surf->Base.Height >> level; - - if (width > 0 && height > 0 && - glGetIntegerv_func && glBindTexture_func && glCopyTexImage2D_func) { - glGetIntegerv_func(GL_TEXTURE_BINDING_2D, &curTexObj); - /* restore texobj from time of eglBindTexImage() call */ - if (curTexObj != xdri_ctx->bound_tex_object) - glBindTexture_func(GL_TEXTURE_2D, xdri_ctx->bound_tex_object); - /* copy pbuffer image to texture */ - glCopyTexImage2D_func(GL_TEXTURE_2D, - level, - intFormat, - 0, 0, width, height, 0); - /* restore current texture */ - if (curTexObj != xdri_ctx->bound_tex_object) - glBindTexture_func(GL_TEXTURE_2D, curTexObj); - } - xdri_ctx->bound_tex_object = -1; - } - return EGL_FALSE; } static EGLBoolean -xdri_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) +xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + struct xdri_egl_surface *xdri_surf = lookup_surface(draw); - _eglLog(_EGL_DEBUG, "XDRI: EGL SwapBuffers"); + xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable); - /* error checking step: */ - if (!_eglSwapBuffers(drv, dpy, draw)) - return EGL_FALSE; + return EGL_TRUE; +} - { - struct xdri_egl_surface *xdri_surf = lookup_surface(draw); - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs; - __DRIscreen *psc = &scrnConf->driScreen; - __DRIdrawable * const pdraw = psc->getDrawable(disp->Xdpy, - xdri_surf->driDrawable, - psc->private); - - if (pdraw) - pdraw->swapBuffers(disp->Xdpy, pdraw->private); - else - _eglLog(_EGL_WARNING, "pdraw is null in SwapBuffers"); - } - return EGL_TRUE; +static void +xdri_Unload(_EGLDriver *drv) +{ + struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); + free(xdri_drv); } @@ -1139,15 +546,12 @@ xdri_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) * Create a new _EGLDriver object and init its dispatch table. */ _EGLDriver * -_eglMain(_EGLDisplay *disp, const char *args) +_eglMain(const char *args) { struct xdri_egl_driver *xdri_drv = CALLOC_STRUCT(xdri_egl_driver); if (!xdri_drv) return NULL; - /* Tell libGL to prefer the EGL drivers over regular DRI drivers */ - __glXPreferEGL(1); - _eglInitDriverFallbacks(&xdri_drv->Base); xdri_drv->Base.API.Initialize = xdri_eglInitialize; xdri_drv->Base.API.Terminate = xdri_eglTerminate; @@ -1155,6 +559,7 @@ _eglMain(_EGLDisplay *disp, const char *args) xdri_drv->Base.API.GetProcAddress = xdri_eglGetProcAddress; xdri_drv->Base.API.CreateContext = xdri_eglCreateContext; + xdri_drv->Base.API.DestroyContext = xdri_eglDestroyContext; xdri_drv->Base.API.MakeCurrent = xdri_eglMakeCurrent; xdri_drv->Base.API.CreateWindowSurface = xdri_eglCreateWindowSurface; xdri_drv->Base.API.CreatePbufferSurface = xdri_eglCreatePbufferSurface; @@ -1163,13 +568,8 @@ _eglMain(_EGLDisplay *disp, const char *args) xdri_drv->Base.API.ReleaseTexImage = xdri_eglReleaseTexImage; xdri_drv->Base.API.SwapBuffers = xdri_eglSwapBuffers; - xdri_drv->Base.ClientAPIsMask = (EGL_OPENGL_BIT | - EGL_OPENGL_ES_BIT | - EGL_OPENGL_ES2_BIT | - EGL_OPENVG_BIT); xdri_drv->Base.Name = "X/DRI"; - - _eglLog(_EGL_DEBUG, "XDRI: main(%s)", args); + xdri_drv->Base.Unload = xdri_Unload; return &xdri_drv->Base; } diff --git a/src/egl/drivers/xdri/glxinit.c b/src/egl/drivers/xdri/glxinit.c new file mode 100644 index 0000000000..7775009394 --- /dev/null +++ b/src/egl/drivers/xdri/glxinit.c @@ -0,0 +1,626 @@ +/** + * 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 "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; +} + +static __GLcontextModes * +_gl_context_modes_create(unsigned count, size_t minimum_size) +{ + const size_t size = (minimum_size > sizeof(__GLcontextModes)) + ? minimum_size : sizeof(__GLcontextModes); + __GLcontextModes *base = NULL; + __GLcontextModes **next; + unsigned i; + + next = &base; + for (i = 0; i < count; i++) { + *next = (__GLcontextModes *) Xmalloc(size); + if (*next == NULL) { + _gl_context_modes_destroy(base); + base = NULL; + break; + } + + memset(*next, 0, size); + (*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 = GLX_DONT_CARE; + (*next)->yInverted = GLX_DONT_CARE; + + next = &((*next)->next); + } + + return base; +} + +_X_HIDDEN void +_gl_context_modes_destroy(__GLcontextModes * modes) +{ + while (modes != NULL) { + __GLcontextModes *const next = modes->next; + + Xfree(modes); + modes = next; + } +} + +_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) { + _gl_context_modes_destroy(psc->configs); + psc->configs = NULL; /* NOTE: just for paranoia */ + } + if (psc->visuals) { + _gl_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 = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes)); + 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/egl/drivers/xdri/glxinit.h b/src/egl/drivers/xdri/glxinit.h new file mode 100644 index 0000000000..57206e627b --- /dev/null +++ b/src/egl/drivers/xdri/glxinit.h @@ -0,0 +1,14 @@ +#ifndef GLXINIT_INCLUDED +#define GLXINIT_INCLUDED + +#include +#include "glxclient.h" + +/* this is used by DRI loaders */ +extern void +_gl_context_modes_destroy(__GLcontextModes * modes); + +extern void +__glXRelease(__GLXdisplayPrivate *dpyPriv); + +#endif /* GLXINIT_INCLUDED */ -- cgit v1.2.3 From 29473d25a34d24ce20564af93514a8d3b096966c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 24 Aug 2009 14:39:25 -0400 Subject: r600: fix state emit sizes --- src/mesa/drivers/dri/r600/r600_context.c | 8 +--- src/mesa/drivers/dri/r600/r700_chip.c | 74 +++++++++++++++++++++++++++++--- src/mesa/drivers/dri/r600/r700_render.c | 7 +++ 3 files changed, 75 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c index 0b0c4f5049..6a066f3510 100644 --- a/src/mesa/drivers/dri/r600/r600_context.c +++ b/src/mesa/drivers/dri/r600/r600_context.c @@ -185,13 +185,7 @@ static void r600_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmes static void r600_vtbl_pre_emit_atoms(radeonContextPtr radeon) { - context_t *context = (context_t *)radeon; - - /* always emit CB base to prevent - * lock ups on some chips. - */ - R600_STATECHANGE(context, cb_target); - r700Start3D(context); + r700Start3D((context_t *)radeon); } static void r600_fallback(GLcontext *ctx, GLuint bit, GLboolean mode) diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c index 3f11cf2c98..16f1a3df36 100644 --- a/src/mesa/drivers/dri/r600/r700_chip.c +++ b/src/mesa/drivers/dri/r600/r700_chip.c @@ -230,6 +230,9 @@ static void r700SendVTXState(GLcontext *ctx, struct radeon_state_atom *atom) unsigned int i, j = 0; BATCH_LOCALS(&context->radeon); + if (context->radeon.tcl.aos_count == 0) + return; + BEGIN_BATCH_NO_AUTOSTATE(6); R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1)); R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX); @@ -989,11 +992,60 @@ static int check_always(GLcontext *ctx, struct radeon_state_atom *atom) return atom->cmd_size; } +static int check_cb(GLcontext *ctx, struct radeon_state_atom *atom) +{ + context_t *context = R700_CONTEXT(ctx); + int count = 7; + + if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770) + count += 11; + + return count; +} + +static int check_blnd(GLcontext *ctx, struct radeon_state_atom *atom) +{ + context_t *context = R700_CONTEXT(ctx); + R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw); + unsigned int ui; + int count = 3; + + if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770) + count += 3; + + if (context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) { + for (ui = 0; ui < R700_MAX_RENDER_TARGETS; ui++) { + if (r700->render_target[ui].enabled) + count += 3; + } + } + + return count; +} + +static int check_ucp(GLcontext *ctx, struct radeon_state_atom *atom) +{ + context_t *context = R700_CONTEXT(ctx); + R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw); + int i; + int count = 0; + + for (i = 0; i < R700_MAX_UCP; i++) { + if (r700->ucp[i].enabled) + count += 6; + } + return count; +} + static int check_vtx(GLcontext *ctx, struct radeon_state_atom *atom) { context_t *context = R700_CONTEXT(ctx); + int count = context->radeon.tcl.aos_count * 18; + + if (count) + count += 6; - return context->radeon.tcl.aos_count * 18; + return count; } static int check_tx(GLcontext *ctx, struct radeon_state_atom *atom) @@ -1014,16 +1066,24 @@ static int check_ps_consts(GLcontext *ctx, struct radeon_state_atom *atom) { context_t *context = R700_CONTEXT(ctx); R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw); + int count = r700->ps.num_consts * 4; - return 2 + (r700->ps.num_consts * 4); + if (count) + count += 2; + + return count; } static int check_vs_consts(GLcontext *ctx, struct radeon_state_atom *atom) { context_t *context = R700_CONTEXT(ctx); R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw); + int count = r700->vs.num_consts * 4; + + if (count) + count += 2; - return 2 + (r700->vs.num_consts * 4); + return count; } #define ALLOC_STATE( ATOM, CHK, SZ, EMIT ) \ @@ -1056,12 +1116,12 @@ void r600InitAtoms(context_t *context) ALLOC_STATE(aa, always, 12, r700SendAAState); ALLOC_STATE(cl, always, 12, r700SendCLState); ALLOC_STATE(gb, always, 6, r700SendGBState); - ALLOC_STATE(ucp, always, 36, r700SendUCPState); + ALLOC_STATE(ucp, ucp, (R700_MAX_UCP * 6), r700SendUCPState); ALLOC_STATE(su, always, 9, r700SendSUState); ALLOC_STATE(poly, always, 10, r700SendPolyState); - ALLOC_STATE(cb, always, 18, r700SendCBState); + ALLOC_STATE(cb, cb, 18, r700SendCBState); ALLOC_STATE(clrcmp, always, 6, r700SendCBCLRCMPState); - ALLOC_STATE(blnd, always, 30, r700SendCBBlendState); + ALLOC_STATE(blnd, blnd, (6 + (R700_MAX_RENDER_TARGETS * 3)), r700SendCBBlendState); ALLOC_STATE(blnd_clr, always, 6, r700SendCBBlendColorState); ALLOC_STATE(cb_target, always, 25, r700SendRenderTargetState); ALLOC_STATE(sx, always, 9, r700SendSXState); @@ -1073,7 +1133,7 @@ void r600InitAtoms(context_t *context) ALLOC_STATE(ps, always, 21, r700SendPSState); ALLOC_STATE(vs_consts, vs_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendVSConsts); ALLOC_STATE(ps_consts, ps_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendPSConsts); - ALLOC_STATE(vtx, vtx, (VERT_ATTRIB_MAX * 18), r700SendVTXState); + ALLOC_STATE(vtx, vtx, (6 + (VERT_ATTRIB_MAX * 18)), r700SendVTXState); ALLOC_STATE(tx, tx, (R700_TEXTURE_NUMBERUNITS * 20), r700SendTexState); ALLOC_STATE(tx_smplr, tx, (R700_TEXTURE_NUMBERUNITS * 5), r700SendTexSamplerState); ALLOC_STATE(tx_brdr_clr, tx, (R700_TEXTURE_NUMBERUNITS * 6), r700SendTexBorderColorState); diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c index 9c4be37aac..cdf3220a7f 100644 --- a/src/mesa/drivers/dri/r600/r700_render.c +++ b/src/mesa/drivers/dri/r600/r700_render.c @@ -315,6 +315,13 @@ static GLboolean r700RunRender(GLcontext * ctx, rcommonEnsureCmdBufSpace(&context->radeon, radeon->hw.max_state_size + ind_count, __FUNCTION__); + /* always emit CB base to prevent + * lock ups on some chips. + */ + R600_STATECHANGE(context, cb_target); + /* mark vtx as dirty since it changes per-draw */ + R600_STATECHANGE(context, vtx); + r700UpdateShaders(ctx); r700SetScissor(context); r700SetupVertexProgram(ctx); -- cgit v1.2.3 From 4cf27608bc069225bf91d47585e344a2c122e940 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 24 Aug 2009 11:05:11 -0600 Subject: ARB prog parser: use correct context limits --- src/mesa/shader/program_parse.y | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y index 89e8850212..e2e83e484f 100644 --- a/src/mesa/shader/program_parse.y +++ b/src/mesa/shader/program_parse.y @@ -2287,12 +2287,12 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, ? & ctx->Const.VertexProgram : & ctx->Const.FragmentProgram; - state->MaxTextureImageUnits = 16; - state->MaxTextureCoordUnits = 8; - state->MaxTextureUnits = 8; - state->MaxClipPlanes = 6; - state->MaxLights = 8; - state->MaxProgramMatrices = 8; + state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits; + state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits; + state->MaxTextureUnits = ctx->Const.MaxTextureUnits; + state->MaxClipPlanes = ctx->Const.MaxClipPlanes; + state->MaxLights = ctx->Const.MaxLights; + state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices; state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB) ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM; -- cgit v1.2.3 From d8a3ada7fb0f50ce9241c452364d9dcc94eef5de Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 24 Aug 2009 11:59:58 -0700 Subject: ARB prog parser: Regenerate parser from previous commit --- src/mesa/shader/program_parse.tab.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/mesa/shader/program_parse.tab.c b/src/mesa/shader/program_parse.tab.c index dbed448113..5c604c2fd1 100644 --- a/src/mesa/shader/program_parse.tab.c +++ b/src/mesa/shader/program_parse.tab.c @@ -5156,12 +5156,12 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, ? & ctx->Const.VertexProgram : & ctx->Const.FragmentProgram; - state->MaxTextureImageUnits = 16; - state->MaxTextureCoordUnits = 8; - state->MaxTextureUnits = 8; - state->MaxClipPlanes = 6; - state->MaxLights = 8; - state->MaxProgramMatrices = 8; + state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits; + state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits; + state->MaxTextureUnits = ctx->Const.MaxTextureUnits; + state->MaxClipPlanes = ctx->Const.MaxClipPlanes; + state->MaxLights = ctx->Const.MaxLights; + state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices; state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB) ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM; -- cgit v1.2.3 From 4eb72568541803fe45d04d9e230212f4f0928ec9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Aug 2009 10:24:50 -0600 Subject: st/mesa: flush bitmap cache if Z value changes When adding a new bitmap to the cache we have to check if the Z value is changing and flush first if it is. This is a modified version of a patch from Justin Dou --- src/mesa/state_tracker/st_cb_bitmap.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 8709633557..ccf972f805 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -94,6 +94,9 @@ struct bitmap_cache GLfloat color[4]; + /** Bitmap's Z position */ + GLfloat zpos; + struct pipe_texture *texture; struct pipe_transfer *trans; @@ -104,6 +107,8 @@ struct bitmap_cache }; +/** Epsilon for Z comparisons */ +#define Z_EPSILON 1e-06 /** @@ -538,9 +543,7 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, } /* draw textured quad */ - offset = setup_bitmap_vertex_data(st, x, y, width, height, - ctx->Current.RasterPos[2], - color); + offset = setup_bitmap_vertex_data(st, x, y, width, height, z, color); util_draw_vertex_buffer(pipe, st->bitmap.vbuf, offset, PIPE_PRIM_TRIANGLE_FAN, @@ -647,7 +650,7 @@ st_flush_bitmap_cache(struct st_context *st) draw_bitmap_quad(st->ctx, cache->xpos, cache->ypos, - st->ctx->Current.RasterPos[2], + cache->zpos, BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT, cache->texture, cache->color); @@ -687,6 +690,7 @@ accum_bitmap(struct st_context *st, { struct bitmap_cache *cache = st->bitmap.cache; int px = -999, py; + const GLfloat z = st->ctx->Current.RasterPos[2]; if (width > BITMAP_CACHE_WIDTH || height > BITMAP_CACHE_HEIGHT) @@ -697,7 +701,8 @@ accum_bitmap(struct st_context *st, py = y - cache->ypos; if (px < 0 || px + width > BITMAP_CACHE_WIDTH || py < 0 || py + height > BITMAP_CACHE_HEIGHT || - !TEST_EQ_4V(st->ctx->Current.RasterColor, cache->color)) { + !TEST_EQ_4V(st->ctx->Current.RasterColor, cache->color) || + ((fabs(z - cache->zpos) > Z_EPSILON))) { /* This bitmap would extend beyond cache bounds, or the bitmap * color is changing * so flush and continue. @@ -712,6 +717,7 @@ accum_bitmap(struct st_context *st, py = (BITMAP_CACHE_HEIGHT - height) / 2; cache->xpos = x; cache->ypos = y - py; + cache->zpos = z; cache->empty = GL_FALSE; COPY_4FV(cache->color, st->ctx->Current.RasterColor); } -- cgit v1.2.3 From 0a24e5011171d71ae88ef0a43b4625ea8d37a917 Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Mon, 24 Aug 2009 11:43:02 -0600 Subject: glsl: Silence gcc uninitialized variable warning. --- src/mesa/shader/slang/slang_builtin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/shader/slang/slang_builtin.c b/src/mesa/shader/slang/slang_builtin.c index ad2e306c19..bef0f85653 100644 --- a/src/mesa/shader/slang/slang_builtin.c +++ b/src/mesa/shader/slang/slang_builtin.c @@ -436,7 +436,7 @@ emit_statevars(const char *name, int array_len, struct gl_program_parameter_list *paramList) { if (type->type == SLANG_SPEC_ARRAY) { - GLint i, pos; + GLint i, pos = -1; assert(array_len > 0); if (strcmp(name, "gl_ClipPlane") == 0) { tokens[0] = STATE_CLIPPLANE; -- cgit v1.2.3 From 93aa0fd81c44c7a5f29f30e8f730e060597b06ad Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 24 Aug 2009 12:43:57 -0600 Subject: vbo: fix divide by zero exception Fixes bug 23489. --- src/mesa/vbo/vbo_exec_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index d76c45f356..625452ac09 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -398,7 +398,7 @@ vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap ) vbo_exec_vtx_unmap( exec ); } - if (unmap) + if (unmap || exec->vtx.vertex_size == 0) exec->vtx.max_vert = 0; else exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) / -- cgit v1.2.3 From 69170a4aae5aeb765e8ab9c61a3adfddcc5830ad Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 24 Aug 2009 12:58:47 -0600 Subject: xlib: fix single buffer window resize bug When a single-buffered window was resized the new window size was never detected. This fix that, but there's still a bug which causes window contents corruption for certain window sizes... --- src/gallium/winsys/xlib/xlib_softpipe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index 277e724d2a..67fea023a3 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -303,6 +303,7 @@ xm_flush_frontbuffer(struct pipe_winsys *pws, */ XMesaContext xmctx = (XMesaContext) context_private; xlib_softpipe_display_surface(xmctx->xm_buffer, surf); + xmesa_check_and_update_buffer_size(xmctx, xmctx->xm_buffer); } -- cgit v1.2.3 From 4bccd693a72a0b42dffc849034263a68e779ca91 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 24 Aug 2009 12:48:01 -0700 Subject: ARB prog: Set error instead of falling through with incorrect value If a fragment program only parameter was queried of a vertex program (e.g., GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB) no error would be set and a random value would be returned. This caused 'glxinfo -l' to show the same values for GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB, GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB, GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB as for GL_MAX_PROGRAM_ENV_PARAMETERS_ARB. This is confusing and incorrect. --- src/mesa/shader/arbprogram.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c index 39136efada..4d8cff0700 100644 --- a/src/mesa/shader/arbprogram.c +++ b/src/mesa/shader/arbprogram.c @@ -1001,6 +1001,9 @@ _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params) _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)"); return; } + } else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)"); + return; } } -- cgit v1.2.3