diff options
48 files changed, 1785 insertions, 1813 deletions
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 8d24e311f8..e7fbf8e8b8 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -48,65 +48,198 @@ * side library and the DRI (direct rendering infrastructure). */ /*@{*/ -typedef struct __DRIdisplayRec __DRIdisplay; -typedef struct __DRIscreenRec __DRIscreen; -typedef struct __DRIcontextRec __DRIcontext; -typedef struct __DRIdrawableRec __DRIdrawable; -typedef struct __DRIdriverRec __DRIdriver; -typedef struct __DRIframebufferRec __DRIframebuffer; -typedef struct __DRIversionRec __DRIversion; -typedef struct __DRIinterfaceMethodsRec __DRIinterfaceMethods; -typedef unsigned long __DRIid; -typedef void __DRInativeDisplay; +typedef struct __DRIdisplayRec __DRIdisplay; +typedef struct __DRIscreenRec __DRIscreen; +typedef struct __DRIcontextRec __DRIcontext; +typedef struct __DRIdrawableRec __DRIdrawable; +typedef struct __DRIdriverRec __DRIdriver; +typedef struct __DRIframebufferRec __DRIframebuffer; +typedef struct __DRIversionRec __DRIversion; +typedef struct __DRIinterfaceMethodsRec __DRIinterfaceMethods; + +typedef struct __DRIextensionRec __DRIextension; +typedef struct __DRIcopySubBufferExtensionRec __DRIcopySubBufferExtension; +typedef struct __DRIswapControlExtensionRec __DRIswapControlExtension; +typedef struct __DRIallocateExtensionRec __DRIallocateExtension; +typedef struct __DRIframeTrackingExtensionRec __DRIframeTrackingExtension; +typedef struct __DRImediaStreamCounterExtensionRec __DRImediaStreamCounterExtension; +typedef struct __DRItexOffsetExtensionRec __DRItexOffsetExtension; /*@}*/ /** - * \name Functions provided by the driver loader. + * Extension struct. Drivers 'inherit' from this struct by embedding + * it as the first element in the extension struct. The + * __DRIscreen::getExtensions entry point will return a list of these + * structs and the loader can use the extensions it knows about by + * casting it to a more specific extension and optionally advertising + * the GLX extension. See below for examples. + * + * We never break API in for a DRI extension. If we need to change + * the way things work in a non-backwards compatible manner, we + * introduce a new extension. During a transition period, we can + * leave both the old and the new extension in the driver, which + * allows us to move to the new interface without having to update the + * loader(s) in lock step. + * + * However, we can add entry points to an extension over time as long + * as we don't break the old ones. As we add entry points to an + * extension, we increase the version number. The corresponding + * #define can be used to guard code that accesses the new entry + * points at compile time and the version field in the extension + * struct can be used at run-time to determine how to use the + * extension. */ -/*@{*/ +struct __DRIextensionRec { + const char *name; + int version; +}; + /** - * Type of a pointer to \c glXGetScreenDriver, as returned by - * \c glXGetProcAddress. This function is used to get the name of the DRI - * driver for the specified screen of the specified display. The driver - * name is typically used with \c glXGetDriverConfig. - * - * \sa glXGetScreenDriver, glXGetProcAddress, glXGetDriverConfig + * Used by drivers to indicate support for setting the read drawable. */ -typedef const char * (* PFNGLXGETSCREENDRIVERPROC) (__DRInativeDisplay *dpy, int scrNum); +#define __DRI_READ_DRAWABLE "DRI_ReadDrawable" +#define __DRI_READ_DRAWABLE_VERSION 1 /** - * Type of a pointer to \c glXGetDriverConfig, as returned by - * \c glXGetProcAddress. This function is used to get the XML document - * describing the configuration options available for the specified driver. - * - * \sa glXGetDriverConfig, glXGetProcAddress, glXGetScreenDriver + * Used by drivers that implement the GLX_MESA_copy_sub_buffer extension. */ -typedef const char * (* PFNGLXGETDRIVERCONFIGPROC) (const char *driverName); +#define __DRI_COPY_SUB_BUFFER "DRI_CopySubBuffer" +#define __DRI_COPY_SUB_BUFFER_VERSION 1 +struct __DRIcopySubBufferExtensionRec { + __DRIextension base; + void (*copySubBuffer)(__DRIdrawable *drawable, int x, int y, int w, int h); +}; /** - * Type of a pointer to \c glxEnableExtension, as returned by - * \c __DRIinterfaceMethods::getProcAddress. This function is used to enable - * a GLX extension on the specified screen. + * Used by drivers that implement the GLX_SGI_swap_control or + * GLX_MESA_swap_control extension. */ -typedef void (* PFNGLXSCRENABLEEXTENSIONPROC) ( void *psc, const char * name ); -/*@}*/ +#define __DRI_SWAP_CONTROL "DRI_SwapControl" +#define __DRI_SWAP_CONTROL_VERSION 1 +struct __DRIswapControlExtensionRec { + __DRIextension base; + void (*setSwapInterval)(__DRIdrawable *drawable, unsigned int inteval); + unsigned int (*getSwapInterval)(__DRIdrawable *drawable); +}; + +/** + * Used by drivers that implement the GLX_MESA_allocate_memory. + */ +#define __DRI_ALLOCATE "DRI_Allocate" +#define __DRI_ALLOCATE_VERSION 1 +struct __DRIallocateExtensionRec { + __DRIextension base; + + void *(*allocateMemory)(__DRIscreen *screen, GLsizei size, + GLfloat readfreq, GLfloat writefreq, + GLfloat priority); + + void (*freeMemory)(__DRIscreen *screen, GLvoid *pointer); + + GLuint (*memoryOffset)(__DRIscreen *screen, const GLvoid *pointer); +}; + +/** + * Used by drivers that implement the GLX_MESA_swap_frame_usage extension. + */ +#define __DRI_FRAME_TRACKING "DRI_FrameTracking" +#define __DRI_FRAME_TRACKING_VERSION 1 +struct __DRIframeTrackingExtensionRec { + __DRIextension base; + + /** + * Enable or disable frame usage tracking. + * + * \since Internal API version 20030317. + */ + int (*frameTracking)(__DRIdrawable *drawable, GLboolean enable); + + /** + * Retrieve frame usage information. + * + * \since Internal API version 20030317. + */ + int (*queryFrameTracking)(__DRIdrawable *drawable, + int64_t * sbc, int64_t * missedFrames, + float * lastMissedUsage, float * usage); +}; + + +/** + * Used by drivers that implement the GLX_SGI_video_sync extension. + */ +#define __DRI_MEDIA_STREAM_COUNTER "DRI_MediaStreamCounter" +#define __DRI_MEDIA_STREAM_COUNTER_VERSION 1 +struct __DRImediaStreamCounterExtensionRec { + __DRIextension base; + + /** + * Get the number of vertical refreshes since some point in time before + * this function was first called (i.e., system start up). + */ + int (*getMSC)(__DRIscreen *screen, int64_t *msc); + + /** + * Wait for the MSC to equal target_msc, or, if that has already passed, + * the next time (MSC % divisor) is equal to remainder. If divisor is + * zero, the function will return as soon as MSC is greater than or equal + * to target_msc. + */ + int (*waitForMSC)(__DRIdrawable *drawable, + int64_t target_msc, int64_t divisor, int64_t remainder, + int64_t * msc, int64_t * sbc); +}; + + +#define __DRI_TEX_OFFSET "DRI_TexOffset" +#define __DRI_TEX_OFFSET_VERSION 1 +struct __DRItexOffsetExtensionRec { + __DRIextension base; + + /** + * Method to override base texture image with a driver specific 'offset'. + * The depth passed in allows e.g. to ignore the alpha channel of texture + * images where the non-alpha components don't occupy a whole texel. + * + * For GLX_EXT_texture_from_pixmap with AIGLX. + */ + void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname, + unsigned long long offset, GLint depth, GLuint pitch); +}; + + +/** + * Macros for building symbol and strings. Standard CPP two step... + */ + +#define __DRI_REAL_STRINGIFY(x) # x +#define __DRI_STRINGIFY(x) __DRI_REAL_STRINGIFY(x) +#define __DRI_REAL_MAKE_VERSION(name, version) name ## _ ## version +#define __DRI_MAKE_VERSION(name, version) __DRI_REAL_MAKE_VERSION(name, version) + +#define __DRI_CREATE_NEW_SCREEN \ + __DRI_MAKE_VERSION(__driCreateNewScreen, __DRI_INTERFACE_VERSION) +#define __DRI_CREATE_NEW_SCREEN_STRING \ + __DRI_STRINGIFY(__DRI_CREATE_NEW_SCREEN) /** * \name Functions and data provided by the driver. */ /*@{*/ -typedef void *(CREATENEWSCREENFUNC)(__DRInativeDisplay *dpy, int scrn, - __DRIscreen *psc, const __GLcontextModes * modes, +#define __DRI_INTERFACE_VERSION 20070105 + +typedef void *(CREATENEWSCREENFUNC)(int scr, __DRIscreen *psc, const __DRIversion * ddx_version, const __DRIversion * dri_version, const __DRIversion * drm_version, const __DRIframebuffer * frame_buffer, void * pSAREA, int fd, int internal_api_version, const __DRIinterfaceMethods * interface, __GLcontextModes ** driver_modes); typedef CREATENEWSCREENFUNC* PFNCREATENEWSCREENFUNC; -extern CREATENEWSCREENFUNC __driCreateNewScreen_20050727; +extern CREATENEWSCREENFUNC __DRI_CREATE_NEW_SCREEN; + /** @@ -138,11 +271,6 @@ typedef void (*__DRIfuncPtr)(void); struct __DRIinterfaceMethodsRec { /** - * Get pointer to named function. - */ - __DRIfuncPtr (*getProcAddress)( const char * proc_name ); - - /** * Create a list of \c __GLcontextModes structures. */ __GLcontextModes * (*createContextModes)(unsigned count, @@ -156,11 +284,6 @@ struct __DRIinterfaceMethodsRec { */ void (*destroyContextModes)( __GLcontextModes * modes ); - /** - * Get the \c __DRIscreen for a given display and screen number. - */ - __DRIscreen *(*getScreen)(__DRInativeDisplay *dpy, int screenNum); - /** * \name Client/server protocol functions. @@ -170,47 +293,13 @@ struct __DRIinterfaceMethodsRec { * the wire protocol (e.g., EGL) will implement glorified no-op functions. */ /*@{*/ - /** - * Determine if the specified window ID still exists. - * - * \note - * Implementations may assume that the driver will only pass an ID into - * this function that actually corresponds to a window. On - * implementations where windows can only be destroyed by the DRI driver - * (e.g., EGL), this function is allowed to always return \c GL_TRUE. - */ - GLboolean (*windowExists)(__DRInativeDisplay *dpy, __DRIid draw); - - /** - * Create the server-side portion of the GL context. - */ - GLboolean (* createContext)( __DRInativeDisplay *dpy, int screenNum, - int configID, void * contextID, drm_context_t * hw_context ); - - /** - * Destroy the server-side portion of the GL context. - */ - GLboolean (* destroyContext)( __DRInativeDisplay *dpy, int screenNum, - __DRIid context ); - - /** - * Create the server-side portion of the drawable. - */ - GLboolean (*createDrawable)( __DRInativeDisplay * ndpy, int screen, - __DRIid drawable, drm_drawable_t * hHWDrawable ); - - /** - * Destroy the server-side portion of the drawable. - */ - GLboolean (*destroyDrawable)( __DRInativeDisplay * ndpy, int screen, - __DRIid drawable ); /** * This function is used to get information about the position, size, and * clip rects of a drawable. */ - GLboolean (* getDrawableInfo) ( __DRInativeDisplay *dpy, int scrn, - __DRIid draw, unsigned int * index, unsigned int * stamp, + GLboolean (* getDrawableInfo) ( __DRIdrawable *drawable, + 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, @@ -234,8 +323,8 @@ struct __DRIinterfaceMethodsRec { * the rate of the "media stream counter". In practical terms, this is * the frame refresh rate of the display. */ - GLboolean (*getMSCRate)(__DRInativeDisplay * dpy, __DRIid drawable, - int32_t * numerator, int32_t * denominator); + GLboolean (*getMSCRate)(__DRIdrawable *draw, + int32_t * numerator, int32_t * denominator); /*@}*/ /** @@ -252,11 +341,10 @@ struct __DRIinterfaceMethodsRec { * drawable was actually done directly to the front buffer (instead * of backing storage, for example) */ - void (*reportDamage)(__DRInativeDisplay * dpy, int screen, - __DRIid drawable, + void (*reportDamage)(__DRIdrawable *draw, int x, int y, drm_clip_rect_t *rects, int num_rects, - int front_buffer); + GLboolean front_buffer); }; @@ -296,21 +384,22 @@ struct __DRIscreenRec { /** * Method to destroy the private DRI screen data. */ - void (*destroyScreen)(__DRInativeDisplay *dpy, int scrn, void *screenPrivate); + void (*destroyScreen)(__DRIscreen *screen); /** - * Method to create the private DRI drawable data and initialize the - * drawable dependent methods. + * Method to get screen extensions. */ - void *(*createNewDrawable)(__DRInativeDisplay *dpy, const __GLcontextModes *modes, - __DRIid draw, __DRIdrawable *pdraw, - int renderType, const int *attrs); + const __DRIextension **(*getExtensions)(__DRIscreen *screen); /** - * Method to return a pointer to the DRI drawable data. + * Method to create the private DRI drawable data and initialize the + * drawable dependent methods. */ - __DRIdrawable *(*getDrawable)(__DRInativeDisplay *dpy, __DRIid draw, - void *drawablePrivate); + void *(*createNewDrawable)(__DRIscreen *screen, + const __GLcontextModes *modes, + __DRIdrawable *pdraw, + drm_drawable_t hwDrawable, + int renderType, const int *attrs); /** * Opaque pointer to private per screen direct rendering data. \c NULL @@ -320,59 +409,16 @@ struct __DRIscreenRec { void *private; /** - * Get the number of vertical refreshes since some point in time before - * this function was first called (i.e., system start up). - * - * \since Internal API version 20030317. - */ - int (*getMSC)( void *screenPrivate, int64_t *msc ); - - /** - * Opaque pointer that points back to the containing - * \c __GLXscreenConfigs. This data structure is shared with DRI drivers - * but \c __GLXscreenConfigs is not. However, they are needed by some GLX - * functions called by DRI drivers. - * - * \since Internal API version 20030813. - */ - void *screenConfigs; - - /** - * Functions associated with MESA_allocate_memory. - * - * \since Internal API version 20030815. - */ - /*@{*/ - void *(*allocateMemory)(__DRInativeDisplay *dpy, int scrn, GLsizei size, - GLfloat readfreq, GLfloat writefreq, - GLfloat priority); - - void (*freeMemory)(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer); - - GLuint (*memoryOffset)(__DRInativeDisplay *dpy, int scrn, const GLvoid *pointer); - /*@}*/ - - /** * Method to create the private DRI context data and initialize the * context dependent methods. * * \since Internal API version 20031201. */ - void * (*createNewContext)(__DRInativeDisplay *dpy, const __GLcontextModes *modes, + void * (*createNewContext)(__DRIscreen *screen, + const __GLcontextModes *modes, int render_type, - void *sharedPrivate, __DRIcontext *pctx); - - /** - * Method to override base texture image with a driver specific 'offset'. - * The depth passed in allows e.g. to ignore the alpha channel of texture - * images where the non-alpha components don't occupy a whole texel. - * - * For GLX_EXT_texture_from_pixmap with AIGLX. - * - * \since Internal API version 20070121. - */ - void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname, - unsigned long long offset, GLint depth, GLuint pitch); + __DRIcontext *shared, + drm_context_t hwContext, __DRIcontext *pctx); }; /** @@ -383,7 +429,7 @@ struct __DRIcontextRec { /** * Method to destroy the private DRI context data. */ - void (*destroyContext)(__DRInativeDisplay *dpy, int scrn, void *contextPrivate); + void (*destroyContext)(__DRIcontext *context); /** * Opaque pointer to private per context direct rendering data. @@ -393,27 +439,20 @@ struct __DRIcontextRec { void *private; /** - * Pointer to the mode used to create this context. - * - * \since Internal API version 20040317. - */ - const __GLcontextModes * mode; - - /** * Method to bind a DRI drawable to a DRI graphics context. * * \since Internal API version 20050727. */ - GLboolean (*bindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw, - __DRIid read, __DRIcontext *ctx); + GLboolean (*bindContext)(__DRIcontext *ctx, + __DRIdrawable *pdraw, + __DRIdrawable *pread); /** * Method to unbind a DRI drawable from a DRI graphics context. * * \since Internal API version 20050727. */ - GLboolean (*unbindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw, - __DRIid read, __DRIcontext *ctx); + GLboolean (*unbindContext)(__DRIcontext *ctx); }; /** @@ -426,12 +465,12 @@ struct __DRIdrawableRec { /** * Method to destroy the private DRI drawable data. */ - void (*destroyDrawable)(__DRInativeDisplay *dpy, void *drawablePrivate); + void (*destroyDrawable)(__DRIdrawable *drawable); /** * Method to swap the front and back buffers. */ - void (*swapBuffers)(__DRInativeDisplay *dpy, void *drawablePrivate); + void (*swapBuffers)(__DRIdrawable *drawable); /** * Opaque pointer to private per drawable direct rendering data. @@ -439,79 +478,6 @@ struct __DRIdrawableRec { * screen used to create this drawable. Never dereferenced in libGL. */ void *private; - - /** - * Get the number of completed swap buffers for this drawable. - * - * \since Internal API version 20030317. - */ - int (*getSBC)(__DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc ); - - /** - * Wait for the SBC to be greater than or equal target_sbc. - * - * \since Internal API version 20030317. - */ - int (*waitForSBC)( __DRInativeDisplay * dpy, void *drawablePriv, - int64_t target_sbc, - int64_t * msc, int64_t * sbc ); - - /** - * Wait for the MSC to equal target_msc, or, if that has already passed, - * the next time (MSC % divisor) is equal to remainder. If divisor is - * zero, the function will return as soon as MSC is greater than or equal - * to target_msc. - * - * \since Internal API version 20030317. - */ - int (*waitForMSC)( __DRInativeDisplay * dpy, void *drawablePriv, - int64_t target_msc, int64_t divisor, int64_t remainder, - int64_t * msc, int64_t * sbc ); - - /** - * Like \c swapBuffers, but does NOT have an implicit \c glFlush. Once - * rendering is complete, waits until MSC is equal to target_msc, or - * if that has already passed, waits until (MSC % divisor) is equal - * to remainder. If divisor is zero, the swap will happen as soon as - * MSC is greater than or equal to target_msc. - * - * \since Internal API version 20030317. - */ - int64_t (*swapBuffersMSC)(__DRInativeDisplay *dpy, void *drawablePrivate, - int64_t target_msc, - int64_t divisor, int64_t remainder); - - /** - * Enable or disable frame usage tracking. - * - * \since Internal API version 20030317. - */ - int (*frameTracking)(__DRInativeDisplay *dpy, void *drawablePrivate, GLboolean enable); - - /** - * Retrieve frame usage information. - * - * \since Internal API version 20030317. - */ - int (*queryFrameTracking)(__DRInativeDisplay *dpy, void *drawablePrivate, - int64_t * sbc, int64_t * missedFrames, - float * lastMissedUsage, float * usage ); - - /** - * Used by drivers that implement the GLX_SGI_swap_control or - * GLX_MESA_swap_control extension. - * - * \since Internal API version 20030317. - */ - unsigned swap_interval; - - /** - * Used by drivers that implement the GLX_MESA_copy_sub_buffer extension. - * - * \since Internal API version 20060314. - */ - void (*copySubBuffer)(__DRInativeDisplay *dpy, void *drawablePrivate, - int x, int y, int w, int h); }; #endif diff --git a/src/glx/x11/Makefile b/src/glx/x11/Makefile index 9f0943a146..00a568cdbc 100644 --- a/src/glx/x11/Makefile +++ b/src/glx/x11/Makefile @@ -31,7 +31,8 @@ SOURCES = \ glx_query.c \ glx_texture_compression.c \ dri_glx.c \ - XF86dri.c + XF86dri.c \ + glxhash.c include $(TOP)/src/mesa/sources diff --git a/src/glx/x11/XF86dri.c b/src/glx/x11/XF86dri.c index 8909a04772..5b0bf14afe 100644 --- a/src/glx/x11/XF86dri.c +++ b/src/glx/x11/XF86dri.c @@ -375,10 +375,9 @@ PUBLIC Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext) context, hHWContext ); } -PUBLIC GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, - __DRIid context ) +PUBLIC GLboolean XF86DRIDestroyContext(Display *dpy, int screen, + XID context ) { - Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRIDestroyContextReq *req; @@ -397,10 +396,9 @@ PUBLIC GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, return True; } -PUBLIC GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen, - __DRIid drawable, drm_drawable_t * hHWDrawable ) +PUBLIC GLboolean XF86DRICreateDrawable(Display *dpy, int screen, + XID drawable, drm_drawable_t * hHWDrawable ) { - Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRICreateDrawableReply rep; xXF86DRICreateDrawableReq *req; @@ -427,16 +425,36 @@ PUBLIC GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen, return True; } -PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen, - __DRIid drawable ) +static int noopErrorHandler(Display *dpy, XErrorEvent *xerr) +{ + return 0; +} + +PUBLIC GLboolean XF86DRIDestroyDrawable(Display *dpy, int screen, + XID drawable ) { - Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRIDestroyDrawableReq *req; + int (*oldXErrorHandler)(Display *, XErrorEvent *); TRACE("DestroyDrawable..."); XF86DRICheckExtension (dpy, info, False); + /* This is called from the DRI driver, which used call it like this + * + * if (windowExists(drawable)) + * destroyDrawable(drawable); + * + * which is a textbook race condition - the window may disappear + * from the server between checking for its existance and + * destroying it. Instead we change the semantics of + * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if + * the windows is gone, by wrapping the destroy call in an error + * handler. */ + + XSync(dpy, GL_FALSE); + oldXErrorHandler = XSetErrorHandler(noopErrorHandler); + LockDisplay(dpy); GetReq(XF86DRIDestroyDrawable, req); req->reqType = info->codes->major_opcode; @@ -445,6 +463,9 @@ PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen, req->drawable = drawable; UnlockDisplay(dpy); SyncHandle(); + + XSetErrorHandler(oldXErrorHandler); + TRACE("DestroyDrawable... return True"); return True; } diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index 5cf9923979..c02f105611 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -167,11 +167,8 @@ ExtractDir(int index, const char *paths, int dirLen, char *dir) * The version of the last incompatible loader/driver inteface change is * appended to the name of the \c __driCreateNewScreen function. This * prevents loaders from trying to load drivers that are too old. - * - * \todo - * Create a macro or something so that this is automatically updated. */ -static const char createNewScreenName[] = "__driCreateNewScreen_20050727"; +static const char createNewScreenName[] = __DRI_CREATE_NEW_SCREEN_STRING; /** diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index 477566cc46..0709f3ef26 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -60,6 +60,7 @@ #include "GL/internal/glcore.h" #include "glapitable.h" #include "glxextensions.h" +#include "glxhash.h" #if defined( USE_XTHREADS ) # include <X11/Xthreads.h> #elif defined( PTHREADS ) @@ -71,7 +72,9 @@ #define __GLX_MAX_TEXTURE_UNITS 32 +typedef struct __GLXscreenConfigsRec __GLXscreenConfigs; typedef struct __GLXcontextRec __GLXcontext; +typedef struct __GLXdrawableRec __GLXdrawable; typedef struct __GLXdisplayPrivateRec __GLXdisplayPrivate; typedef struct _glapi_table __GLapi; @@ -79,6 +82,9 @@ typedef struct _glapi_table __GLapi; #ifdef GLX_DIRECT_RENDERING +#define containerOf(ptr, type, member) \ + (type *)( (char *)ptr - offsetof(type,member) ) + #include <GL/internal/dri_interface.h> @@ -239,6 +245,7 @@ struct __GLXcontextRec { * Screen number. */ GLint screen; + __GLXscreenConfigs *psc; /** * \c GL_TRUE if the context was created with ImportContext, which @@ -349,6 +356,16 @@ struct __GLXcontextRec { * Per context direct rendering interface functions and data. */ __DRIcontext driContext; + + /** + * Pointer to the mode used to create this context. + */ + const __GLcontextModes * mode; + + /** + * XID for the server side drm_context_t + */ + XID hwContextID; #endif /** @@ -439,7 +456,7 @@ extern void __glFreeAttributeState(__GLXcontext *); * One of these records exists per screen of the display. It contains * a pointer to the config data for that screen (if the screen supports GL). */ -typedef struct __GLXscreenConfigsRec { +struct __GLXscreenConfigsRec { /** * GLX extension string reported by the X-server. */ @@ -456,6 +473,30 @@ typedef struct __GLXscreenConfigsRec { * Per screen direct rendering interface functions and data. */ __DRIscreen driScreen; + __glxHashTable *drawHash; + Display *dpy; + int scr; + +#ifdef __DRI_COPY_SUB_BUFFER + __DRIcopySubBufferExtension *copySubBuffer; +#endif + +#ifdef __DRI_SWAP_CONTROL + __DRIswapControlExtension *swapControl; +#endif + +#ifdef __DRI_ALLOCATE + __DRIallocateExtension *allocate; +#endif + +#ifdef __DRI_FRAME_TRACKING + __DRIframeTrackingExtension *frameTracking; +#endif + +#ifdef __DRI_MEDIA_STREAM_COUNTER + __DRImediaStreamCounterExtension *msc; +#endif + #endif /** @@ -475,7 +516,7 @@ typedef struct __GLXscreenConfigsRec { GLboolean ext_list_first_time; /*@}*/ -} __GLXscreenConfigs; +}; /** * Per display private data. One of these records exists for each display @@ -528,6 +569,18 @@ struct __GLXdisplayPrivateRec { #endif }; +#ifdef GLX_DIRECT_RENDERING + +struct __GLXdrawableRec { + XID drawable; + __GLXscreenConfigs *psc; + __DRIdrawable driDrawable; +}; + +#endif + + + void __glXFreeContext(__GLXcontext*); extern GLubyte *__glXFlushRenderBuffer(__GLXcontext*, GLubyte*); @@ -687,7 +740,7 @@ extern int __glXGetInternalVersion(void); /* Get the unadjusted system time */ extern int __glXGetUST( int64_t * ust ); -extern Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, - int32_t * numerator, int32_t * denominator); +extern GLboolean __glXGetMscRateOML(__DRIdrawable *draw, + int32_t * numerator, int32_t * denominator); #endif /* !__GLX_client_h__ */ diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index f52b71ffcd..0a49e94586 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -61,41 +61,87 @@ static const char __glXGLXClientVersion[] = "1.4"; /****************************************************************************/ + +#ifdef GLX_DIRECT_RENDERING + +static Bool windowExistsFlag; +static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr) +{ + if (xerr->error_code == BadWindow) { + windowExistsFlag = GL_FALSE; + } + return 0; +} + +/** + * Find drawables in the local hash that have been destroyed on the + * server. + * + * \param dpy Display to destroy drawables for + * \param screen Screen number to destroy drawables for + */ +static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc) +{ + XID draw; + __GLXdrawable *pdraw; + XWindowAttributes xwa; + int (*oldXErrorHandler)(Display *, XErrorEvent *); + + /* Set no-op error handler so Xlib doesn't bail out if the windows + * has alreay been destroyed on the server. */ + XSync(dpy, GL_FALSE); + oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler); + + if (__glxHashFirst(sc->drawHash, &draw, (void *)&pdraw) == 1) { + do { + windowExistsFlag = GL_TRUE; + XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */ + if (!windowExistsFlag) { + /* Destroy the local drawable data, if the drawable no + longer exists in the Xserver */ + (*pdraw->driDrawable.destroyDrawable)(&pdraw->driDrawable); + XF86DRIDestroyDrawable(dpy, sc->scr, draw); + Xfree(pdraw); + } + } while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1); + } + + XSetErrorHandler(oldXErrorHandler); +} + /** * Get the __DRIdrawable for the drawable associated with a GLXContext * * \param dpy The display associated with \c drawable. * \param drawable GLXDrawable whose __DRIdrawable part is to be retrieved. + * \param scrn_num If non-NULL, the drawables screen is stored there * \returns A pointer to the context's __DRIdrawable on success, or NULL if * the drawable is not associated with a direct-rendering context. */ - -#ifdef GLX_DIRECT_RENDERING static __DRIdrawable * GetDRIDrawable( Display *dpy, GLXDrawable drawable, int * const scrn_num ) { __GLXdisplayPrivate * const priv = __glXInitialize(dpy); + __GLXdrawable * const pdraw; + const unsigned screen_count = ScreenCount(dpy); + unsigned i; + __GLXscreenConfigs *sc; - if ( (priv != NULL) && (priv->driDisplay.private != NULL) ) { - const unsigned screen_count = ScreenCount(dpy); - unsigned i; - - for ( i = 0 ; i < screen_count ; i++ ) { - __DRIscreen * const psc = &priv->screenConfigs[i].driScreen; - __DRIdrawable * const pdraw = (psc->private != NULL) - ? (*psc->getDrawable)(dpy, drawable, psc->private) : NULL; - - if ( pdraw != NULL ) { - if ( scrn_num != NULL ) { - *scrn_num = i; - } - return pdraw; - } + if (priv == NULL || priv->driDisplay.private == NULL) + return NULL; + + for (i = 0; i < screen_count; i++) { + sc = &priv->screenConfigs[i]; + if (__glxHashLookup(sc->drawHash, drawable, (void *) &pdraw) == 0) { + if (scrn_num != NULL) + *scrn_num = i; + return &pdraw->driDrawable; } } return NULL; } + #endif @@ -330,6 +376,7 @@ CreateContext(Display *dpy, XVisualInfo *vis, int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen; __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); const __GLcontextModes * mode; + drm_context_t hwContext; /* The value of fbconfig cannot change because it is tested * later in the function. @@ -348,18 +395,32 @@ CreateContext(Display *dpy, XVisualInfo *vis, } if (psc && psc->driScreen.private) { - void * const shared = (shareList != NULL) - ? shareList->driContext.private : NULL; + __DRIcontext *shared = (shareList != NULL) + ? &shareList->driContext : NULL; + + + if (!XF86DRICreateContextWithConfig(dpy, psc->scr, + mode->fbconfigID, + &gc->hwContextID, &hwContext)) + /* gah, handle this better */ + return NULL; + gc->driContext.private = - (*psc->driScreen.createNewContext)( dpy, mode, renderType, + (*psc->driScreen.createNewContext)( &psc->driScreen, + mode, renderType, shared, + hwContext, &gc->driContext ); if (gc->driContext.private) { gc->isDirect = GL_TRUE; gc->screen = mode->screen; + gc->psc = psc; gc->vid = mode->visualID; gc->fbconfigID = mode->fbconfigID; - gc->driContext.mode = mode; + gc->mode = mode; + } + else { + XF86DRIDestroyContext(dpy, psc->scr, gc->hwContextID); } } } @@ -469,10 +530,11 @@ DestroyContext(Display *dpy, GLXContext gc) /* Destroy the direct rendering context */ if (gc->isDirect) { if (gc->driContext.private) { - (*gc->driContext.destroyContext)(dpy, gc->screen, - gc->driContext.private); + (*gc->driContext.destroyContext)(&gc->driContext); + XF86DRIDestroyContext(dpy, gc->psc->scr, gc->hwContextID); gc->driContext.private = NULL; } + GarbageCollectDRIDrawables(dpy, gc->psc); } #endif @@ -797,7 +859,7 @@ PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable) __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, NULL ); if ( pdraw != NULL ) { - (*pdraw->swapBuffers)(dpy, pdraw->private); + (*pdraw->swapBuffers)(pdraw); return; } #endif @@ -1669,16 +1731,15 @@ static int __glXSwapIntervalSGI(int interval) return GLX_BAD_VALUE; } -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_SWAP_CONTROL if ( gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); __DRIdrawable * const pdraw = GetDRIDrawable( gc->currentDpy, gc->currentDrawable, NULL ); - if ( __glXExtensionBitIsEnabled( psc, SGI_swap_control_bit ) - && (pdraw != NULL) ) { - pdraw->swap_interval = interval; + if (psc->swapControl != NULL && pdraw != NULL) { + psc->swapControl->setSwapInterval(pdraw, interval); return 0; } else { @@ -1716,7 +1777,7 @@ static int __glXSwapIntervalSGI(int interval) */ static int __glXSwapIntervalMESA(unsigned int interval) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_SWAP_CONTROL GLXContext gc = __glXGetCurrentContext(); if ( interval < 0 ) { @@ -1727,14 +1788,11 @@ static int __glXSwapIntervalMESA(unsigned int interval) __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if ( (psc != NULL) && (psc->driScreen.private != NULL) - && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) { + if ( (psc != NULL) && (psc->driScreen.private != NULL) ) { __DRIdrawable * const pdraw = - (*psc->driScreen.getDrawable)(gc->currentDpy, - gc->currentDrawable, - psc->driScreen.private); - if ( pdraw != NULL ) { - pdraw->swap_interval = interval; + GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + if (psc->swapControl != NULL && pdraw != NULL) { + psc->swapControl->setSwapInterval(pdraw, interval); return 0; } } @@ -1749,21 +1807,18 @@ static int __glXSwapIntervalMESA(unsigned int interval) static int __glXGetSwapIntervalMESA(void) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_SWAP_CONTROL GLXContext gc = __glXGetCurrentContext(); if ( (gc != NULL) && gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if ( (psc != NULL) && (psc->driScreen.private != NULL) - && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) { + if ( (psc != NULL) && (psc->driScreen.private != NULL) ) { __DRIdrawable * const pdraw = - (*psc->driScreen.getDrawable)(gc->currentDpy, - gc->currentDrawable, - psc->driScreen.private); - if ( pdraw != NULL ) { - return pdraw->swap_interval; + GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + if (psc->swapControl != NULL && pdraw != NULL) { + return psc->swapControl->getSwapInterval(pdraw); } } } @@ -1780,15 +1835,13 @@ static int __glXGetSwapIntervalMESA(void) static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable) { int status = GLX_BAD_CONTEXT; -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_FRAME_TRACKING int screen; __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if ( (pdraw != NULL) && (pdraw->frameTracking != NULL) - && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { - status = pdraw->frameTracking( dpy, pdraw->private, GL_TRUE ); - } + if (pdraw != NULL && psc->frameTracking != NULL) + status = psc->frameTracking->frameTracking(pdraw, GL_TRUE); #else (void) dpy; (void) drawable; @@ -1800,15 +1853,13 @@ static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable) static GLint __glXEndFrameTrackingMESA(Display *dpy, GLXDrawable drawable) { int status = GLX_BAD_CONTEXT; -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_FRAME_TRACKING int screen; __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if ( (pdraw != NULL) && (pdraw->frameTracking != NULL) - && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { - status = pdraw->frameTracking( dpy, pdraw->private, GL_FALSE ); - } + if (pdraw != NULL && psc->frameTracking != NULL) + status = psc->frameTracking->frameTracking(pdraw, GL_FALSE); #else (void) dpy; (void) drawable; @@ -1821,19 +1872,19 @@ static GLint __glXGetFrameUsageMESA(Display *dpy, GLXDrawable drawable, GLfloat *usage) { int status = GLX_BAD_CONTEXT; -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_FRAME_TRACKING int screen; __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL) - && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { - int64_t sbc, missedFrames; - float lastMissedUsage; + if (pdraw != NULL && psc->frameTracking != NULL) { + int64_t sbc, missedFrames; + float lastMissedUsage; - status = pdraw->queryFrameTracking( dpy, pdraw->private, &sbc, - &missedFrames, &lastMissedUsage, - usage ); + status = psc->frameTracking->queryFrameTracking(pdraw, &sbc, + &missedFrames, + &lastMissedUsage, + usage); } #else (void) dpy; @@ -1849,18 +1900,16 @@ static GLint __glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable, GLfloat *lastMissedUsage) { int status = GLX_BAD_CONTEXT; -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_FRAME_TRACKING int screen; __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL) - && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { + if (pdraw != NULL && psc->frameTracking != NULL) { float usage; - status = pdraw->queryFrameTracking( dpy, pdraw->private, sbc, - missedFrames, lastMissedUsage, - & usage ); + status = psc->frameTracking->queryFrameTracking(pdraw, sbc, missedFrames, + lastMissedUsage, &usage); } #else (void) dpy; @@ -1882,19 +1931,18 @@ static int __glXGetVideoSyncSGI(unsigned int *count) * FIXME: there should be a GLX encoding for this call. I can find no * FIXME: documentation for the GLX encoding. */ -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_MEDIA_STREAM_COUNTER GLXContext gc = __glXGetCurrentContext(); if ( (gc != NULL) && gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit ) - && psc->driScreen.private && psc->driScreen.getMSC) { + if (psc->msc != NULL && psc->driScreen.private != NULL) { int ret; int64_t temp; - ret = psc->driScreen.getMSC( psc->driScreen.private, & temp ); + ret = psc->msc->getMSC(&psc->driScreen, &temp); *count = (unsigned) temp; return (ret == 0) ? 0 : GLX_BAD_CONTEXT; } @@ -1907,7 +1955,7 @@ static int __glXGetVideoSyncSGI(unsigned int *count) static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_MEDIA_STREAM_COUNTER GLXContext gc = __glXGetCurrentContext(); if ( divisor <= 0 || remainder < 0 ) @@ -1916,20 +1964,16 @@ static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count if ( (gc != NULL) && gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit ) - && psc->driScreen.private ) { + if (psc->msc != NULL && psc->driScreen.private ) { __DRIdrawable * const pdraw = - (*psc->driScreen.getDrawable)(gc->currentDpy, - gc->currentDrawable, - psc->driScreen.private); - if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) ) { + GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + if (pdraw != NULL) { int ret; int64_t msc; int64_t sbc; - ret = (*pdraw->waitForMSC)( gc->currentDpy, pdraw->private, - 0, divisor, remainder, - & msc, & sbc ); + ret = (*psc->msc->waitForMSC)(pdraw, 0, + divisor, remainder, &msc, &sbc); *count = (unsigned) msc; return (ret == 0) ? 0 : GLX_BAD_CONTEXT; } @@ -2084,7 +2128,7 @@ static Bool __glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc) { -#ifdef GLX_DIRECT_RENDERING +#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER) __GLXdisplayPrivate * const priv = __glXInitialize(dpy); if ( priv != NULL ) { @@ -2093,11 +2137,10 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable, __GLXscreenConfigs * const psc = &priv->screenConfigs[i]; assert( (pdraw == NULL) || (i != -1) ); - return ( (pdraw && pdraw->getSBC && psc->driScreen.getMSC) - && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) - && ((*psc->driScreen.getMSC)( psc->driScreen.private, msc ) == 0) - && ((*pdraw->getSBC)( dpy, psc->driScreen.private, sbc ) == 0) - && (__glXGetUST( ust ) == 0) ); + return ( (pdraw && psc->sbc && psc->msc) + && ((*psc->msc->getMSC)(&psc->driScreen, msc) == 0) + && ((*psc->sbc->getSBC)(pdraw, sbc) == 0) + && (__glXGetUST(ust) == 0) ); } #else (void) dpy; @@ -2126,25 +2169,25 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable, * when GLX_OML_sync_control appears in the client extension string. */ -Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, - int32_t * numerator, int32_t * denominator) +GLboolean __glXGetMscRateOML(__DRIdrawable *draw, + int32_t * numerator, int32_t * denominator) { #if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE ) + __GLXdrawable *glxDraw = + containerOf(draw, __GLXdrawable, driDrawable); + __GLXscreenConfigs *psc = glxDraw->psc; + Display *dpy = psc->dpy; __GLXdisplayPrivate * const priv = __glXInitialize(dpy); if ( priv != NULL ) { XF86VidModeModeLine mode_line; int dot_clock; - int screen_num; int i; - GetDRIDrawable( dpy, drawable, & screen_num ); - if ( (screen_num != -1) - && XF86VidModeQueryVersion( dpy, & i, & i ) - && XF86VidModeGetModeLine( dpy, screen_num, & dot_clock, - & mode_line ) ) { + if (XF86VidModeQueryVersion( dpy, & i, & i ) && + XF86VidModeGetModeLine(dpy, psc->scr, &dot_clock, &mode_line) ) { unsigned n = dot_clock * 1000; unsigned d = mode_line.vtotal * mode_line.htotal; @@ -2186,13 +2229,11 @@ Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, *numerator = n; *denominator = d; - (void) drawable; return True; } } #else - (void) dpy; - (void) drawable; + (void) draw; (void) numerator; (void) denominator; #endif @@ -2204,7 +2245,7 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_SWAP_BUFFER_COUNTER int screen; __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); @@ -2219,11 +2260,10 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable, if ( divisor > 0 && remainder >= divisor ) return -1; - if ( (pdraw != NULL) && (pdraw->swapBuffersMSC != NULL) - && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) { - return (*pdraw->swapBuffersMSC)(dpy, pdraw->private, target_msc, - divisor, remainder); - } + if (pdraw != NULL && psc->counters != NULL) + return (*psc->sbc->swapBuffersMSC)(pdraw, target_msc, + divisor, remainder); + #else (void) dpy; (void) drawable; @@ -2240,7 +2280,7 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_MEDIA_STREAM_COUNTER int screen; __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); @@ -2254,10 +2294,9 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, if ( divisor > 0 && remainder >= divisor ) return False; - if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) - && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) { - ret = (*pdraw->waitForMSC)( dpy, pdraw->private, target_msc, - divisor, remainder, msc, sbc ); + if (pdraw != NULL && psc->msc != NULL) { + ret = (*psc->msc->waitForMSC)(pdraw, target_msc, + divisor, remainder, msc, sbc); /* __glXGetUST returns zero on success and non-zero on failure. * This function returns True on success and False on failure. @@ -2282,7 +2321,7 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc ) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_SWAP_BUFFER_COUNTER int screen; __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); @@ -2294,9 +2333,8 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, if ( target_sbc < 0 ) return False; - if ( (pdraw != NULL) && (pdraw->waitForSBC != NULL) - && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )) { - ret = (*pdraw->waitForSBC)( dpy, pdraw->private, target_sbc, msc, sbc ); + if (pdraw != NULL && psc->sbc != NULL) { + ret = (*psc->sbc->waitForSBC)(pdraw, target_sbc, msc, sbc); /* __glXGetUST returns zero on success and non-zero on failure. * This function returns True on success and False on failure. @@ -2324,16 +2362,14 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size, float readFreq, float writeFreq, float priority) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_ALLOCATE __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); - if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) { - if (psc && psc->driScreen.private && psc->driScreen.allocateMemory) { - return (*psc->driScreen.allocateMemory)( dpy, scrn, size, - readFreq, writeFreq, - priority ); - } - } + if (psc && psc->allocate) + return (*psc->allocate->allocateMemory)( &psc->driScreen, size, + readFreq, writeFreq, + priority ); + #else (void) dpy; (void) scrn; @@ -2349,14 +2385,12 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn, PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_ALLOCATE __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); - if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) { - if (psc && psc->driScreen.private && psc->driScreen.freeMemory) { - (*psc->driScreen.freeMemory)( dpy, scrn, pointer ); - } - } + if (psc && psc->allocate) + (*psc->allocate->freeMemory)( &psc->driScreen, pointer ); + #else (void) dpy; (void) scrn; @@ -2368,14 +2402,12 @@ PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) PUBLIC GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn, const void *pointer ) { -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_ALLOCATE __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); - if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) { - if (psc && psc->driScreen.private && psc->driScreen.memoryOffset) { - return (*psc->driScreen.memoryOffset)( dpy, scrn, pointer ); - } - } + if (psc && psc->allocate) + return (*psc->allocate->memoryOffset)( &psc->driScreen, pointer ); + #else (void) dpy; (void) scrn; @@ -2448,13 +2480,13 @@ static void __glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr; CARD8 opcode; -#ifdef GLX_DIRECT_RENDERING +#ifdef __DRI_COPY_SUB_BUFFER int screen; __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); if ( pdraw != NULL ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); - if ( __glXExtensionBitIsEnabled( psc, MESA_copy_sub_buffer_bit ) ) { - (*pdraw->copySubBuffer)(dpy, pdraw->private, x, y, width, height); + if (psc->copySubBuffer != NULL) { + (*psc->copySubBuffer->copySubBuffer)(pdraw, x, y, width, height); } return; @@ -2889,50 +2921,6 @@ int __glXGetInternalVersion(void) } - -static Bool windowExistsFlag; - -static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr) -{ - if (xerr->error_code == BadWindow) { - windowExistsFlag = GL_FALSE; - } - return 0; -} - -/** - * Determine if a window associated with a \c GLXDrawable exists on the - * X-server. This function is not used internally by libGL. It is provided - * as a utility function for DRI drivers. - * Drivers should not call this function directly. They should instead use - * \c glXGetProcAddress to obtain a pointer to the function. - * - * \param dpy Display associated with the drawable to be queried. - * \param draw \c GLXDrawable to test. - * - * \returns \c GL_TRUE if a window exists that is associated with \c draw, - * otherwise \c GL_FALSE is returned. - * - * \warning This function is not currently thread-safe. - * - * \sa glXGetProcAddress - * - * \since Internal API version 20021128. - */ -Bool __glXWindowExists(Display *dpy, GLXDrawable draw) -{ - XWindowAttributes xwa; - int (*oldXErrorHandler)(Display *, XErrorEvent *); - - XSync(dpy, GL_FALSE); - windowExistsFlag = GL_TRUE; - oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler); - XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */ - XSetErrorHandler(oldXErrorHandler); - return windowExistsFlag; -} - - /** * Get the unadjusted system time (UST). Currently, the UST is measured in * microseconds since Epoc. The actual resolution of the UST may vary from diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index 8fe10338a8..7b25ad717a 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -61,6 +61,7 @@ #include <inttypes.h> #include <sys/mman.h> #include "xf86dri.h" +#include "xf86drm.h" #include "sarea.h" #include "dri_glx.h" #endif @@ -108,10 +109,6 @@ static int _mesa_sparc_needs_init = 1; #define INIT_MESA_SPARC #endif -#ifdef GLX_DIRECT_RENDERING -static __DRIscreen *__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn); -#endif /* GLX_DIRECT_RENDERING */ - static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext gc); @@ -363,9 +360,9 @@ static void FreeScreenConfigs(__GLXdisplayPrivate *priv) #ifdef GLX_DIRECT_RENDERING /* Free the direct rendering per screen data */ if (psc->driScreen.private) - (*psc->driScreen.destroyScreen)(priv->dpy, i, - psc->driScreen.private); + (*psc->driScreen.destroyScreen)(&psc->driScreen); psc->driScreen.private = NULL; + __glxHashDestroy(psc->drawHash); #endif } XFree((char*) priv->screenConfigs); @@ -694,21 +691,8 @@ filter_modes( __GLcontextModes ** server_modes, return modes_count; } - -/** - * Implement \c __DRIinterfaceMethods::getProcAddress. - */ -static __DRIfuncPtr get_proc_address( const char * proc_name ) -{ - if (strcmp( proc_name, "glxEnableExtension" ) == 0) { - return (__DRIfuncPtr) __glXScrEnableExtension; - } - - return NULL; -} - #ifdef XDAMAGE_1_1_INTERFACE -static GLboolean has_damage_post(__DRInativeDisplay *dpy) +static GLboolean has_damage_post(Display *dpy) { static GLboolean inited = GL_FALSE; static GLboolean has_damage; @@ -730,8 +714,7 @@ static GLboolean has_damage_post(__DRInativeDisplay *dpy) } #endif /* XDAMAGE_1_1_INTERFACE */ -static void __glXReportDamage(__DRInativeDisplay *dpy, int screen, - __DRIid drawable, +static void __glXReportDamage(__DRIdrawable *driDraw, int x, int y, drm_clip_rect_t *rects, int num_rects, GLboolean front_buffer) @@ -741,6 +724,11 @@ static void __glXReportDamage(__DRInativeDisplay *dpy, int screen, XserverRegion region; int i; int x_off, y_off; + __GLXdrawable *glxDraw = + containerOf(driDraw, __GLXdrawable, driDrawable); + __GLXscreenConfigs *psc = glxDraw->psc; + Display *dpy = psc->dpy; + Drawable drawable; if (!has_damage_post(dpy)) return; @@ -748,10 +736,11 @@ static void __glXReportDamage(__DRInativeDisplay *dpy, int screen, if (front_buffer) { x_off = x; y_off = y; - drawable = RootWindow(dpy, screen); + drawable = RootWindow(dpy, psc->scr); } else{ x_off = 0; y_off = 0; + drawable = glxDraw->drawable; } xrects = malloc(sizeof(XRectangle) * num_rects); @@ -771,24 +760,35 @@ static void __glXReportDamage(__DRInativeDisplay *dpy, int screen, #endif } +static GLboolean +__glXDRIGetDrawableInfo(__DRIdrawable *drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t **pBackClipRects) +{ + __GLXdrawable *glxDraw = + containerOf(drawable, __GLXdrawable, driDrawable); + __GLXscreenConfigs *psc = glxDraw->psc; + Display *dpy = psc->dpy; + + return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable, + index, stamp, X, Y, W, H, + numClipRects, pClipRects, + backX, backY, + numBackClipRects, pBackClipRects); +} + + /** * Table of functions exported by the loader to the driver. */ static const __DRIinterfaceMethods interface_methods = { - get_proc_address, - _gl_context_modes_create, _gl_context_modes_destroy, - - __glXFindDRIScreen, - __glXWindowExists, - - XF86DRICreateContextWithConfig, - XF86DRIDestroyContext, - XF86DRICreateDrawable, - XF86DRIDestroyDrawable, - XF86DRIGetDrawableInfo, + __glXDRIGetDrawableInfo, __glXGetUST, __glXGetMscRateOML, @@ -816,7 +816,7 @@ static const __DRIinterfaceMethods interface_methods = { * returned by the client-side driver. */ static void * -CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc, +CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, __DRIdisplay * driDpy, PFNCREATENEWSCREENFUNC createNewScreen) { @@ -937,13 +937,11 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc, if ( status == 0 ) { __GLcontextModes * driver_modes = NULL; - __GLXscreenConfigs *configs = psc->screenConfigs; err_msg = "InitDriver"; err_extra = NULL; - psp = (*createNewScreen)(dpy, scrn, - psc, - configs->configs, + psp = (*createNewScreen)(scrn, + &psc->driScreen, & ddx_version, & dri_version, & drm_version, @@ -954,8 +952,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc, & interface_methods, & driver_modes ); - filter_modes( & configs->configs, - driver_modes ); + filter_modes(&psc->configs, driver_modes); _gl_context_modes_destroy( driver_modes ); } } @@ -999,6 +996,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc, return psp; } + #endif /* GLX_DIRECT_RENDERING */ @@ -1169,6 +1167,16 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) UnlockDisplay(dpy); #ifdef GLX_DIRECT_RENDERING + psc->scr = i; + psc->dpy = dpy; + /* Create drawable hash */ + psc->drawHash = __glxHashCreate(); + if ( psc->drawHash == NULL ) { + SyncHandle(); + FreeScreenConfigs(priv); + return GL_FALSE; + } + /* Initialize per screen dynamic client GLX extensions */ psc->ext_list_first_time = GL_TRUE; /* Initialize the direct rendering per screen data and functions */ @@ -1179,11 +1187,12 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) if (priv->driDisplay.createNewScreen && priv->driDisplay.createNewScreen[i]) { - psc->driScreen.screenConfigs = (void *)psc; psc->driScreen.private = - CallCreateNewScreen(dpy, i, & psc->driScreen, + CallCreateNewScreen(dpy, i, psc, & priv->driDisplay, priv->driDisplay.createNewScreen[i] ); + if (psc->driScreen.private != NULL) + __glXScrEnableDRIExtension(psc); } } #endif @@ -1506,33 +1515,6 @@ PUBLIC GLXDrawable glXGetCurrentDrawable(void) /************************************************************************/ -#ifdef GLX_DIRECT_RENDERING -/* Return the DRI per screen structure */ -__DRIscreen *__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn) -{ - __DRIscreen *pDRIScreen = NULL; - XExtDisplayInfo *info = __glXFindDisplay(dpy); - XExtData **privList, *found; - __GLXdisplayPrivate *dpyPriv; - XEDataObject dataObj; - - __glXLock(); - dataObj.display = dpy; - privList = XEHeadOfExtensionList(dataObj); - found = XFindOnExtensionList(privList, info->codes->extension); - __glXUnlock(); - - if (found) { - dpyPriv = (__GLXdisplayPrivate *)found->private_data; - pDRIScreen = &dpyPriv->screenConfigs[scrn].driScreen; - } - - return pDRIScreen; -} -#endif - -/************************************************************************/ - static Bool SendMakeCurrentRequest( Display *dpy, CARD8 opcode, GLXContextID gc, GLXContextTag old_gc, GLXDrawable draw, GLXDrawable read, xGLXMakeCurrentReply * reply ); @@ -1617,20 +1599,71 @@ static Bool SendMakeCurrentRequest(Display *dpy, CARD8 opcode, #ifdef GLX_DIRECT_RENDERING +static __DRIdrawable * +FetchDRIDrawable( Display *dpy, GLXDrawable drawable, GLXContext gc) +{ + __GLXdisplayPrivate * const priv = __glXInitialize(dpy); + __GLXdrawable *pdraw; + __GLXscreenConfigs *sc; + drm_drawable_t hwDrawable; + void *empty_attribute_list = NULL; + + if (priv == NULL || priv->driDisplay.private == NULL) + return NULL; + + sc = &priv->screenConfigs[gc->screen]; + if (__glxHashLookup(sc->drawHash, drawable, (void *) &pdraw) == 0) + return &pdraw->driDrawable; + + /* Allocate a new drawable */ + pdraw = Xmalloc(sizeof(*pdraw)); + if (!pdraw) + return NULL; + + pdraw->drawable = drawable; + pdraw->psc = sc; + + if (!XF86DRICreateDrawable(dpy, sc->scr, drawable, &hwDrawable)) + return NULL; + + /* Create a new drawable */ + pdraw->driDrawable.private = + (*sc->driScreen.createNewDrawable)(&sc->driScreen, + gc->mode, + &pdraw->driDrawable, + hwDrawable, + GLX_WINDOW_BIT, + empty_attribute_list); + + if (!pdraw->driDrawable.private) { + XF86DRIDestroyDrawable(dpy, sc->scr, drawable); + Xfree(pdraw); + return NULL; + } + + if (__glxHashInsert(sc->drawHash, drawable, pdraw)) { + (*pdraw->driDrawable.destroyDrawable)(&pdraw->driDrawable); + XF86DRIDestroyDrawable(dpy, sc->scr, drawable); + Xfree(pdraw); + return NULL; + } + + return &pdraw->driDrawable; +} + static Bool BindContextWrapper( Display *dpy, GLXContext gc, GLXDrawable draw, GLXDrawable read ) { - return (*gc->driContext.bindContext)(dpy, gc->screen, draw, read, - & gc->driContext); + __DRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc); + __DRIdrawable *pread = FetchDRIDrawable(dpy, read, gc); + + return (*gc->driContext.bindContext)(&gc->driContext, pdraw, pread); } static Bool UnbindContextWrapper( GLXContext gc ) { - return (*gc->driContext.unbindContext)(gc->currentDpy, gc->screen, - gc->currentDrawable, - gc->currentReadable, - & gc->driContext ); + return (*gc->driContext.unbindContext)(&gc->driContext); } #endif /* GLX_DIRECT_RENDERING */ @@ -1742,7 +1775,10 @@ USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, if (oldGC->isDirect) { if (oldGC->driContext.private) { (*oldGC->driContext.destroyContext) - (dpy, oldGC->screen, oldGC->driContext.private); + (&oldGC->driContext); + XF86DRIDestroyContext(oldGC->createDpy, + oldGC->psc->scr, + gc->hwContextID); oldGC->driContext.private = NULL; } } diff --git a/src/glx/x11/glxextensions.c b/src/glx/x11/glxextensions.c index 1d99b61db0..84f556e0cc 100644 --- a/src/glx/x11/glxextensions.c +++ b/src/glx/x11/glxextensions.c @@ -356,28 +356,71 @@ __glXProcessServerString( const struct extension_info * ext, } } +#ifdef GLX_DIRECT_RENDERING -/** - * Enable a named GLX extension on a given screen. - * Drivers should not call this function directly. They should instead use - * \c glXGetProcAddress to obtain a pointer to the function. - * - * \param psc Pointer to GLX per-screen record. - * \param name Name of the extension to enable. - * - * \sa glXGetProcAddress - * - * \since Internal API version 20030813. - */ void -__glXScrEnableExtension( __GLXscreenConfigs *psc, const char * name ) +__glXScrEnableDRIExtension(__GLXscreenConfigs *psc) { - __glXExtensionsCtr(); - __glXExtensionsCtrScreen(psc); - set_glx_extension( known_glx_extensions, name, strlen( name ), GL_TRUE, - psc->direct_support ); + const __DRIextension **extensions; + int i; + + __glXExtensionsCtr(); + __glXExtensionsCtrScreen(psc); + + extensions = psc->driScreen.getExtensions(&psc->driScreen); + for (i = 0; extensions[i]; i++) { +#ifdef __DRI_COPY_SUB_BUFFER + if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { + psc->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i]; + SET_BIT(psc->direct_support, MESA_copy_sub_buffer_bit); + } +#endif + +#ifdef __DRI_SWAP_CONTROL + if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) { + psc->swapControl = (__DRIswapControlExtension *) extensions[i]; + SET_BIT(psc->direct_support, SGI_swap_control_bit); + SET_BIT(psc->direct_support, MESA_swap_control_bit); + } +#endif + +#ifdef __DRI_ALLOCATE + if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) { + psc->allocate = (__DRIallocateExtension *) extensions[i]; + SET_BIT(psc->direct_support, MESA_allocate_memory_bit); + } +#endif + +#ifdef __DRI_FRAME_TRACKING + if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) { + psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i]; + SET_BIT(psc->direct_support, MESA_swap_frame_usage_bit); + } +#endif + +#ifdef __DRI_MEDIA_STREAM_COUNTER + if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) { + psc->msc = (__DRImediaStreamCounterExtension *) extensions[i]; + SET_BIT(psc->direct_support, SGI_video_sync_bit); + } +#endif + +#ifdef __DRI_SWAP_BUFFER_COUNTER + /* No driver supports this at this time and the extension is + * not defined in dri_interface.h. Will enable + * GLX_OML_sync_control if implemented. */ +#endif + +#ifdef __DRI_READ_DRAWABLE + if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { + SET_BIT(psc->direct_support, SGI_make_current_read_bit); + } +#endif + /* Ignore unknown extensions */ + } } +#endif /** * Initialize global extension support tables. diff --git a/src/glx/x11/glxextensions.h b/src/glx/x11/glxextensions.h index a4241b6b7f..144b02ad03 100644 --- a/src/glx/x11/glxextensions.h +++ b/src/glx/x11/glxextensions.h @@ -234,7 +234,11 @@ extern GLboolean __glXExtensionBitIsEnabled( struct __GLXscreenConfigsRec *psc, extern const char * __glXGetClientExtensions( void ); extern void __glXCalculateUsableExtensions( struct __GLXscreenConfigsRec *psc, GLboolean display_is_direct_capable, int server_minor_version ); -extern void __glXScrEnableExtension( struct __GLXscreenConfigsRec *psc, const char * name ); + +#ifdef GLX_DIRECT_RENDERING +extern void __glXScrEnableDRIExtension( struct __GLXscreenConfigsRec *psc ); +#endif + extern void __glXCalculateUsableGLExtensions( struct __GLXcontextRec * gc, const char * server_string, int major_version, int minor_version ); extern void __glXGetGLVersion( int * major_version, int * minor_version ); diff --git a/src/glx/x11/glxhash.c b/src/glx/x11/glxhash.c new file mode 100644 index 0000000000..1b284c5f45 --- /dev/null +++ b/src/glx/x11/glxhash.c @@ -0,0 +1,411 @@ +/* glxhash.c -- Small hash table support for integer -> integer mapping + * Taken from libdrm. + * + * Created: Sun Apr 18 09:35:45 1999 by faith@precisioninsight.com + * + * Copyright 1999 Precision Insight, 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, 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT 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. + * + * Authors: Rickard E. (Rik) Faith <faith@valinux.com> + * + * DESCRIPTION + * + * This file contains a straightforward implementation of a fixed-sized + * hash table using self-organizing linked lists [Knuth73, pp. 398-399] for + * collision resolution. There are two potentially interesting things + * about this implementation: + * + * 1) The table is power-of-two sized. Prime sized tables are more + * traditional, but do not have a significant advantage over power-of-two + * sized table, especially when double hashing is not used for collision + * resolution. + * + * 2) The hash computation uses a table of random integers [Hanson97, + * pp. 39-41]. + * + * FUTURE ENHANCEMENTS + * + * With a table size of 512, the current implementation is sufficient for a + * few hundred keys. Since this is well above the expected size of the + * tables for which this implementation was designed, the implementation of + * dynamic hash tables was postponed until the need arises. A common (and + * naive) approach to dynamic hash table implementation simply creates a + * new hash table when necessary, rehashes all the data into the new table, + * and destroys the old table. The approach in [Larson88] is superior in + * two ways: 1) only a portion of the table is expanded when needed, + * distributing the expansion cost over several insertions, and 2) portions + * of the table can be locked, enabling a scalable thread-safe + * implementation. + * + * REFERENCES + * + * [Hanson97] David R. Hanson. C Interfaces and Implementations: + * Techniques for Creating Reusable Software. Reading, Massachusetts: + * Addison-Wesley, 1997. + * + * [Knuth73] Donald E. Knuth. The Art of Computer Programming. Volume 3: + * Sorting and Searching. Reading, Massachusetts: Addison-Wesley, 1973. + * + * [Larson88] Per-Ake Larson. "Dynamic Hash Tables". CACM 31(4), April + * 1988, pp. 446-457. + * + */ + +#include "glxhash.h" + +#define HASH_MAIN 0 + +#include <stdio.h> +#include <stdlib.h> + +#define HASH_MAGIC 0xdeadbeef +#define HASH_DEBUG 0 +#define HASH_SIZE 512 /* Good for about 100 entries */ + /* If you change this value, you probably + have to change the HashHash hashing + function! */ + +#define HASH_ALLOC malloc +#define HASH_FREE free +#define HASH_RANDOM_DECL +#define HASH_RANDOM_INIT(seed) srandom(seed) +#define HASH_RANDOM random() +#define HASH_RANDOM_DESTROY + +typedef struct __glxHashBucket { + unsigned long key; + void *value; + struct __glxHashBucket *next; +} __glxHashBucket, *__glxHashBucketPtr; + +typedef struct __glxHashTable *__glxHashTablePtr; +struct __glxHashTable { + unsigned long magic; + unsigned long entries; + unsigned long hits; /* At top of linked list */ + unsigned long partials; /* Not at top of linked list */ + unsigned long misses; /* Not in table */ + __glxHashBucketPtr buckets[HASH_SIZE]; + int p0; + __glxHashBucketPtr p1; +}; + +static unsigned long HashHash(unsigned long key) +{ + unsigned long hash = 0; + unsigned long tmp = key; + static int init = 0; + static unsigned long scatter[256]; + int i; + + if (!init) { + HASH_RANDOM_DECL; + HASH_RANDOM_INIT(37); + for (i = 0; i < 256; i++) scatter[i] = HASH_RANDOM; + HASH_RANDOM_DESTROY; + ++init; + } + + while (tmp) { + hash = (hash << 1) + scatter[tmp & 0xff]; + tmp >>= 8; + } + + hash %= HASH_SIZE; +#if HASH_DEBUG + printf( "Hash(%d) = %d\n", key, hash); +#endif + return hash; +} + +__glxHashTable *__glxHashCreate(void) +{ + __glxHashTablePtr table; + int i; + + table = HASH_ALLOC(sizeof(*table)); + if (!table) return NULL; + table->magic = HASH_MAGIC; + table->entries = 0; + table->hits = 0; + table->partials = 0; + table->misses = 0; + + for (i = 0; i < HASH_SIZE; i++) table->buckets[i] = NULL; + return table; +} + +int __glxHashDestroy(__glxHashTable *t) +{ + __glxHashTablePtr table = (__glxHashTablePtr)t; + __glxHashBucketPtr bucket; + __glxHashBucketPtr next; + int i; + + if (table->magic != HASH_MAGIC) return -1; /* Bad magic */ + + for (i = 0; i < HASH_SIZE; i++) { + for (bucket = table->buckets[i]; bucket;) { + next = bucket->next; + HASH_FREE(bucket); + bucket = next; + } + } + HASH_FREE(table); + return 0; +} + +/* Find the bucket and organize the list so that this bucket is at the + top. */ + +static __glxHashBucketPtr HashFind(__glxHashTablePtr table, + unsigned long key, unsigned long *h) +{ + unsigned long hash = HashHash(key); + __glxHashBucketPtr prev = NULL; + __glxHashBucketPtr bucket; + + if (h) *h = hash; + + for (bucket = table->buckets[hash]; bucket; bucket = bucket->next) { + if (bucket->key == key) { + if (prev) { + /* Organize */ + prev->next = bucket->next; + bucket->next = table->buckets[hash]; + table->buckets[hash] = bucket; + ++table->partials; + } else { + ++table->hits; + } + return bucket; + } + prev = bucket; + } + ++table->misses; + return NULL; +} + +int __glxHashLookup(__glxHashTable *t, unsigned long key, void **value) +{ + __glxHashTablePtr table = (__glxHashTablePtr)t; + __glxHashBucketPtr bucket; + + if (!table || table->magic != HASH_MAGIC) return -1; /* Bad magic */ + + bucket = HashFind(table, key, NULL); + if (!bucket) return 1; /* Not found */ + *value = bucket->value; + return 0; /* Found */ +} + +int __glxHashInsert(__glxHashTable *t, unsigned long key, void *value) +{ + __glxHashTablePtr table = (__glxHashTablePtr)t; + __glxHashBucketPtr bucket; + unsigned long hash; + + if (table->magic != HASH_MAGIC) return -1; /* Bad magic */ + + if (HashFind(table, key, &hash)) return 1; /* Already in table */ + + bucket = HASH_ALLOC(sizeof(*bucket)); + if (!bucket) return -1; /* Error */ + bucket->key = key; + bucket->value = value; + bucket->next = table->buckets[hash]; + table->buckets[hash] = bucket; +#if HASH_DEBUG + printf("Inserted %d at %d/%p\n", key, hash, bucket); +#endif + return 0; /* Added to table */ +} + +int __glxHashDelete(__glxHashTable *t, unsigned long key) +{ + __glxHashTablePtr table = (__glxHashTablePtr)t; + unsigned long hash; + __glxHashBucketPtr bucket; + + if (table->magic != HASH_MAGIC) return -1; /* Bad magic */ + + bucket = HashFind(table, key, &hash); + + if (!bucket) return 1; /* Not found */ + + table->buckets[hash] = bucket->next; + HASH_FREE(bucket); + return 0; +} + +int __glxHashNext(__glxHashTable *t, unsigned long *key, void **value) +{ + __glxHashTablePtr table = (__glxHashTablePtr)t; + + while (table->p0 < HASH_SIZE) { + if (table->p1) { + *key = table->p1->key; + *value = table->p1->value; + table->p1 = table->p1->next; + return 1; + } + table->p1 = table->buckets[table->p0]; + ++table->p0; + } + return 0; +} + +int __glxHashFirst(__glxHashTable *t, unsigned long *key, void **value) +{ + __glxHashTablePtr table = (__glxHashTablePtr)t; + + if (table->magic != HASH_MAGIC) return -1; /* Bad magic */ + + table->p0 = 0; + table->p1 = table->buckets[0]; + return __glxHashNext(table, key, value); +} + +#if HASH_MAIN +#define DIST_LIMIT 10 +static int dist[DIST_LIMIT]; + +static void clear_dist(void) { + int i; + + for (i = 0; i < DIST_LIMIT; i++) dist[i] = 0; +} + +static int count_entries(__glxHashBucketPtr bucket) +{ + int count = 0; + + for (; bucket; bucket = bucket->next) ++count; + return count; +} + +static void update_dist(int count) +{ + if (count >= DIST_LIMIT) ++dist[DIST_LIMIT-1]; + else ++dist[count]; +} + +static void compute_dist(__glxHashTablePtr table) +{ + int i; + __glxHashBucketPtr bucket; + + printf("Entries = %ld, hits = %ld, partials = %ld, misses = %ld\n", + table->entries, table->hits, table->partials, table->misses); + clear_dist(); + for (i = 0; i < HASH_SIZE; i++) { + bucket = table->buckets[i]; + update_dist(count_entries(bucket)); + } + for (i = 0; i < DIST_LIMIT; i++) { + if (i != DIST_LIMIT-1) printf("%5d %10d\n", i, dist[i]); + else printf("other %10d\n", dist[i]); + } +} + +static void check_table(__glxHashTablePtr table, + unsigned long key, unsigned long value) +{ + unsigned long retval = 0; + int retcode = __glxHashLookup(table, key, &retval); + + switch (retcode) { + case -1: + printf("Bad magic = 0x%08lx:" + " key = %lu, expected = %lu, returned = %lu\n", + table->magic, key, value, retval); + break; + case 1: + printf("Not found: key = %lu, expected = %lu returned = %lu\n", + key, value, retval); + break; + case 0: + if (value != retval) + printf("Bad value: key = %lu, expected = %lu, returned = %lu\n", + key, value, retval); + break; + default: + printf("Bad retcode = %d: key = %lu, expected = %lu, returned = %lu\n", + retcode, key, value, retval); + break; + } +} + +int main(void) +{ + __glxHashTablePtr table; + int i; + + printf("\n***** 256 consecutive integers ****\n"); + table = __glxHashCreate(); + for (i = 0; i < 256; i++) __glxHashInsert(table, i, i); + for (i = 0; i < 256; i++) check_table(table, i, i); + for (i = 256; i >= 0; i--) check_table(table, i, i); + compute_dist(table); + __glxHashDestroy(table); + + printf("\n***** 1024 consecutive integers ****\n"); + table = __glxHashCreate(); + for (i = 0; i < 1024; i++) __glxHashInsert(table, i, i); + for (i = 0; i < 1024; i++) check_table(table, i, i); + for (i = 1024; i >= 0; i--) check_table(table, i, i); + compute_dist(table); + __glxHashDestroy(table); + + printf("\n***** 1024 consecutive page addresses (4k pages) ****\n"); + table = __glxHashCreate(); + for (i = 0; i < 1024; i++) __glxHashInsert(table, i*4096, i); + for (i = 0; i < 1024; i++) check_table(table, i*4096, i); + for (i = 1024; i >= 0; i--) check_table(table, i*4096, i); + compute_dist(table); + __glxHashDestroy(table); + + printf("\n***** 1024 random integers ****\n"); + table = __glxHashCreate(); + srandom(0xbeefbeef); + for (i = 0; i < 1024; i++) __glxHashInsert(table, random(), i); + srandom(0xbeefbeef); + for (i = 0; i < 1024; i++) check_table(table, random(), i); + srandom(0xbeefbeef); + for (i = 0; i < 1024; i++) check_table(table, random(), i); + compute_dist(table); + __glxHashDestroy(table); + + printf("\n***** 5000 random integers ****\n"); + table = __glxHashCreate(); + srandom(0xbeefbeef); + for (i = 0; i < 5000; i++) __glxHashInsert(table, random(), i); + srandom(0xbeefbeef); + for (i = 0; i < 5000; i++) check_table(table, random(), i); + srandom(0xbeefbeef); + for (i = 0; i < 5000; i++) check_table(table, random(), i); + compute_dist(table); + __glxHashDestroy(table); + + return 0; +} +#endif diff --git a/src/glx/x11/glxhash.h b/src/glx/x11/glxhash.h new file mode 100644 index 0000000000..66012fb889 --- /dev/null +++ b/src/glx/x11/glxhash.h @@ -0,0 +1,16 @@ +#ifndef _GLX_HASH_H_ +#define _GLX_HASH_H_ + + +typedef struct __glxHashTable __glxHashTable; + +/* Hash table routines */ +extern __glxHashTable *__glxHashCreate(void); +extern int __glxHashDestroy(__glxHashTable *t); +extern int __glxHashLookup(__glxHashTable *t, unsigned long key, void **value); +extern int __glxHashInsert(__glxHashTable *t, unsigned long key, void *value); +extern int __glxHashDelete(__glxHashTable *t, unsigned long key); +extern int __glxHashFirst(__glxHashTable *t, unsigned long *key, void **value); +extern int __glxHashNext(__glxHashTable *t, unsigned long *key, void **value); + +#endif /* _GLX_HASH_H_ */ diff --git a/src/glx/x11/xf86dri.h b/src/glx/x11/xf86dri.h index 0a2bb24971..69a2d74fb2 100644 --- a/src/glx/x11/xf86dri.h +++ b/src/glx/x11/xf86dri.h @@ -94,14 +94,14 @@ Bool XF86DRICreateContext( Display *dpy, int screen, Visual *visual, Bool XF86DRICreateContextWithConfig( Display *dpy, int screen, int configID, XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); -extern GLboolean XF86DRIDestroyContext( __DRInativeDisplay *dpy, int screen, - __DRIid context_id ); +extern GLboolean XF86DRIDestroyContext( Display *dpy, int screen, + XID context_id ); -extern GLboolean XF86DRICreateDrawable( __DRInativeDisplay *dpy, int screen, - __DRIid drawable, drm_drawable_t *hHWDrawable ); +extern GLboolean XF86DRICreateDrawable( Display *dpy, int screen, + XID drawable, drm_drawable_t *hHWDrawable ); -extern GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay *dpy, int screen, - __DRIid drawable); +extern GLboolean XF86DRIDestroyDrawable( Display *dpy, int screen, + XID drawable); Bool XF86DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable, unsigned int *index, unsigned int *stamp, diff --git a/src/glx/x11/xf86dristr.h b/src/glx/x11/xf86dristr.h index ac05b183b3..7e8bc557d3 100644 --- a/src/glx/x11/xf86dristr.h +++ b/src/glx/x11/xf86dristr.h @@ -50,9 +50,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 4.0.0: Original * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02 * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02 + * 5.0.0: Drop XIDs from DRI interface. */ -#define XF86DRI_MAJOR_VERSION 4 -#define XF86DRI_MINOR_VERSION 1 +#define XF86DRI_MAJOR_VERSION 5 +#define XF86DRI_MINOR_VERSION 0 #define XF86DRI_PATCH_VERSION 0 typedef struct _XF86DRIQueryVersion { diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index c30e66f172..d59ea0ddad 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -33,7 +33,7 @@ #include "drm_sarea.h" #ifndef GLX_OML_sync_control -typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRInativeDisplay *dpy, __DRIid drawable, int32_t *numerator, int32_t *denominator); +typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator); #endif /* This pointer *must* be set by the driver's __driCreateNewScreen funciton! @@ -47,22 +47,26 @@ static const int empty_attribute_list[1] = { None }; /** + * This is just a token extension used to signal that the driver + * supports setting a read drawable. + */ +const __DRIextension driReadDrawableExtension = { + __DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION +}; + +/** * Cached copy of the internal API version used by libGL and the client-side * DRI driver. */ static int api_ver = 0; -/* forward declarations */ -static int driQueryFrameTracking( __DRInativeDisplay *dpy, void *priv, - int64_t *sbc, int64_t *missedFrames, - float *lastMissedUsage, float *usage ); - -static void *driCreateNewDrawable(__DRInativeDisplay *dpy, - const __GLcontextModes *modes, - __DRIid draw, __DRIdrawable *pdraw, +static void *driCreateNewDrawable(__DRIscreen *screen, + const __GLcontextModes *modes, + __DRIdrawable *pdraw, + drm_drawable_t hwDrawable, int renderType, const int *attrs); -static void driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate); +static void driDestroyDrawable(__DRIdrawable *drawable); /** @@ -89,63 +93,6 @@ __driUtilMessage(const char *f, ...) /*****************************************************************/ -/** \name Drawable list management */ -/*****************************************************************/ -/*@{*/ - -static GLboolean __driAddDrawable(void *drawHash, __DRIdrawable *pdraw) -{ - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; - - if (drmHashInsert(drawHash, pdp->draw, pdraw)) - return GL_FALSE; - - return GL_TRUE; -} - -static __DRIdrawable *__driFindDrawable(void *drawHash, __DRIid draw) -{ - int retcode; - __DRIdrawable *pdraw; - - retcode = drmHashLookup(drawHash, draw, (void *)&pdraw); - if (retcode) - return NULL; - - return pdraw; -} - - -/** - * Find drawables in the local hash that have been destroyed on the - * server. - * - * \param drawHash Hash-table containing all know drawables. - */ -static void __driGarbageCollectDrawables(void *drawHash) -{ - __DRIid draw; - __DRInativeDisplay *dpy; - __DRIdrawable *pdraw; - - if (drmHashFirst(drawHash, &draw, (void *)&pdraw) == 1) { - do { - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; - dpy = pdp->driScreenPriv->display; - if (! (*dri_interface->windowExists)(dpy, draw)) { - /* Destroy the local drawable data, if the drawable no - longer exists in the Xserver */ - (*pdraw->destroyDrawable)(dpy, pdraw->private); - _mesa_free(pdraw); - } - } while (drmHashNext(drawHash, &draw, (void *)&pdraw) == 1); - } -} - -/*@}*/ - - -/*****************************************************************/ /** \name Context (un)binding functions */ /*****************************************************************/ /*@{*/ @@ -153,10 +100,7 @@ static void __driGarbageCollectDrawables(void *drawHash) /** * Unbind context. * - * \param dpy the display handle. - * \param scrn the screen number. - * \param draw drawable. - * \param read Current reading drawable. + * \param scrn the screen. * \param gc context. * * \return \c GL_TRUE on success, or \c GL_FALSE on failure. @@ -169,13 +113,8 @@ static void __driGarbageCollectDrawables(void *drawHash) * While casting the opaque private pointers associated with the parameters * into their respective real types it also assures they are not \c NULL. */ -static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn, - __DRIid draw, __DRIid read, - __DRIcontext *ctx) +static GLboolean driUnbindContext(__DRIcontext *ctx) { - __DRIscreen *pDRIScreen; - __DRIdrawable *pdraw; - __DRIdrawable *pread; __DRIcontextPrivate *pcp; __DRIscreenPrivate *psp; __DRIdrawablePrivate *pdp; @@ -186,39 +125,17 @@ static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn, ** calling driUnbindContext. */ - if (ctx == NULL || draw == None || read == None) { - /* ERROR!!! */ - return GL_FALSE; - } + if (ctx == NULL) + return GL_FALSE; - pDRIScreen = (*dri_interface->getScreen)(dpy, scrn); - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - /* ERROR!!! */ - return GL_FALSE; - } - - psp = (__DRIscreenPrivate *)pDRIScreen->private; pcp = (__DRIcontextPrivate *)ctx->private; - - pdraw = __driFindDrawable(psp->drawHash, draw); - if (!pdraw) { - /* ERROR!!! */ - return GL_FALSE; - } - pdp = (__DRIdrawablePrivate *)pdraw->private; - - pread = __driFindDrawable(psp->drawHash, read); - if (!pread) { - /* ERROR!!! */ - return GL_FALSE; - } - prp = (__DRIdrawablePrivate *)pread->private; - + psp = (__DRIscreenPrivate *)pcp->driScreenPriv; + pdp = (__DRIdrawablePrivate *)pcp->driDrawablePriv; + prp = (__DRIdrawablePrivate *)pcp->driReadablePriv; /* Let driver unbind drawable from context */ (*psp->DriverAPI.UnbindContext)(pcp); - if (pdp->refcount == 0) { /* ERROR!!! */ return GL_FALSE; @@ -254,72 +171,18 @@ static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn, * This function takes both a read buffer and a draw buffer. This is needed * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent * function. - * - * \bug This function calls \c driCreateNewDrawable in two places with the - * \c renderType hard-coded to \c GLX_WINDOW_BIT. Some checking might - * be needed in those places when support for pbuffers and / or pixmaps - * is added. Is it safe to assume that the drawable is a window? */ -static GLboolean DoBindContext(__DRInativeDisplay *dpy, - __DRIid draw, __DRIid read, - __DRIcontext *ctx, const __GLcontextModes * modes, - __DRIscreenPrivate *psp) +static GLboolean DoBindContext(__DRIcontext *ctx, + __DRIdrawable *pdraw, + __DRIdrawable *pread) { - __DRIdrawable *pdraw; __DRIdrawablePrivate *pdp; - __DRIdrawable *pread; __DRIdrawablePrivate *prp; __DRIcontextPrivate * const pcp = ctx->private; + __DRIscreenPrivate *psp = pcp->driScreenPriv; - - /* Find the _DRIdrawable which corresponds to the writing drawable. */ - pdraw = __driFindDrawable(psp->drawHash, draw); - if (!pdraw) { - /* Allocate a new drawable */ - pdraw = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable)); - if (!pdraw) { - /* ERROR!!! */ - return GL_FALSE; - } - - /* Create a new drawable */ - driCreateNewDrawable(dpy, modes, draw, pdraw, GLX_WINDOW_BIT, - empty_attribute_list); - if (!pdraw->private) { - /* ERROR!!! */ - _mesa_free(pdraw); - return GL_FALSE; - } - - } pdp = (__DRIdrawablePrivate *) pdraw->private; - - /* Find the _DRIdrawable which corresponds to the reading drawable. */ - if (read == draw) { - /* read buffer == draw buffer */ - prp = pdp; - } - else { - pread = __driFindDrawable(psp->drawHash, read); - if (!pread) { - /* Allocate a new drawable */ - pread = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable)); - if (!pread) { - /* ERROR!!! */ - return GL_FALSE; - } - - /* Create a new drawable */ - driCreateNewDrawable(dpy, modes, read, pread, GLX_WINDOW_BIT, - empty_attribute_list); - if (!pread->private) { - /* ERROR!!! */ - _mesa_free(pread); - return GL_FALSE; - } - } - prp = (__DRIdrawablePrivate *) pread->private; - } + prp = (__DRIdrawablePrivate *) pread->private; /* Bind the drawable to the context */ pcp->driDrawablePriv = pdp; @@ -358,30 +221,19 @@ static GLboolean DoBindContext(__DRInativeDisplay *dpy, * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent * function. */ -static GLboolean driBindContext(__DRInativeDisplay *dpy, int scrn, - __DRIid draw, __DRIid read, - __DRIcontext * ctx) +static GLboolean driBindContext(__DRIcontext * ctx, + __DRIdrawable *pdraw, + __DRIdrawable *pread) { - __DRIscreen *pDRIScreen; - /* ** Assume error checking is done properly in glXMakeCurrent before ** calling driBindContext. */ - if (ctx == NULL || draw == None || read == None) { - /* ERROR!!! */ + if (ctx == NULL || pdraw == None || pread == None) return GL_FALSE; - } - - pDRIScreen = (*dri_interface->getScreen)(dpy, scrn); - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - /* ERROR!!! */ - return GL_FALSE; - } - return DoBindContext( dpy, draw, read, ctx, ctx->mode, - (__DRIscreenPrivate *)pDRIScreen->private ); + return DoBindContext( ctx, pdraw, pread ); } /*@}*/ @@ -438,8 +290,7 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); - if (!__driFindDrawable(psp->drawHash, pdp->draw) || - ! (*dri_interface->getDrawableInfo)(pdp->display, pdp->screen, pdp->draw, + if (! (*dri_interface->getDrawableInfo)(pdp->pdraw, &pdp->index, &pdp->lastStamp, &pdp->x, &pdp->y, &pdp->w, &pdp->h, &pdp->numClipRects, &pdp->pClipRects, @@ -473,7 +324,6 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) /** * Swap buffers. * - * \param dpy the display handle. * \param drawablePrivate opaque pointer to the per-drawable private info. * * \internal @@ -481,9 +331,9 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) * * Is called directly from glXSwapBuffers(). */ -static void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate ) +static void driSwapBuffers(__DRIdrawable *drawable) { - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; + __DRIdrawablePrivate *dPriv = drawable->private; drm_clip_rect_t rect; dPriv->swapBuffers(dPriv); @@ -502,53 +352,25 @@ static void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate ) * front buffer, so we report the damage there rather than to the backing * store (if any). */ - (*dri_interface->reportDamage)(dpy, dPriv->screen, dPriv->draw, - dPriv->x, dPriv->y, + (*dri_interface->reportDamage)(dPriv->pdraw, dPriv->x, dPriv->y, &rect, 1, GL_TRUE); } /** * Called directly from a number of higher-level GLX functions. */ -static int driGetMSC( void *screenPrivate, int64_t *msc ) +static int driGetMSC( __DRIscreen *screen, int64_t *msc ) { - __DRIscreenPrivate *sPriv = (__DRIscreenPrivate *) screenPrivate; + __DRIscreenPrivate *sPriv = screen->private; return sPriv->DriverAPI.GetMSC( sPriv, msc ); } -/** - * Called directly from a number of higher-level GLX functions. - */ -static int driGetSBC( __DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc ) +static int driWaitForMSC(__DRIdrawable *drawable, int64_t target_msc, + int64_t divisor, int64_t remainder, + int64_t * msc, int64_t * sbc) { - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; - __DRIswapInfo sInfo; - int status; - - - status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo ); - *sbc = sInfo.swap_count; - - return status; -} - -static int driWaitForSBC( __DRInativeDisplay * dpy, void *drawablePriv, - int64_t target_sbc, - int64_t * msc, int64_t * sbc ) -{ - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; - - return dPriv->driScreenPriv->DriverAPI.WaitForSBC( dPriv, target_sbc, - msc, sbc ); -} - -static int driWaitForMSC( __DRInativeDisplay * dpy, void *drawablePriv, - int64_t target_msc, - int64_t divisor, int64_t remainder, - int64_t * msc, int64_t * sbc ) -{ - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; + __DRIdrawablePrivate *dPriv = drawable->private; __DRIswapInfo sInfo; int status; @@ -570,36 +392,55 @@ static int driWaitForMSC( __DRInativeDisplay * dpy, void *drawablePriv, return status; } -static int64_t driSwapBuffersMSC( __DRInativeDisplay * dpy, void *drawablePriv, - int64_t target_msc, - int64_t divisor, int64_t remainder ) +const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = { + { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION }, + driGetMSC, + driWaitForMSC, +}; + +static void driCopySubBuffer(__DRIdrawable *drawable, + int x, int y, int w, int h) { - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; + __DRIdrawablePrivate *dPriv = drawable->private; + dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h); +} - return dPriv->driScreenPriv->DriverAPI.SwapBuffersMSC( dPriv, target_msc, - divisor, - remainder ); +const __DRIcopySubBufferExtension driCopySubBufferExtension = { + { __DRI_COPY_SUB_BUFFER, __DRI_COPY_SUB_BUFFER_VERSION }, + driCopySubBuffer +}; + +static void driSetSwapInterval(__DRIdrawable *drawable, unsigned int interval) +{ + __DRIdrawablePrivate *dpriv = drawable->private; + + dpriv->swap_interval = interval; } -static void driCopySubBuffer( __DRInativeDisplay *dpy, void *drawablePrivate, - int x, int y, int w, int h) +static unsigned int driGetSwapInterval(__DRIdrawable *drawable) { - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; - dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h); - (void) dpy; + __DRIdrawablePrivate *dpriv = drawable->private; + + return dpriv->swap_interval; } +const __DRIswapControlExtension driSwapControlExtension = { + { __DRI_SWAP_CONTROL, __DRI_SWAP_CONTROL_VERSION }, + driSetSwapInterval, + driGetSwapInterval +}; + + /** * This is called via __DRIscreenRec's createNewDrawable pointer. */ -static void *driCreateNewDrawable(__DRInativeDisplay *dpy, +static void *driCreateNewDrawable(__DRIscreen *screen, const __GLcontextModes *modes, - __DRIid draw, __DRIdrawable *pdraw, + drm_drawable_t hwDrawable, int renderType, const int *attrs) { - __DRIscreen * const pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen); __DRIscreenPrivate *psp; __DRIdrawablePrivate *pdp; @@ -611,21 +452,12 @@ static void *driCreateNewDrawable(__DRInativeDisplay *dpy, */ (void) attrs; - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - return NULL; - } - pdp = (__DRIdrawablePrivate *)_mesa_malloc(sizeof(__DRIdrawablePrivate)); if (!pdp) { return NULL; } - if (!(*dri_interface->createDrawable)(dpy, modes->screen, draw, &pdp->hHWDrawable)) { - _mesa_free(pdp); - return NULL; - } - - pdp->draw = draw; + pdp->hHWDrawable = hwDrawable; pdp->pdraw = pdraw; pdp->refcount = 0; pdp->pStamp = NULL; @@ -639,16 +471,13 @@ static void *driCreateNewDrawable(__DRInativeDisplay *dpy, pdp->numBackClipRects = 0; pdp->pClipRects = NULL; pdp->pBackClipRects = NULL; - pdp->display = dpy; - pdp->screen = modes->screen; - psp = (__DRIscreenPrivate *)pDRIScreen->private; + psp = (__DRIscreenPrivate *)screen->private; pdp->driScreenPriv = psp; pdp->driContextPriv = &psp->dummyContextPriv; if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, modes, renderType == GLX_PIXMAP_BIT)) { - (void)(*dri_interface->destroyDrawable)(dpy, modes->screen, pdp->draw); _mesa_free(pdp); return NULL; } @@ -657,62 +486,26 @@ static void *driCreateNewDrawable(__DRInativeDisplay *dpy, pdraw->destroyDrawable = driDestroyDrawable; pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */ - pdraw->getSBC = driGetSBC; - pdraw->waitForSBC = driWaitForSBC; - pdraw->waitForMSC = driWaitForMSC; - pdraw->swapBuffersMSC = driSwapBuffersMSC; - pdraw->frameTracking = NULL; - pdraw->queryFrameTracking = driQueryFrameTracking; - - if (driCompareGLXAPIVersion (20060314) >= 0) - pdraw->copySubBuffer = driCopySubBuffer; - /* This special default value is replaced with the configured * default value when the drawable is first bound to a direct * rendering context. */ - pdraw->swap_interval = (unsigned)-1; + pdp->swap_interval = (unsigned)-1; pdp->swapBuffers = psp->DriverAPI.SwapBuffers; - /* Add pdraw to drawable list */ - if (!__driAddDrawable(psp->drawHash, pdraw)) { - /* ERROR!!! */ - (*pdraw->destroyDrawable)(dpy, pdp); - _mesa_free(pdp); - pdp = NULL; - pdraw->private = NULL; - } - return (void *) pdp; } -static __DRIdrawable * -driGetDrawable(__DRInativeDisplay *dpy, __DRIid draw, void *screenPrivate) -{ - __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; - - /* - ** Make sure this routine returns NULL if the drawable is not bound - ** to a direct rendering context! - */ - return __driFindDrawable(psp->drawHash, draw); -} - static void -driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate) +driDestroyDrawable(__DRIdrawable *drawable) { - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *) drawablePrivate; + __DRIdrawablePrivate *pdp = drawable->private; __DRIscreenPrivate *psp; - int scrn; if (pdp) { psp = pdp->driScreenPriv; - scrn = psp->myNum; (*psp->DriverAPI.DestroyBuffer)(pdp); - if ((*dri_interface->windowExists)(dpy, pdp->draw)) - (void)(*dri_interface->destroyDrawable)(dpy, scrn, pdp->draw); - drmHashDelete(psp->drawHash, pdp->draw); if (pdp->pClipRects) { _mesa_free(pdp->pClipRects); pdp->pClipRects = NULL; @@ -736,8 +529,6 @@ driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate) /** * Destroy the per-context private information. * - * \param dpy the display handle. - * \param scrn the screen number. * \param contextPrivate opaque pointer to the per-drawable private info. * * \internal @@ -745,14 +536,12 @@ driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate) * drmDestroyContext(), and finally frees \p contextPrivate. */ static void -driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate) +driDestroyContext(__DRIcontext *context) { - __DRIcontextPrivate *pcp = (__DRIcontextPrivate *) contextPrivate; + __DRIcontextPrivate *pcp = context->private; if (pcp) { (*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp); - __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash); - (void) (*dri_interface->destroyContext)(dpy, scrn, pcp->contextID); _mesa_free(pcp); } } @@ -765,7 +554,7 @@ driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate) * \param modes Mode used to create the new context. * \param render_type Type of rendering target. \c GLX_RGBA is the only * type likely to ever be supported for direct-rendering. - * \param sharedPrivate The shared context dependent methods or \c NULL if + * \param shared The shared context dependent methods or \c NULL if * non-existent. * \param pctx DRI context to receive the context dependent methods. * @@ -780,35 +569,23 @@ driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate) * */ static void * -driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes, - int render_type, void *sharedPrivate, __DRIcontext *pctx) +driCreateNewContext(__DRIscreen *screen, const __GLcontextModes *modes, + int render_type, __DRIcontext *shared, + drm_context_t hwContext, __DRIcontext *pctx) { - __DRIscreen *pDRIScreen; __DRIcontextPrivate *pcp; - __DRIcontextPrivate *pshare = (__DRIcontextPrivate *) sharedPrivate; + __DRIcontextPrivate *pshare = (shared != NULL) ? shared->private : NULL; __DRIscreenPrivate *psp; void * const shareCtx = (pshare != NULL) ? pshare->driverPrivate : NULL; - pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen); - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - /* ERROR!!! */ - return NULL; - } - - psp = (__DRIscreenPrivate *)pDRIScreen->private; + psp = (__DRIscreenPrivate *)screen->private; pcp = (__DRIcontextPrivate *)_mesa_malloc(sizeof(__DRIcontextPrivate)); if (!pcp) { return NULL; } - if (! (*dri_interface->createContext)(dpy, modes->screen, modes->fbconfigID, - &pcp->contextID, &pcp->hHWContext)) { - _mesa_free(pcp); - return NULL; - } - - pcp->display = dpy; + pcp->hHWContext = hwContext; pcp->driScreenPriv = psp; pcp->driDrawablePriv = NULL; @@ -817,7 +594,6 @@ driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes, */ if (!psp->dummyContextPriv.driScreenPriv) { - psp->dummyContextPriv.contextID = 0; psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context; psp->dummyContextPriv.driScreenPriv = psp; psp->dummyContextPriv.driDrawablePriv = NULL; @@ -830,19 +606,23 @@ driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes, pctx->unbindContext = driUnbindContext; if ( !(*psp->DriverAPI.CreateContext)(modes, pcp, shareCtx) ) { - (void) (*dri_interface->destroyContext)(dpy, modes->screen, - pcp->contextID); _mesa_free(pcp); return NULL; } - __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash); - return pcp; } /*@}*/ +static const __DRIextension ** +driGetExtensions(__DRIscreen *screen) +{ + __DRIscreenPrivate *psp = screen->private; + + return psp->extensions; +} + /*****************************************************************/ /** \name Screen handling functions */ /*****************************************************************/ @@ -859,9 +639,9 @@ driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes, * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls * drmClose(), and finally frees \p screenPrivate. */ -static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPrivate) +static void driDestroyScreen(__DRIscreen *screen) { - __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; + __DRIscreenPrivate *psp = screen->private; if (psp) { /* No interaction with the X-server is possible at this point. This @@ -874,14 +654,7 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); - _mesa_free(psp->pDevPriv); (void)drmCloseOnce(psp->fd); - if ( psp->modes != NULL ) { - (*dri_interface->destroyContextModes)( psp->modes ); - } - - assert(psp->drawHash); - drmHashDestroy(psp->drawHash); _mesa_free(psp); } @@ -889,9 +662,12 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv /** - * Utility function used to create a new driver-private screen structure. + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. * - * \param dpy Display pointer * \param scrn Index of the screen * \param psc DRI screen data (not driver private) * \param modes Linked list of known display modes. This list is, at a @@ -912,44 +688,32 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv * driver and libGL. * \param driverAPI Driver API functions used by other routines in dri_util.c. * - * \note - * There is no need to check the minimum API version in this function. Since - * the \c __driCreateNewScreen function is versioned, it is impossible for a - * loader that is too old to even load this driver. + * \note There is no need to check the minimum API version in this + * function. Since the name of this function is versioned, it is + * impossible for a loader that is too old to even load this driver. */ -__DRIscreenPrivate * -__driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, - __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drm_sarea_t *pSAREA, - int fd, - int internal_api_version, - const struct __DriverAPIRec *driverAPI) +PUBLIC +void * __DRI_CREATE_NEW_SCREEN( int scrn, __DRIscreen *psc, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes ) + { __DRIscreenPrivate *psp; - - + static const __DRIextension *emptyExtensionList[] = { NULL }; + dri_interface = interface; api_ver = internal_api_version; - psp = (__DRIscreenPrivate *)_mesa_malloc(sizeof(__DRIscreenPrivate)); - if (!psp) { - return NULL; - } - - /* Create the hash table */ - psp->drawHash = drmHashCreate(); - if ( psp->drawHash == NULL ) { - _mesa_free( psp ); + psp = _mesa_malloc(sizeof(*psp)); + if (!psp) return NULL; - } - psp->display = dpy; - psp->myNum = scrn; psp->psc = psc; - psp->modes = modes; /* ** NOT_DONE: This is used by the X server to detect when the client @@ -958,18 +722,9 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, */ psp->drawLockID = 1; - psp->drmMajor = drm_version->major; - psp->drmMinor = drm_version->minor; - psp->drmPatch = drm_version->patch; - psp->ddxMajor = ddx_version->major; - psp->ddxMinor = ddx_version->minor; - psp->ddxPatch = ddx_version->patch; - psp->driMajor = dri_version->major; - psp->driMinor = dri_version->minor; - psp->driPatch = dri_version->patch; - - /* install driver's callback functions */ - memcpy( &psp->DriverAPI, driverAPI, sizeof(struct __DriverAPIRec) ); + psp->drm_version = *drm_version; + psp->ddx_version = *ddx_version; + psp->dri_version = *dri_version; psp->pSAREA = pSAREA; @@ -982,7 +737,9 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, psp->pDevPriv = frame_buffer->dev_priv; psp->fbBPP = psp->fbStride * 8 / frame_buffer->width; + psp->extensions = emptyExtensionList; psp->fd = fd; + psp->myNum = scrn; /* ** Do not init dummy context here; actual initialization will be @@ -992,25 +749,19 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, psp->dummyContextPriv.driScreenPriv = NULL; psc->destroyScreen = driDestroyScreen; + psc->getExtensions = driGetExtensions; psc->createNewDrawable = driCreateNewDrawable; - psc->getDrawable = driGetDrawable; - psc->getMSC = driGetMSC; psc->createNewContext = driCreateNewContext; - if (internal_api_version >= 20070121) - psc->setTexOffset = psp->DriverAPI.setTexOffset; - - if ( (psp->DriverAPI.InitDriver != NULL) - && !(*psp->DriverAPI.InitDriver)(psp) ) { - _mesa_free( psp ); + *driver_modes = __driDriverInitScreen(psp); + if (*driver_modes == NULL) { + _mesa_free(psp); return NULL; } - return psp; } - /** * Compare the current GLX API version with a driver supplied required version. * @@ -1039,14 +790,20 @@ int driCompareGLXAPIVersion( GLint required_version ) static int -driQueryFrameTracking( __DRInativeDisplay * dpy, void * priv, - int64_t * sbc, int64_t * missedFrames, - float * lastMissedUsage, float * usage ) +driFrameTracking(__DRIdrawable *drawable, GLboolean enable) +{ + return GLX_BAD_CONTEXT; +} + +static int +driQueryFrameTracking(__DRIdrawable *drawable, + int64_t * sbc, int64_t * missedFrames, + float * lastMissedUsage, float * usage) { __DRIswapInfo sInfo; int status; int64_t ust; - __DRIdrawablePrivate * dpriv = (__DRIdrawablePrivate *) priv; + __DRIdrawablePrivate * dpriv = drawable->private; status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo ); @@ -1062,6 +819,11 @@ driQueryFrameTracking( __DRInativeDisplay * dpy, void * priv, return status; } +const __DRIframeTrackingExtension driFrameTrackingExtension = { + { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION }, + driFrameTracking, + driQueryFrameTracking +}; /** * Calculate amount of swap interval used between GLX buffer swaps. @@ -1101,9 +863,8 @@ driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust, float usage = 1.0; - if ( (*dri_interface->getMSCRate)( dPriv->display, dPriv->draw, &n, &d ) ) { - interval = (dPriv->pdraw->swap_interval != 0) - ? dPriv->pdraw->swap_interval : 1; + if ( (*dri_interface->getMSCRate)(dPriv->pdraw, &n, &d) ) { + interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1; /* We want to calculate diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 539d28d114..91992a9a24 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -67,6 +67,22 @@ typedef struct __DRIutilversionRec2 __DRIutilversion2; /** + * Driver specific entry point. Implemented by the driver. Called + * from the top level createNewScreen entry point to initialize the + * __DRIscreenPrivate struct. + */ +extern __GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp); + +/** + * Extensions. + */ +extern const __DRIextension driReadDrawableExtension; +extern const __DRIcopySubBufferExtension driCopySubBufferExtension; +extern const __DRIswapControlExtension driSwapControlExtension; +extern const __DRIframeTrackingExtension driFrameTrackingExtension; +extern const __DRImediaStreamCounterExtension driMediaStreamCounterExtension; + +/** * Used by DRI_VALIDATE_DRAWABLE_INFO */ #define DRI_VALIDATE_DRAWABLE_INFO_ONCE(pDrawPriv) \ @@ -109,11 +125,6 @@ do { \ * this structure. */ struct __DriverAPIRec { - /** - * Driver initialization callback - */ - GLboolean (*InitDriver)(__DRIscreenPrivate *driScrnPriv); - /** * Screen destruction callback */ @@ -248,7 +259,6 @@ struct __DRIdrawablePrivateRec { /** * X's drawable ID associated with this private drawable. */ - __DRIid draw; __DRIdrawable *pdraw; /** @@ -318,20 +328,15 @@ struct __DRIdrawablePrivateRec { __DRIscreenPrivate *driScreenPriv; /** - * \name Display and screen information. - * - * Basically just need these for when the locking code needs to call - * \c __driUtilUpdateDrawableInfo. + * Called via glXSwapBuffers(). */ - /*@{*/ - __DRInativeDisplay *display; - int screen; - /*@}*/ + void (*swapBuffers)( __DRIdrawablePrivate *dPriv ); /** - * Called via glXSwapBuffers(). + * Controls swap interval as used by GLX_SGI_swap_control and + * GLX_MESA_swap_control. */ - void (*swapBuffers)( __DRIdrawablePrivate *dPriv ); + unsigned int swap_interval; }; /** @@ -341,11 +346,6 @@ struct __DRIcontextPrivateRec { /** * Kernel context handle used to access the device lock. */ - __DRIid contextID; - - /** - * Kernel context handle used to access the device lock. - */ drm_context_t hHWContext; /** @@ -354,9 +354,9 @@ struct __DRIcontextPrivateRec { void *driverPrivate; /** - * This context's display pointer. + * Pointer back to the \c __DRIcontext that contains this structure. */ - __DRInativeDisplay *display; + __DRIcontext *pctx; /** * Pointer to drawable currently bound to this context for drawing. @@ -379,11 +379,6 @@ struct __DRIcontextPrivateRec { */ struct __DRIscreenPrivateRec { /** - * Display for this screen - */ - __DRInativeDisplay *display; - - /** * Current screen's number */ int myNum; @@ -394,37 +389,19 @@ struct __DRIscreenPrivateRec { struct __DriverAPIRec DriverAPI; /** - * \name DDX version * DDX / 2D driver version information. - * \todo Replace these fields with a \c __DRIversionRec. */ - /*@{*/ - int ddxMajor; - int ddxMinor; - int ddxPatch; - /*@}*/ + __DRIversion ddx_version; /** - * \name DRI version * DRI X extension version information. - * \todo Replace these fields with a \c __DRIversionRec. */ - /*@{*/ - int driMajor; - int driMinor; - int driPatch; - /*@}*/ + __DRIversion dri_version; /** - * \name DRM version * DRM (kernel module) version information. - * \todo Replace these fields with a \c __DRIversionRec. */ - /*@{*/ - int drmMajor; - int drmMinor; - int drmPatch; - /*@}*/ + __DRIversion drm_version; /** * ID used when the client sets the drawable lock. @@ -490,11 +467,6 @@ struct __DRIscreenPrivateRec { __DRIcontextPrivate dummyContextPriv; /** - * Hash table to hold the drawable information for this screen. - */ - void *drawHash; - - /** * Device-dependent private information (not stored in the SAREA). * * This pointer is never touched by the DRI layer. @@ -502,21 +474,14 @@ struct __DRIscreenPrivateRec { void *private; /** - * GLX visuals / FBConfigs for this screen. These are stored as a - * linked list. - * - * \note - * This field is \b only used in conjunction with the old interfaces. If - * the new interfaces are used, this field will be set to \c NULL and will - * not be dereferenced. + * Pointer back to the \c __DRIscreen that contains this structure. */ - __GLcontextModes *modes; + __DRIscreen *psc; /** - * Pointer back to the \c __DRIscreen that contains this structure. + * Extensions provided by this driver. */ - - __DRIscreen *psc; + const __DRIextension **extensions; }; @@ -540,8 +505,8 @@ extern void __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp); -extern __DRIscreenPrivate * __driUtilCreateNewScreen( __DRInativeDisplay *dpy, - int scrn, __DRIscreen *psc, __GLcontextModes * modes, +extern __DRIscreenPrivate * __driUtilCreateNewScreen( int scr, __DRIscreen *psc, + __GLcontextModes * modes, const __DRIversion * ddx_version, const __DRIversion * dri_version, const __DRIversion * drm_version, const __DRIframebuffer * frame_buffer, drm_sarea_t *pSAREA, int fd, int internal_api_version, diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c index e7ed545f13..3b5acfecb1 100644 --- a/src/mesa/drivers/dri/common/vblank.c +++ b/src/mesa/drivers/dri/common/vblank.c @@ -255,13 +255,13 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd ) void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags, GLuint *vbl_seq ) { - if ( priv->pdraw->swap_interval == (unsigned)-1 ) { + if ( priv->swap_interval == (unsigned)-1 ) { /* Get current vertical blank sequence */ drmVBlank vbl = { .request={ .type = DRM_VBLANK_RELATIVE, .sequence = 0 } }; do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd ); - priv->pdraw->swap_interval = (flags & (VBLANK_FLAG_THROTTLE | - VBLANK_FLAG_SYNC)) != 0 ? 1 : 0; + priv->swap_interval = (flags & (VBLANK_FLAG_THROTTLE | + VBLANK_FLAG_SYNC)) != 0 ? 1 : 0; } } @@ -277,9 +277,9 @@ driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags ) if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) { /* this must have been initialized when the drawable was first bound * to a direct rendering context. */ - assert ( priv->pdraw->swap_interval != (unsigned)-1 ); + assert ( priv->swap_interval != (unsigned)-1 ); - return priv->pdraw->swap_interval; + return priv->swap_interval; } else if ( (flags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) { return 1; diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c index 4c5323d230..3a5551eeb3 100644 --- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c +++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c @@ -605,7 +605,6 @@ void ffbXMesaUpdateState(ffbContextPtr fmesa) } static const struct __DriverAPIRec ffbAPI = { - .InitDriver = ffbInitDriver, .DestroyScreen = ffbDestroyScreen, .CreateContext = ffbCreateContext, .DestroyContext = ffbDestroyContext, @@ -704,49 +703,28 @@ ffbFillInModes( unsigned pixel_bits, unsigned depth_bits, /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \todo maybe fold this into intelInitDriver + * + * \return the __GLcontextModes supported by this driver */ -PUBLIC -void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes ) - +__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 0, 1, 1 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 0, 0, 1 }; - dri_interface = interface; - if ( ! driCheckDriDdxDrmVersions2( "ffb", - dri_version, & dri_expected, - ddx_version, & ddx_expected, - drm_version, & drm_expected ) ) { + &psp->dri_version, & dri_expected, + &psp->ddx_version, & ddx_expected, + &psp->drm_version, & drm_expected ) ) return NULL; - } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &ffbAPI); - if ( psp != NULL ) { - *driver_modes = ffbFillInModes( 32, 16, 0, GL_TRUE ); - } + psp->DriverAPI = ffbAPI; + + if (!ffbInitDriver(psp)) + return NULL; - return (void *) psp; + return ffbFillInModes( 32, 16, 0, GL_TRUE ); } diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c index f8cf050d7e..3c7ec96ff3 100644 --- a/src/mesa/drivers/dri/i810/i810screen.c +++ b/src/mesa/drivers/dri/i810/i810screen.c @@ -403,7 +403,6 @@ i810DestroyBuffer(__DRIdrawablePrivate *driDrawPriv) static const struct __DriverAPIRec i810API = { - .InitDriver = i810InitDriver, .DestroyScreen = i810DestroyScreen, .CreateContext = i810CreateContext, .DestroyContext = i810DestroyContext, @@ -421,52 +420,30 @@ static const struct __DriverAPIRec i810API = { /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. + * + * \todo maybe fold this into intelInitDriver * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \return the __GLcontextModes supported by this driver */ -PUBLIC -void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes ) - +PUBLIC __GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 1, 0, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 1, 2, 0 }; - dri_interface = interface; - if ( ! driCheckDriDdxDrmVersions2( "i810", - dri_version, & dri_expected, - ddx_version, & ddx_expected, - drm_version, & drm_expected ) ) { + &psp->dri_version, & dri_expected, + &psp->ddx_version, & ddx_expected, + &psp->drm_version, & drm_expected ) ) { return NULL; } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &i810API); - if ( psp != NULL ) { - *driver_modes = i810FillInModes( 16, - 16, 0, - 1); - driInitExtensions( NULL, card_extensions, GL_TRUE ); - } + psp->DriverAPI = i810API; + driInitExtensions( NULL, card_extensions, GL_TRUE ); + + if (!i810InitDriver(psp)) + return NULL; - return (void *) psp; + return i810FillInModes(16, 16, 0, 1); } diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c index 938bed6da7..46a67b141e 100644 --- a/src/mesa/drivers/dri/i915/intel_buffers.c +++ b/src/mesa/drivers/dri/i915/intel_buffers.c @@ -45,7 +45,7 @@ /* This block can be removed when libdrm >= 2.3.1 is required */ -#ifndef DRM_VBLANK_FLIP +#ifndef DRM_IOCTL_I915_FLIP #define DRM_VBLANK_FLIP 0x8000000 @@ -231,7 +231,7 @@ intelWindowMoved(struct intel_context *intel) } } - if (intel->intelScreen->driScrnPriv->ddxMinor >= 7) { + if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) { drmI830Sarea *sarea = intel->sarea; drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index 041a155fe7..d7af432ad6 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -613,7 +613,7 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, if (intel->ctx.DrawBuffer == &intel_fb->Base) { if (intel->driDrawable != driDrawPriv) { - if (driDrawPriv->pdraw->swap_interval == (unsigned)-1) { + if (driDrawPriv->swap_interval == (unsigned)-1) { int i; intel_fb->vblank_flags = (intel->intelScreen->irq_active != 0) diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c index 0934213c13..291441b360 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.c +++ b/src/mesa/drivers/dri/i915/intel_screen.c @@ -219,7 +219,7 @@ intel_recreate_static_regions(intelScreenPrivate *intelScreen) /* The rotated region is only used for old DDXes that didn't handle rotation \ * on their own. */ - if (intelScreen->driScrnPriv->ddxMinor < 8) { + if (intelScreen->driScrnPriv->ddx_version.minor < 8) { intelScreen->rotated_region = intel_recreate_static(intelScreen, intelScreen->rotated_region, @@ -379,7 +379,7 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, intelScreen->back.handle = sarea->back_handle; intelScreen->back.size = sarea->back_size; - if (intelScreen->driScrnPriv->ddxMinor >= 8) { + if (intelScreen->driScrnPriv->ddx_version.minor >= 8) { intelScreen->third.offset = sarea->third_offset; intelScreen->third.pitch = sarea->pitch * intelScreen->cpp; intelScreen->third.handle = sarea->third_handle; @@ -391,7 +391,7 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, intelScreen->depth.handle = sarea->depth_handle; intelScreen->depth.size = sarea->depth_size; - if (intelScreen->driScrnPriv->ddxMinor >= 9) { + if (intelScreen->driScrnPriv->ddx_version.minor >= 9) { intelScreen->front.bo_handle = sarea->front_bo_handle; intelScreen->back.bo_handle = sarea->back_bo_handle; intelScreen->third.bo_handle = sarea->third_bo_handle; @@ -421,19 +421,22 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, intelPrintSAREA(sarea); } +static const __DRIextension *intelExtensions[] = { + &driReadDrawableExtension, + &driCopySubBufferExtension.base, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + NULL +}; -static GLboolean -intelInitDriver(__DRIscreenPrivate * sPriv) + +static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) { intelScreenPrivate *intelScreen; I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; drmI830Sarea *sarea; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> - getProcAddress("glxEnableExtension")); - void *const psc = sPriv->psc->screenConfigs; - if (sPriv->devPrivSize != sizeof(I830DRIRec)) { fprintf(stderr, "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); @@ -491,7 +494,7 @@ intelInitDriver(__DRIscreenPrivate * sPriv) if (0) intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - intelScreen->drmMinor = sPriv->drmMinor; + intelScreen->drmMinor = sPriv->drm_version.minor; /* Determine if IRQs are active? */ { @@ -525,20 +528,14 @@ intelInitDriver(__DRIscreenPrivate * sPriv) } } - if (glx_enable_extension != NULL) { - (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); - (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); - (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); - } + sPriv->extensions = intelExtensions; /* If we've got a new enough DDX that's initializing TTM and giving us * object handles for the shared buffers, use that. */ intelScreen->ttm = GL_FALSE; if (getenv("INTEL_NO_TTM") == NULL && - intelScreen->driScrnPriv->ddxMinor >= 9 && + intelScreen->driScrnPriv->ddx_version.minor >= 9 && intelScreen->drmMinor >= 11 && intelScreen->front.bo_handle != -1) { intelScreen->bufmgr = intel_bufmgr_ttm_init(sPriv->fd, @@ -776,7 +773,6 @@ intelCreateContext(const __GLcontextModes * mesaVis, static const struct __DriverAPIRec intelAPI = { - .InitDriver = intelInitDriver, .DestroyScreen = intelDestroyScreen, .CreateContext = intelCreateContext, .DestroyContext = intelDestroyContext, @@ -881,65 +877,46 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \todo maybe fold this into intelInitDriver + * + * \return the __GLcontextModes supported by this driver */ -PUBLIC void * -__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, - __DRIscreen * psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes) +PUBLIC __GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 1, 5, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 1, 5, 0 }; + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - dri_interface = interface; + psp->DriverAPI = intelAPI; if (!driCheckDriDdxDrmVersions2("i915", - dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { + &psp->dri_version, &dri_expected, + &psp->ddx_version, &ddx_expected, + &psp->drm_version, &drm_expected)) { return NULL; } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &intelAPI); - - if (psp != NULL) { - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - *driver_modes = intelFillInModes(dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, 1); - - /* Calling driInitExtensions here, with a NULL context pointer, does not actually - * enable the extensions. It just makes sure that all the dispatch offsets for all - * the extensions that *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is called, but we can't - * enable the extensions until we have a context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions(NULL, card_extensions, GL_FALSE); - } + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + + if (!intelInitDriver(psp)) + return NULL; - return (void *) psp; + return intelFillInModes(dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); } struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen) diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 5dac50df32..e35f7da938 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -264,14 +264,19 @@ intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen, intelPrintSAREA(sarea); } +static const __DRIextension *intelExtensions[] = { + &driReadDrawableExtension, + &driCopySubBufferExtension.base, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + NULL +}; static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) { intelScreenPrivate *intelScreen; I830DRIPtr gDRIPriv = (I830DRIPtr)sPriv->pDevPriv; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension")); - void * const psc = sPriv->psc->screenConfigs; volatile drmI830Sarea *sarea; if (sPriv->devPrivSize != sizeof(I830DRIRec)) { @@ -317,7 +322,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) return GL_FALSE; } - intelScreen->drmMinor = sPriv->drmMinor; + intelScreen->drmMinor = sPriv->drm_version.minor; /* Determine if IRQs are active? */ { @@ -351,14 +356,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) } } - if (glx_enable_extension != NULL) { - (*glx_enable_extension)( psc, "GLX_SGI_swap_control" ); - (*glx_enable_extension)( psc, "GLX_SGI_video_sync" ); - (*glx_enable_extension)( psc, "GLX_MESA_swap_control" ); - (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" ); - (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" ); - (*glx_enable_extension)( psc, "GLX_MESA_copy_sub_buffer" ); - } + sPriv->extensions = intelExtensions; return GL_TRUE; } @@ -541,7 +539,6 @@ static GLboolean intelCreateContext( const __GLcontextModes *mesaVis, static const struct __DriverAPIRec intelAPI = { - .InitDriver = intelInitDriver, .DestroyScreen = intelDestroyScreen, .CreateContext = intelCreateContext, .DestroyContext = intelDestroyContext, @@ -640,62 +637,44 @@ intelFillInModes( unsigned pixel_bits, unsigned depth_bits, /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \todo maybe fold this into intelInitDriver + * + * \return the __GLcontextModes supported by this driver */ -PUBLIC -void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes ) - +__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 1, 6, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 1, 3, 0 }; + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - dri_interface = interface; - + psp->DriverAPI = intelAPI; if ( ! driCheckDriDdxDrmVersions2( "i915", - dri_version, & dri_expected, - ddx_version, & ddx_expected, - drm_version, & drm_expected ) ) { - return NULL; + &psp->dri_version, &dri_expected, + &psp->ddx_version, &ddx_expected, + &psp->drm_version, &drm_expected ) ) { + return NULL; } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &intelAPI); - if ( psp != NULL ) { - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - *driver_modes = intelFillInModes( dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, - GL_TRUE ); - /* Calling driInitExtensions here, with a NULL context pointer, does not actually - * enable the extensions. It just makes sure that all the dispatch offsets for all - * the extensions that *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is called, but we can't - * enable the extensions until we have a context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - intelInitExtensions(NULL, GL_FALSE); - } + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + intelInitExtensions(NULL, GL_FALSE); + + if (!intelInitDriver(psp)) + return NULL; - return (void *) psp; + return intelFillInModes( dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, + GL_TRUE ); } diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.c b/src/mesa/drivers/dri/mach64/mach64_screen.c index 4e9e216e7d..04eb081514 100644 --- a/src/mesa/drivers/dri/mach64/mach64_screen.c +++ b/src/mesa/drivers/dri/mach64/mach64_screen.c @@ -208,9 +208,7 @@ mach64CreateScreen( __DRIscreenPrivate *sPriv ) { mach64ScreenPtr mach64Screen; ATIDRIPtr serverInfo = (ATIDRIPtr)sPriv->pDevPriv; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension")); - void * const psc = sPriv->psc->screenConfigs; + int i; if (sPriv->devPrivSize != sizeof(ATIDRIRec)) { fprintf(stderr,"\nERROR! sizeof(ATIDRIRec) does not match passed size from device driver\n"); @@ -319,15 +317,14 @@ mach64CreateScreen( __DRIscreenPrivate *sPriv ) mach64Screen->driScreen = sPriv; - if ( glx_enable_extension != NULL ) { - if ( mach64Screen->irq != 0 ) { - (*glx_enable_extension)( psc, "GLX_SGI_swap_control" ); - (*glx_enable_extension)( psc, "GLX_SGI_video_sync" ); - (*glx_enable_extension)( psc, "GLX_MESA_swap_control" ); - } - - (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" ); + i = 0; + mach64Screen->extensions[i++] = &driFrameTrackingExtension.base; + if ( mach64Screen->irq != 0 ) { + mach64Screen->extensions[i++] = &driSwapControlExtension.base; + mach64Screen->extensions[i++] = &driMediaStreamCounterExtension.base; } + mach64Screen->extensions[i++] = NULL; + sPriv->extensions = mach64Screen->extensions; return mach64Screen; } @@ -477,7 +474,6 @@ mach64InitDriver( __DRIscreenPrivate *driScreen ) static struct __DriverAPIRec mach64API = { - .InitDriver = mach64InitDriver, .DestroyScreen = mach64DestroyScreen, .CreateContext = mach64CreateContext, .DestroyContext = mach64DestroyContext, @@ -495,63 +491,41 @@ static struct __DriverAPIRec mach64API = { /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \todo maybe fold this into intelInitDriver + * + * \return the __GLcontextModes supported by this driver */ -PUBLIC -void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes ) - +__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 6, 4, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 2, 0, 0 }; + ATIDRIPtr dri_priv = (ATIDRIPtr) psp->pDevPriv; - dri_interface = interface; - + psp->DriverAPI = mach64API; if ( ! driCheckDriDdxDrmVersions2( "Mach64", - dri_version, & dri_expected, - ddx_version, & ddx_expected, - drm_version, & drm_expected ) ) { + &psp->dri_version, & dri_expected, + &psp->ddx_version, & ddx_expected, + &psp->drm_version, & drm_expected ) ) { return NULL; } + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, card_extensions, GL_FALSE ); + + if (!mach64InitDriver(psp)) + return NULL; - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &mach64API); - if ( psp != NULL ) { - ATIDRIPtr dri_priv = (ATIDRIPtr) psp->pDevPriv; - *driver_modes = mach64FillInModes( dri_priv->cpp * 8, - 16, - 0, - 1); - - /* Calling driInitExtensions here, with a NULL context pointer, does not actually - * enable the extensions. It just makes sure that all the dispatch offsets for all - * the extensions that *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is called, but we can't - * enable the extensions until we have a context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions( NULL, card_extensions, GL_FALSE ); - } - - return (void *) psp; + return mach64FillInModes( dri_priv->cpp * 8, 16, 0, 1); } diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.h b/src/mesa/drivers/dri/mach64/mach64_screen.h index 5305058e2f..766554d7e4 100644 --- a/src/mesa/drivers/dri/mach64/mach64_screen.h +++ b/src/mesa/drivers/dri/mach64/mach64_screen.h @@ -73,6 +73,8 @@ typedef struct { __DRIscreenPrivate *driScreen; driOptionCache optionCache; + + const __DRIextension *extensions[4]; } mach64ScreenRec, *mach64ScreenPtr; #endif /* __MACH64_SCREEN_H__ */ diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c index f4e651afa0..99a2ea0491 100644 --- a/src/mesa/drivers/dri/mga/mga_xmesa.c +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -193,14 +193,19 @@ mgaFillInModes( unsigned pixel_bits, unsigned depth_bits, } +static const __DRIextension *mgaExtensions[] = { + &driReadDrawableExtension, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + NULL +}; + static GLboolean mgaInitDriver(__DRIscreenPrivate *sPriv) { mgaScreenPrivate *mgaScreen; MGADRIPtr serverInfo = (MGADRIPtr)sPriv->pDevPriv; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension")); - void * const psc = sPriv->psc->screenConfigs; if (sPriv->devPrivSize != sizeof(MGADRIRec)) { fprintf(stderr,"\nERROR! sizeof(MGADRIRec) does not match passed size from device driver\n"); @@ -217,7 +222,7 @@ mgaInitDriver(__DRIscreenPrivate *sPriv) mgaScreen->sPriv = sPriv; sPriv->private = (void *)mgaScreen; - if (sPriv->drmMinor >= 1) { + if (sPriv->drm_version.minor >= 1) { int ret; drm_mga_getparam_t gp; @@ -235,13 +240,7 @@ mgaInitDriver(__DRIscreenPrivate *sPriv) } } - if ( glx_enable_extension != NULL ) { - (*glx_enable_extension)( psc, "GLX_MESA_swap_control" ); - (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" ); - (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" ); - (*glx_enable_extension)( psc, "GLX_SGI_swap_control" ); - (*glx_enable_extension)( psc, "GLX_SGI_video_sync" ); - } + sPriv->extensions = mgaExtensions; if (serverInfo->chipset != MGA_CARD_TYPE_G200 && serverInfo->chipset != MGA_CARD_TYPE_G400) { @@ -274,7 +273,7 @@ mgaInitDriver(__DRIscreenPrivate *sPriv) * there is a new, in-kernel mechanism for handling the wait. */ - if (mgaScreen->sPriv->drmMinor < 2) { + if (mgaScreen->sPriv->drm_version.minor < 2) { mgaScreen->mmio.handle = serverInfo->registers.handle; mgaScreen->mmio.size = serverInfo->registers.size; if ( drmMap( sPriv->fd, @@ -935,7 +934,6 @@ void mgaGetLock( mgaContextPtr mmesa, GLuint flags ) static const struct __DriverAPIRec mgaAPI = { - .InitDriver = mgaInitDriver, .DestroyScreen = mgaDestroyScreen, .CreateContext = mgaCreateContext, .DestroyContext = mgaDestroyContext, @@ -953,69 +951,50 @@ static const struct __DriverAPIRec mgaAPI = { /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \todo maybe fold this into intelInitDriver + * + * \return the __GLcontextModes supported by this driver */ -PUBLIC -void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes ) - +__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 1, 2, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 3, 0, 0 }; + MGADRIPtr dri_priv = (MGADRIPtr) psp->pDevPriv; - dri_interface = interface; - + psp->DriverAPI = mgaAPI; if ( ! driCheckDriDdxDrmVersions2( "MGA", - dri_version, & dri_expected, - ddx_version, & ddx_expected, - drm_version, & drm_expected ) ) { + &psp->dri_version, & dri_expected, + &psp->ddx_version, & ddx_expected, + &psp->drm_version, & drm_expected ) ) return NULL; - } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &mgaAPI); - if ( psp != NULL ) { - MGADRIPtr dri_priv = (MGADRIPtr) psp->pDevPriv; - *driver_modes = mgaFillInModes( dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, - (dri_priv->backOffset != dri_priv->depthOffset) ); - - /* Calling driInitExtensions here, with a NULL context pointer, does not actually - * enable the extensions. It just makes sure that all the dispatch offsets for all - * the extensions that *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is called, but we can't - * enable the extensions until we have a context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions( NULL, card_extensions, GL_FALSE ); - driInitExtensions( NULL, g400_extensions, GL_FALSE ); - driInitSingleExtension( NULL, ARB_vp_extension ); - driInitExtensions( NULL, NV_vp_extensions, GL_FALSE ); - } + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + + driInitExtensions( NULL, card_extensions, GL_FALSE ); + driInitExtensions( NULL, g400_extensions, GL_FALSE ); + driInitSingleExtension( NULL, ARB_vp_extension ); + driInitExtensions( NULL, NV_vp_extensions, GL_FALSE ); + + if (!mgaInitDriver(psp)) + return NULL; - return (void *) psp; + return mgaFillInModes( dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, + (dri_priv->backOffset != dri_priv->depthOffset) ); } diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c index f8587fc541..679d688925 100644 --- a/src/mesa/drivers/dri/mga/mgaioctl.c +++ b/src/mesa/drivers/dri/mga/mgaioctl.c @@ -55,7 +55,7 @@ mgaSetFence( mgaContextPtr mmesa, uint32_t * fence ) { int ret = ENOSYS; - if ( mmesa->driScreen->drmMinor >= 2 ) { + if ( mmesa->driScreen->drm_version.minor >= 2 ) { ret = drmCommandWriteRead( mmesa->driScreen->fd, DRM_MGA_SET_FENCE, fence, sizeof( uint32_t )); if (ret) { @@ -73,7 +73,7 @@ mgaWaitFence( mgaContextPtr mmesa, uint32_t fence, uint32_t * curr_fence ) { int ret = ENOSYS; - if ( mmesa->driScreen->drmMinor >= 2 ) { + if ( mmesa->driScreen->drm_version.minor >= 2 ) { uint32_t temp = fence; ret = drmCommandWriteRead( mmesa->driScreen->fd, diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c index c20a76f29e..88f2175cc3 100644 --- a/src/mesa/drivers/dri/mga/mgastate.c +++ b/src/mesa/drivers/dri/mga/mgastate.c @@ -778,8 +778,6 @@ void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ) { __DRIdrawablePrivate *const driDrawable = mmesa->driDrawable; __DRIdrawablePrivate *const driReadable = mmesa->driReadable; - drm_mga_sarea_t *sarea = mmesa->sarea; - mmesa->dirty_cliprects = 0; @@ -790,9 +788,6 @@ void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ) mga_set_cliprects(mmesa); - sarea->req_drawable = driDrawable->draw; - sarea->req_draw_buffer = mmesa->draw_buffer; - mgaUpdateClipping( mmesa->glCtx ); mgaCalcViewport( mmesa->glCtx ); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 065aa81746..3e7bab63f3 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -195,7 +195,6 @@ nouveauGetSwapInfo(__DRIdrawablePrivate *dpriv, __DRIswapInfo *sInfo) } static const struct __DriverAPIRec nouveauAPI = { - .InitDriver = nouveauInitDriver, .DestroyScreen = nouveauDestroyScreen, .CreateContext = nouveauCreateContext, .DestroyContext = nouveauDestroyContext, @@ -285,81 +284,62 @@ nouveauFillInModes( unsigned pixel_bits, unsigned depth_bits, /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \todo maybe fold this into intelInitDriver + * + * \return the __GLcontextModes supported by this driver */ -PUBLIC -void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes) - +__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 1, 2, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL }; + NOUVEAUDRIPtr dri_priv = (NOUVEAUDRIPtr)psp->pDevPriv; + #if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 #error nouveau_drm.h version doesn't match expected version #endif - dri_interface = interface; if (!driCheckDriDdxDrmVersions2("nouveau", - dri_version, & dri_expected, - ddx_version, & ddx_expected, - drm_version, & drm_expected)) { + &psp->dri_version, & dri_expected, + &psp->ddx_version, & ddx_expected, + &psp->drm_version, & drm_expected)) return NULL; - } // temporary lock step versioning - if (drm_expected.patch!=drm_version->patch) { + if (drm_expected.patch != psp->drm_version.patch) { __driUtilMessage("%s: wrong DRM version, expected %d, got %d\n", - __func__, - drm_expected.patch, drm_version->patch); + __func__, + drm_expected.patch, psp->drm_version.patch); return NULL; } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &nouveauAPI); - if ( psp != NULL ) { - NOUVEAUDRIPtr dri_priv = (NOUVEAUDRIPtr)psp->pDevPriv; - - *driver_modes = nouveauFillInModes(dri_priv->bpp, - (dri_priv->bpp == 16) ? 16 : 24, - (dri_priv->bpp == 16) ? 0 : 8, - 1 - ); - - /* Calling driInitExtensions here, with a NULL context pointer, does not actually - * enable the extensions. It just makes sure that all the dispatch offsets for all - * the extensions that *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is called, but we can't - * enable the extensions until we have a context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions( NULL, common_extensions, GL_FALSE ); - driInitExtensions( NULL, nv10_extensions, GL_FALSE ); - driInitExtensions( NULL, nv10_extensions, GL_FALSE ); - driInitExtensions( NULL, nv30_extensions, GL_FALSE ); - driInitExtensions( NULL, nv40_extensions, GL_FALSE ); - driInitExtensions( NULL, nv50_extensions, GL_FALSE ); - } + psp->DriverAPI = nouveauAPI; + + /* Calling driInitExtensions here, with a NULL context + * pointer, does not actually enable the extensions. It just + * makes sure that all the dispatch offsets for all the + * extensions that *might* be enables are known. This is + * needed because the dispatch offsets need to be known when + * _mesa_context_create is called, but we can't enable the + * extensions until we have a context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, common_extensions, GL_FALSE ); + driInitExtensions( NULL, nv10_extensions, GL_FALSE ); + driInitExtensions( NULL, nv10_extensions, GL_FALSE ); + driInitExtensions( NULL, nv30_extensions, GL_FALSE ); + driInitExtensions( NULL, nv40_extensions, GL_FALSE ); + driInitExtensions( NULL, nv50_extensions, GL_FALSE ); + + if (!nouveauInitDriver(psp)) + return NULL; - return (void *) psp; + return nouveauFillInModes(dri_priv->bpp, + (dri_priv->bpp == 16) ? 16 : 24, + (dri_priv->bpp == 16) ? 0 : 8, + 1); } diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c index 95e54a6af5..c9fe11f38b 100644 --- a/src/mesa/drivers/dri/r128/r128_context.c +++ b/src/mesa/drivers/dri/r128/r128_context.c @@ -254,7 +254,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual, _tnl_allow_vertex_fog( ctx, GL_TRUE ); driInitExtensions( ctx, card_extensions, GL_TRUE ); - if (sPriv->drmMinor >= 4) + if (sPriv->drm_version.minor >= 4) _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" ); r128InitTriFuncs( ctx ); diff --git a/src/mesa/drivers/dri/r128/r128_screen.c b/src/mesa/drivers/dri/r128/r128_screen.c index 880dee85c2..9d65ebddf7 100644 --- a/src/mesa/drivers/dri/r128/r128_screen.c +++ b/src/mesa/drivers/dri/r128/r128_screen.c @@ -98,9 +98,7 @@ r128CreateScreen( __DRIscreenPrivate *sPriv ) { r128ScreenPtr r128Screen; R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension")); - void * const psc = sPriv->psc->screenConfigs; + int i; if (sPriv->devPrivSize != sizeof(R128DRIRec)) { fprintf(stderr,"\nERROR! sizeof(R128DRIRec) does not match passed size from device driver\n"); @@ -121,7 +119,7 @@ r128CreateScreen( __DRIscreenPrivate *sPriv ) r128Screen->IsPCI = r128DRIPriv->IsPCI; r128Screen->sarea_priv_offset = r128DRIPriv->sarea_priv_offset; - if (sPriv->drmMinor >= 3) { + if (sPriv->drm_version.minor >= 3) { drm_r128_getparam_t gp; int ret; @@ -226,15 +224,14 @@ r128CreateScreen( __DRIscreenPrivate *sPriv ) r128Screen->driScreen = sPriv; - if ( glx_enable_extension != NULL ) { - if ( r128Screen->irq != 0 ) { - (*glx_enable_extension)( psc, "GLX_SGI_swap_control" ); - (*glx_enable_extension)( psc, "GLX_SGI_video_sync" ); - (*glx_enable_extension)( psc, "GLX_MESA_swap_control" ); - } - - (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" ); + i = 0; + r128Screen->extensions[i++] = &driFrameTrackingExtension.base; + if ( r128Screen->irq != 0 ) { + r128Screen->extensions[i++] = &driSwapControlExtension.base; + r128Screen->extensions[i++] = &driMediaStreamCounterExtension.base; } + r128Screen->extensions[i++] = NULL; + sPriv->extensions = r128Screen->extensions; return r128Screen; } @@ -404,7 +401,6 @@ r128InitDriver( __DRIscreenPrivate *sPriv ) static struct __DriverAPIRec r128API = { - .InitDriver = r128InitDriver, .DestroyScreen = r128DestroyScreen, .CreateContext = r128CreateContext, .DestroyContext = r128DestroyContext, @@ -504,64 +500,43 @@ r128FillInModes( unsigned pixel_bits, unsigned depth_bits, /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \todo maybe fold this into intelInitDriver + * + * \return the __GLcontextModes supported by this driver */ -PUBLIC -void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes ) - +__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 4, 0, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 2, 2, 0 }; + R128DRIPtr dri_priv = (R128DRIPtr) psp->pDevPriv; - - dri_interface = interface; - + psp->DriverAPI = r128API; if ( ! driCheckDriDdxDrmVersions2( "Rage128", - dri_version, & dri_expected, - ddx_version, & ddx_expected, - drm_version, & drm_expected ) ) { + &psp->dri_version, & dri_expected, + &psp->ddx_version, & ddx_expected, + &psp->drm_version, & drm_expected ) ) return NULL; - } - - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &r128API); - if ( psp != NULL ) { - R128DRIPtr dri_priv = (R128DRIPtr) psp->pDevPriv; - *driver_modes = r128FillInModes( dri_priv->bpp, - (dri_priv->bpp == 16) ? 16 : 24, - (dri_priv->bpp == 16) ? 0 : 8, - (dri_priv->backOffset != dri_priv->depthOffset) ); - - /* Calling driInitExtensions here, with a NULL context pointer, does not actually - * enable the extensions. It just makes sure that all the dispatch offsets for all - * the extensions that *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is called, but we can't - * enable the extensions until we have a context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions( NULL, card_extensions, GL_FALSE ); - } - return (void *) psp; + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, card_extensions, GL_FALSE ); + + if (!r128InitDriver(psp)) + return NULL; + + return r128FillInModes( dri_priv->bpp, + (dri_priv->bpp == 16) ? 16 : 24, + (dri_priv->bpp == 16) ? 0 : 8, + (dri_priv->backOffset != dri_priv->depthOffset) ); } diff --git a/src/mesa/drivers/dri/r128/r128_screen.h b/src/mesa/drivers/dri/r128/r128_screen.h index 8db8eea358..c333713766 100644 --- a/src/mesa/drivers/dri/r128/r128_screen.h +++ b/src/mesa/drivers/dri/r128/r128_screen.h @@ -78,6 +78,8 @@ typedef struct { /* Configuration cache with default values for all contexts */ driOptionCache optionCache; + const __DRIextension *extensions[4]; + } r128ScreenRec, *r128ScreenPtr; diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 5a178442bd..8f43a2f312 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -277,14 +277,14 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, "def_max_anisotropy"); if ( driQueryOptionb( &rmesa->optionCache, "hyperz" ) ) { - if ( sPriv->drmMinor < 13 ) + if ( sPriv->drm_version.minor < 13 ) fprintf( stderr, "DRM version 1.%d too old to support HyperZ, " - "disabling.\n",sPriv->drmMinor ); + "disabling.\n", sPriv->drm_version.minor ); else rmesa->using_hyperz = GL_TRUE; } - if ( sPriv->drmMinor >= 15 ) + if ( sPriv->drm_version.minor >= 15 ) rmesa->texmicrotile = GL_TRUE; /* Init default driver functions then plug in our R200-specific functions @@ -317,7 +317,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, rmesa->dri.hwContext = driContextPriv->hHWContext; rmesa->dri.hwLock = &sPriv->pSAREA->lock; rmesa->dri.fd = sPriv->fd; - rmesa->dri.drmMinor = sPriv->drmMinor; + rmesa->dri.drmMinor = sPriv->drm_version.minor; rmesa->r200Screen = screen; rmesa->sarea = (drm_radeon_sarea_t *)((GLubyte *)sPriv->pSAREA + diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index 2366bde525..c9c5a86172 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -857,7 +857,7 @@ void r200Finish( GLcontext *ctx ) * the kernel data structures, and the current context to get the * device fd. */ -void *r200AllocateMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLsizei size, +void *r200AllocateMemoryMESA(__DRIscreen *screen, GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority) { @@ -899,7 +899,7 @@ void *r200AllocateMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLsizei size, /* Called via glXFreeMemoryMESA() */ -void r200FreeMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer) +void r200FreeMemoryMESA(__DRIscreen *screen, GLvoid *pointer) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa; @@ -936,7 +936,7 @@ void r200FreeMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer) } /* Called via glXGetMemoryOffsetMESA() */ -GLuint r200GetMemoryOffsetMESA(__DRInativeDisplay *dpy, int scrn, const GLvoid *pointer) +GLuint r200GetMemoryOffsetMESA(__DRIscreen *screen, const GLvoid *pointer) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa; diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.h b/src/mesa/drivers/dri/r200/r200_ioctl.h index 5ed1555f6a..bf12679947 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.h +++ b/src/mesa/drivers/dri/r200/r200_ioctl.h @@ -98,10 +98,10 @@ extern void r200WaitForIdleLocked( r200ContextPtr rmesa ); extern void r200WaitForVBlank( r200ContextPtr rmesa ); extern void r200InitIoctlFuncs( struct dd_function_table *functions ); -extern void *r200AllocateMemoryMESA( __DRInativeDisplay *dpy, int scrn, GLsizei size, GLfloat readfreq, +extern void *r200AllocateMemoryMESA( __DRIscreen *screen, GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority ); -extern void r200FreeMemoryMESA( __DRInativeDisplay *dpy, int scrn, GLvoid *pointer ); -extern GLuint r200GetMemoryOffsetMESA( __DRInativeDisplay *dpy, int scrn, const GLvoid *pointer ); +extern void r200FreeMemoryMESA( __DRIscreen *screen, GLvoid *pointer ); +extern GLuint r200GetMemoryOffsetMESA( __DRIscreen *screen, const GLvoid *pointer ); extern GLboolean r200IsGartMemory( r200ContextPtr rmesa, const GLvoid *pointer, GLint size ); diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c index e9634b427a..6dfaf3c647 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.c +++ b/src/mesa/drivers/dri/r300/radeon_context.c @@ -156,7 +156,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon, radeon->dri.hwContext = driContextPriv->hHWContext; radeon->dri.hwLock = &sPriv->pSAREA->lock; radeon->dri.fd = sPriv->fd; - radeon->dri.drmMinor = sPriv->drmMinor; + radeon->dri.drmMinor = sPriv->drm_version.minor; radeon->radeonScreen = screen; radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA + diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index b302275c71..defc82fa26 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -233,14 +233,14 @@ radeonCreateContext( const __GLcontextModes *glVisual, "def_max_anisotropy"); if ( driQueryOptionb( &rmesa->optionCache, "hyperz" ) ) { - if ( sPriv->drmMinor < 13 ) + if ( sPriv->drm_version.minor < 13 ) fprintf( stderr, "DRM version 1.%d too old to support HyperZ, " - "disabling.\n",sPriv->drmMinor ); + "disabling.\n", sPriv->drm_version.minor ); else rmesa->using_hyperz = GL_TRUE; } - if ( sPriv->drmMinor >= 15 ) + if ( sPriv->drm_version.minor >= 15 ) rmesa->texmicrotile = GL_TRUE; /* Init default driver functions then plug in our Radeon-specific functions @@ -271,7 +271,7 @@ radeonCreateContext( const __GLcontextModes *glVisual, rmesa->dri.hwContext = driContextPriv->hHWContext; rmesa->dri.hwLock = &sPriv->pSAREA->lock; rmesa->dri.fd = sPriv->fd; - rmesa->dri.drmMinor = sPriv->drmMinor; + rmesa->dri.drmMinor = sPriv->drm_version.minor; rmesa->radeonScreen = screen; rmesa->sarea = (drm_radeon_sarea_t *)((GLubyte *)sPriv->pSAREA + diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 682cf3a5ee..10d3c2b27c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -332,6 +332,21 @@ radeonFillInModes( unsigned pixel_bits, unsigned depth_bits, return modes; } +#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) +static const __DRIallocateExtension r200AllocateExtension = { + { __DRI_ALLOCATE, __DRI_ALLOCATE_VERSION }, + r200AllocateMemoryMESA, + r200FreeMemoryMESA, + r200GetMemoryOffsetMESA +}; +#endif + +#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) +static const __DRItexOffsetExtension r300texOffsetExtension = { + { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION }, + r300SetTexOffset, +}; +#endif /* Create the device specific screen private data struct. */ @@ -341,9 +356,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) radeonScreenPtr screen; RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv; unsigned char *RADEONMMIO; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension")); - void * const psc = sPriv->psc->screenConfigs; + int i; if (sPriv->devPrivSize != sizeof(RADEONDRIRec)) { fprintf(stderr,"\nERROR! sizeof(RADEONDRIRec) does not match passed size from device driver\n"); @@ -396,13 +409,13 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret); return NULL; } - screen->drmSupportsCubeMapsR200 = (sPriv->drmMinor >= 7); - screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11); - screen->drmSupportsTriPerf = (sPriv->drmMinor >= 16); - screen->drmSupportsFragShader = (sPriv->drmMinor >= 18); - screen->drmSupportsPointSprites = (sPriv->drmMinor >= 13); - screen->drmSupportsCubeMapsR100 = (sPriv->drmMinor >= 15); - screen->drmSupportsVertexProgram = (sPriv->drmMinor >= 25); + screen->drmSupportsCubeMapsR200 = (sPriv->drm_version.minor >= 7); + screen->drmSupportsBlendColor = (sPriv->drm_version.minor >= 11); + screen->drmSupportsTriPerf = (sPriv->drm_version.minor >= 16); + screen->drmSupportsFragShader = (sPriv->drm_version.minor >= 18); + screen->drmSupportsPointSprites = (sPriv->drm_version.minor >= 13); + screen->drmSupportsCubeMapsR100 = (sPriv->drm_version.minor >= 15); + screen->drmSupportsVertexProgram = (sPriv->drm_version.minor >= 25); } screen->mmio.handle = dri_priv->registerHandle; @@ -667,7 +680,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) return NULL; } if ((screen->chip_family == CHIP_FAMILY_R350 || screen->chip_family == CHIP_FAMILY_R300) && - sPriv->ddxMinor < 2) { + sPriv->ddx_version.minor < 2) { fprintf(stderr, "xf86-video-ati-6.6.2 or newer needed for Radeon 9500/9700/9800 cards.\n"); return NULL; } @@ -684,7 +697,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) screen->fbLocation = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16; - if ( sPriv->drmMinor >= 10 ) { + if ( sPriv->drm_version.minor >= 10 ) { drm_radeon_setparam_t sp; sp.param = RADEON_SETPARAM_FB_LOCATION; @@ -702,7 +715,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) screen->depthPitch = dri_priv->depthPitch; /* Check if ddx has set up a surface reg to cover depth buffer */ - screen->depthHasSurface = ((sPriv->ddxMajor > 4) && + screen->depthHasSurface = ((sPriv->ddx_version.major > 4) && (screen->chip_flags & RADEON_CHIPSET_TCL)); if ( dri_priv->textureSize == 0 ) { @@ -732,29 +745,28 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) dri_priv->log2GARTTexGran; } - if ( glx_enable_extension != NULL ) { - if ( screen->irq != 0 ) { - (*glx_enable_extension)( psc, "GLX_SGI_swap_control" ); - (*glx_enable_extension)( psc, "GLX_SGI_video_sync" ); - (*glx_enable_extension)( psc, "GLX_MESA_swap_control" ); - } - - (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" ); - if (IS_R200_CLASS(screen)) - (*glx_enable_extension)( psc, "GLX_MESA_allocate_memory" ); + i = 0; + screen->extensions[i++] = &driCopySubBufferExtension.base; + screen->extensions[i++] = &driFrameTrackingExtension.base; + screen->extensions[i++] = &driReadDrawableExtension; - (*glx_enable_extension)( psc, "GLX_MESA_copy_sub_buffer" ); - (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" ); + if ( screen->irq != 0 ) { + screen->extensions[i++] = &driSwapControlExtension.base; + screen->extensions[i++] = &driMediaStreamCounterExtension.base; } #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) - if (IS_R200_CLASS(screen)) { - sPriv->psc->allocateMemory = (void *) r200AllocateMemoryMESA; - sPriv->psc->freeMemory = (void *) r200FreeMemoryMESA; - sPriv->psc->memoryOffset = (void *) r200GetMemoryOffsetMESA; - } + if (IS_R200_CLASS(screen)) + screen->extensions[i++] = &r200AllocateExtension.base; +#endif + +#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) + screen->extensions[i++] = &r300texOffsetExtension.base; #endif + screen->extensions[i++] = NULL; + sPriv->extensions = screen->extensions; + screen->driScreen = sPriv; screen->sarea_priv_offset = dri_priv->sarea_priv_offset; return screen; @@ -939,7 +951,6 @@ static void radeonDestroyContext(__DRIcontextPrivate * driContextPriv) #if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)) static struct __DriverAPIRec radeonAPI = { - .InitDriver = radeonInitDriver, .DestroyScreen = radeonDestroyScreen, .CreateContext = radeonCreateContext, .DestroyContext = radeonDestroyContext, @@ -954,13 +965,9 @@ static struct __DriverAPIRec radeonAPI = { .WaitForSBC = NULL, .SwapBuffersMSC = NULL, .CopySubBuffer = radeonCopySubBuffer, -#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) - .setTexOffset = r300SetTexOffset, -#endif }; #else static const struct __DriverAPIRec r200API = { - .InitDriver = radeonInitDriver, .DestroyScreen = radeonDestroyScreen, .CreateContext = r200CreateContext, .DestroyContext = r200DestroyContext, @@ -979,30 +986,16 @@ static const struct __DriverAPIRec r200API = { }; #endif + /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. + * + * \todo maybe fold this into intelInitDriver * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \return the __GLcontextModes supported by this driver */ -PUBLIC void * -__driCreateNewScreen_20050727( __DRInativeDisplay *dpy, - int scrn, __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes ) +__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; #if !RADEON_COMMON static const char *driver_name = "Radeon"; static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 }; @@ -1019,57 +1012,46 @@ __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 1, 24, 0 }; #endif - - dri_interface = interface; + RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv; if ( ! driCheckDriDdxDrmVersions3( driver_name, - dri_version, & dri_expected, - ddx_version, & ddx_expected, - drm_version, & drm_expected ) ) { + &psp->dri_version, & dri_expected, + &psp->ddx_version, & ddx_expected, + &psp->drm_version, & drm_expected ) ) { return NULL; } #if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)) - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &radeonAPI); + psp->DriverAPI = radeonAPI; #elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &r200API); + psp->DriverAPI = r200API; #endif - if ( psp != NULL ) { - RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv; - if (driver_modes) { - *driver_modes = radeonFillInModes( dri_priv->bpp, - (dri_priv->bpp == 16) ? 16 : 24, - (dri_priv->bpp == 16) ? 0 : 8, - (dri_priv->backOffset != dri_priv->depthOffset) ); - } - - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create - * is called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions( NULL, card_extensions, GL_FALSE ); + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create + * is called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, card_extensions, GL_FALSE ); #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200) - driInitExtensions( NULL, blend_extensions, GL_FALSE ); - driInitSingleExtension( NULL, ARB_vp_extension ); - driInitSingleExtension( NULL, NV_vp_extension ); - driInitSingleExtension( NULL, ATI_fs_extension ); - driInitExtensions( NULL, point_extensions, GL_FALSE ); + driInitExtensions( NULL, blend_extensions, GL_FALSE ); + driInitSingleExtension( NULL, ARB_vp_extension ); + driInitSingleExtension( NULL, NV_vp_extension ); + driInitSingleExtension( NULL, ATI_fs_extension ); + driInitExtensions( NULL, point_extensions, GL_FALSE ); #endif - } - return (void *) psp; + if (!radeonInitDriver(psp)) + return NULL; + + return radeonFillInModes( dri_priv->bpp, + (dri_priv->bpp == 16) ? 16 : 24, + (dri_priv->bpp == 16) ? 0 : 8, + (dri_priv->backOffset != dri_priv->depthOffset) ); } diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h index 25e6fcf399..184b0d225e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.h +++ b/src/mesa/drivers/dri/radeon/radeon_screen.h @@ -103,6 +103,8 @@ typedef struct { /* Configuration cache with default values for all contexts */ driOptionCache optionCache; + + const __DRIextension *extensions[8]; } radeonScreenRec, *radeonScreenPtr; #define IS_R100_CLASS(screen) \ diff --git a/src/mesa/drivers/dri/s3v/s3v_xmesa.c b/src/mesa/drivers/dri/s3v/s3v_xmesa.c index c66fd6dac3..7b0b006b69 100644 --- a/src/mesa/drivers/dri/s3v/s3v_xmesa.c +++ b/src/mesa/drivers/dri/s3v/s3v_xmesa.c @@ -329,7 +329,6 @@ s3vUnbindContext( __DRIcontextPrivate *driContextPriv ) static struct __DriverAPIRec s3vAPI = { - s3vInitDriver, s3vDestroyScreen, s3vCreateContext, s3vDestroyContext, @@ -355,6 +354,9 @@ void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, DEBUG(("__driCreateScreen: psp = %p\n", psp)); psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &s3vAPI); DEBUG(("__driCreateScreen: psp = %p\n", psp)); + if (!s3vInitDriver(psp)) + return NULLL + return (void *) psp; } #endif diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c index 43422db9a8..013e88216f 100644 --- a/src/mesa/drivers/dri/savage/savage_xmesa.c +++ b/src/mesa/drivers/dri/savage/savage_xmesa.c @@ -168,6 +168,10 @@ static const struct tnl_pipeline_stage *savage_pipeline[] = { }; +static const __DRIextension *savageExtensions[] = { + &driReadDrawableExtension, +}; + /* this is first function called in dirver*/ static GLboolean @@ -175,9 +179,6 @@ savageInitDriver(__DRIscreenPrivate *sPriv) { savageScreenPrivate *savageScreen; SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension")); - if (sPriv->devPrivSize != sizeof(SAVAGEDRIRec)) { fprintf(stderr,"\nERROR! sizeof(SAVAGEDRIRec) does not match passed size from device driver\n"); @@ -265,10 +266,7 @@ savageInitDriver(__DRIscreenPrivate *sPriv) driParseOptionInfo (&savageScreen->optionCache, __driConfigOptions, __driNConfigOptions); - if (glx_enable_extension != NULL) { - (*glx_enable_extension)(sPriv->psc->screenConfigs, - "GLX_SGI_make_current_read"); - } + sPriv->extensions = savageExtensions; #if 0 savageDDFastPathInit(); @@ -525,7 +523,7 @@ savageCreateContext( const __GLcontextModes *mesaVis, "enable_fastpath"); /* DRM versions before 2.1.3 would only render triangle lists. ELTS * support was added in 2.2.0. */ - if (imesa->enable_fastpath && sPriv->drmMinor < 2) { + if (imesa->enable_fastpath && sPriv->drm_version.minor < 2) { fprintf (stderr, "*** Disabling fast path because your DRM version is buggy " "or doesn't\n*** support ELTS. You need at least Savage DRM " @@ -920,7 +918,6 @@ void savageGetLock( savageContextPtr imesa, GLuint flags ) static const struct __DriverAPIRec savageAPI = { - savageInitDriver, savageDestroyScreen, savageCreateContext, savageDestroyContext, @@ -1017,63 +1014,44 @@ savageFillInModes( unsigned pixel_bits, unsigned depth_bits, /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \todo maybe fold this into intelInitDriver + * + * \return the __GLcontextModes supported by this driver */ -PUBLIC -void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes ) - +__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 2, 0, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 2, 1, 0 }; - - dri_interface = interface; + SAVAGEDRIPtr dri_priv = (SAVAGEDRIPtr)psp->pDevPriv; if ( ! driCheckDriDdxDrmVersions2( "Savage", - dri_version, & dri_expected, - ddx_version, & ddx_expected, - drm_version, & drm_expected ) ) { + &psp->dri_version, & dri_expected, + &psp->ddx_version, & ddx_expected, + &psp->drm_version, & drm_expected ) ) return NULL; - } - - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &savageAPI); - if ( psp != NULL ) { - SAVAGEDRIPtr dri_priv = (SAVAGEDRIPtr)psp->pDevPriv; - *driver_modes = savageFillInModes( dri_priv->cpp*8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, - (dri_priv->backOffset != dri_priv->depthOffset) ); - - /* Calling driInitExtensions here, with a NULL context pointer, does not actually - * enable the extensions. It just makes sure that all the dispatch offsets for all - * the extensions that *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is called, but we can't - * enable the extensions until we have a context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions( NULL, card_extensions, GL_FALSE ); - } - return (void *) psp; + psp->DriverAPI = savageAPI; + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, card_extensions, GL_FALSE ); + + if (!savageInitDriver(psp)) + return NULL; + + return savageFillInModes( dri_priv->cpp*8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, + (dri_priv->backOffset != dri_priv->depthOffset) ); } diff --git a/src/mesa/drivers/dri/savage/savagetex.c b/src/mesa/drivers/dri/savage/savagetex.c index 719e50f964..1dcfee291f 100644 --- a/src/mesa/drivers/dri/savage/savagetex.c +++ b/src/mesa/drivers/dri/savage/savagetex.c @@ -1016,7 +1016,7 @@ static void savageUploadTexImages( savageContextPtr imesa, savageTexObjPtr t ) /* Heap timestamps are only reliable with Savage DRM 2.3.x or * later. Earlier versions had only 16 bit time stamps which * would wrap too frequently. */ - if (imesa->savageScreen->driScrnPriv->drmMinor >= 3) { + if (imesa->savageScreen->driScrnPriv->drm_version.minor >= 3) { unsigned int heap = t->base.heap->heapId; LOCK_HARDWARE(imesa); savageWaitEvent (imesa, imesa->textureHeaps[heap]->timestamp); @@ -1713,7 +1713,7 @@ static void savageTimestampTextures( savageContextPtr imesa ) * Only useful with long-lived 32-bit event tags available * with Savage DRM 2.3.x or later. */ if ((imesa->CurrentTexObj[0] || imesa->CurrentTexObj[1]) && - imesa->savageScreen->driScrnPriv->drmMinor >= 3) { + imesa->savageScreen->driScrnPriv->drm_version.minor >= 3) { unsigned int e; FLUSH_BATCH(imesa); e = savageEmitEvent(imesa, SAVAGE_WAIT_3D); diff --git a/src/mesa/drivers/dri/sis/sis_screen.c b/src/mesa/drivers/dri/sis/sis_screen.c index 89d734ba78..79682a7253 100644 --- a/src/mesa/drivers/dri/sis/sis_screen.c +++ b/src/mesa/drivers/dri/sis/sis_screen.c @@ -304,7 +304,6 @@ sisInitDriver( __DRIscreenPrivate *sPriv ) } static struct __DriverAPIRec sisAPI = { - .InitDriver = sisInitDriver, .DestroyScreen = sisDestroyScreen, .CreateContext = sisCreateContext, .DestroyContext = sisDestroyContext, @@ -323,60 +322,42 @@ static struct __DriverAPIRec sisAPI = { /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. + * + * \todo maybe fold this into intelInitDriver * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \return the __GLcontextModes supported by this driver */ -PUBLIC -void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, - __DRIscreen *psc, - const __GLcontextModes *modes, - const __DRIversion *ddx_version, - const __DRIversion *dri_version, - const __DRIversion *drm_version, - const __DRIframebuffer *frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes **driver_modes ) - +__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = {0, 8, 0}; static const __DRIversion dri_expected = {4, 0, 0}; static const __DRIversion drm_expected = {1, 0, 0}; static const char *driver_name = "SiS"; - dri_interface = interface; + SISDRIPtr dri_priv = (SISDRIPtr)psp->pDevPriv; - if (!driCheckDriDdxDrmVersions2(driver_name, dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { + if (!driCheckDriDdxDrmVersions2(driver_name, + &psp->dri_version, &dri_expected, + &psp->ddx_version, &ddx_expected, + &psp->drm_version, &drm_expected)) return NULL; - } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &sisAPI); - if (psp != NULL) { - SISDRIPtr dri_priv = (SISDRIPtr)psp->pDevPriv; - *driver_modes = sisFillInModes(dri_priv->bytesPerPixel * 8); - - /* Calling driInitExtensions here, with a NULL context pointer, does not actually - * enable the extensions. It just makes sure that all the dispatch offsets for all - * the extensions that *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is called, but we can't - * enable the extensions until we have a context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions( NULL, card_extensions, GL_FALSE ); - } + psp->DriverAPI = sisAPI; + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, card_extensions, GL_FALSE ); + + if (!sisInitDriver(psp)) + return NULL; - return (void *)psp; + return sisFillInModes(dri_priv->bytesPerPixel * 8); } diff --git a/src/mesa/drivers/dri/tdfx/tdfx_screen.c b/src/mesa/drivers/dri/tdfx/tdfx_screen.c index 1f9ff4e30c..5bdb446d15 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_screen.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_screen.c @@ -63,6 +63,10 @@ DRI_CONF_BEGIN DRI_CONF_SECTION_END DRI_CONF_END; +static const __DRIextension *tdfxExtensions[] = { + &driReadDrawableExtension, +}; + static const GLuint __driNConfigOptions = 1; extern const struct dri_extension card_extensions[]; @@ -73,9 +77,6 @@ tdfxCreateScreen( __DRIscreenPrivate *sPriv ) { tdfxScreenPrivate *fxScreen; TDFXDRIPtr fxDRIPriv = (TDFXDRIPtr) sPriv->pDevPriv; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension")); - void *const psc = sPriv->psc->screenConfigs; if (sPriv->devPrivSize != sizeof(TDFXDRIRec)) { fprintf(stderr,"\nERROR! sizeof(TDFXDRIRec) does not match passed size from device driver\n"); @@ -116,9 +117,7 @@ tdfxCreateScreen( __DRIscreenPrivate *sPriv ) return GL_FALSE; } - if (glx_enable_extension != NULL) { - (*glx_enable_extension)(psc, "GLX_SGI_make_current_read"); - } + sPriv->extensions = tdfxExtensions; return GL_TRUE; } @@ -346,7 +345,6 @@ tdfxSwapBuffers( __DRIdrawablePrivate *driDrawPriv ) static const struct __DriverAPIRec tdfxAPI = { - .InitDriver = tdfxInitDriver, .DestroyScreen = tdfxDestroyScreen, .CreateContext = tdfxCreateContext, .DestroyContext = tdfxDestroyContext, @@ -432,69 +430,50 @@ static __GLcontextModes *tdfxFillInModes(unsigned pixel_bits, } /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. + * + * \todo maybe fold this into intelInitDriver * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \return the __GLcontextModes supported by this driver */ -PUBLIC -void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes ) +__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 1, 1, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 1, 0, 0 }; - dri_interface = interface; + /* divined from tdfx_dri.c, sketchy */ + TDFXDRIPtr dri_priv = (TDFXDRIPtr) psp->pDevPriv; + + /* XXX i wish it was like this */ + /* bpp = dri_priv->bpp */ + int bpp = (dri_priv->cpp > 2) ? 24 : 16; if ( ! driCheckDriDdxDrmVersions2( "tdfx", - dri_version, & dri_expected, - ddx_version, & ddx_expected, - drm_version, & drm_expected ) ) { + &psp->dri_version, & dri_expected, + &psp->ddx_version, & ddx_expected, + &psp->drm_version, & drm_expected ) ) return NULL; - } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &tdfxAPI); - - if (psp != NULL) { - /* divined from tdfx_dri.c, sketchy */ - TDFXDRIPtr dri_priv = (TDFXDRIPtr) psp->pDevPriv; - int bpp = (dri_priv->cpp > 2) ? 24 : 16; + psp->DriverAPI = tdfxAPI; + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, card_extensions, GL_FALSE ); + driInitExtensions( NULL, napalm_extensions, GL_FALSE ); - /* XXX i wish it was like this */ - /* bpp = dri_priv->bpp */ + if (!tdfxInitDriver(psp)) + return NULL; - *driver_modes = tdfxFillInModes(bpp, (bpp == 16) ? 16 : 24, - (bpp == 16) ? 0 : 8, - (dri_priv->backOffset!=dri_priv->depthOffset)); - - /* Calling driInitExtensions here, with a NULL context pointer, does not actually - * enable the extensions. It just makes sure that all the dispatch offsets for all - * the extensions that *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is called, but we can't - * enable the extensions until we have a context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions( NULL, card_extensions, GL_FALSE ); - driInitExtensions( NULL, napalm_extensions, GL_FALSE ); - } - - return (void *)psp; + return tdfxFillInModes(bpp, (bpp == 16) ? 16 : 24, + (bpp == 16) ? 0 : 8, + (dri_priv->backOffset!=dri_priv->depthOffset)); } diff --git a/src/mesa/drivers/dri/trident/trident_context.c b/src/mesa/drivers/dri/trident/trident_context.c index 8dc7f0dc78..81098bc9cd 100644 --- a/src/mesa/drivers/dri/trident/trident_context.c +++ b/src/mesa/drivers/dri/trident/trident_context.c @@ -418,7 +418,6 @@ tridentInitDriver(__DRIscreenPrivate *sPriv) } static struct __DriverAPIRec tridentAPI = { - tridentInitDriver, tridentDestroyScreen, tridentCreateContext, tridentDestroyContext, @@ -430,43 +429,36 @@ static struct __DriverAPIRec tridentAPI = { }; -PUBLIC void *__driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, - __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes ) +/** + * This is the driver specific part of the createNewScreen entry point. + * + * \todo maybe fold this into intelInitDriver + * + * \return the __GLcontextModes supported by this driver + */ +__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 4, 0, 0 }; static const __DRIversion dri_expected = { 3, 1, 0 }; static const __DRIversion drm_expected = { 1, 0, 0 }; - - dri_interface = interface; - + if ( ! driCheckDriDdxDrmVersions2( "Trident", - dri_version, & dri_expected, - ddx_version, & ddx_expected, - drm_version, & drm_expected ) ) { + &psp->dri_version, & dri_expected, + &psp->ddx_version, & ddx_expected, + &psp->drm_version, & drm_expected ) ) return NULL; - } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &tridentAPI); + psp->DriverAPI = tridentAPI; + + if (!tridentInitDriver(psp)) + return NULL; - if ( psp != NULL ) { + /* Wait... what? This driver doesn't report any modes... */ #if 0 - TRIDENTDRIPtr dri_priv = (TRIDENTDRIPtr) psp->pDevPriv; - *driver_modes = tridentFillInModes( dri_priv->bytesPerPixel * 8, - GL_TRUE ); + TRIDENTDRIPtr dri_priv = (TRIDENTDRIPtr) psp->pDevPriv; + *driver_modes = tridentFillInModes( dri_priv->bytesPerPixel * 8, + GL_TRUE ); #endif - } - return (void *) psp; + + return NULL; } diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c index 7c73877720..66e92cc602 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.c +++ b/src/mesa/drivers/dri/unichrome/via_context.c @@ -601,9 +601,6 @@ viaCreateContext(const __GLcontextModes *visual, _tnl_allow_pixel_fog(ctx, GL_FALSE); _tnl_allow_vertex_fog(ctx, GL_TRUE); -/* vmesa->display = dpy; */ - vmesa->display = sPriv->display; - vmesa->hHWContext = driContextPriv->hHWContext; vmesa->driFd = sPriv->fd; vmesa->driHwLock = &sPriv->pSAREA->lock; diff --git a/src/mesa/drivers/dri/unichrome/via_context.h b/src/mesa/drivers/dri/unichrome/via_context.h index fecd2782fb..6321713688 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.h +++ b/src/mesa/drivers/dri/unichrome/via_context.h @@ -289,7 +289,6 @@ struct via_context { drm_context_t hHWContext; drm_hw_lock_t *driHwLock; int driFd; - __DRInativeDisplay *display; /** * DRI drawable bound to this context for drawing. diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c index 90f76be44d..f3912ac352 100644 --- a/src/mesa/drivers/dri/unichrome/via_screen.c +++ b/src/mesa/drivers/dri/unichrome/via_screen.c @@ -98,9 +98,7 @@ viaInitDriver(__DRIscreenPrivate *sPriv) { viaScreenPrivate *viaScreen; VIADRIPtr gDRIPriv = (VIADRIPtr)sPriv->pDevPriv; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension")); - void * const psc = sPriv->psc->screenConfigs; + int i; if (sPriv->devPrivSize != sizeof(VIADRIRec)) { fprintf(stderr,"\nERROR! sizeof(VIADRIRec) does not match passed size from device driver\n"); @@ -175,17 +173,17 @@ viaInitDriver(__DRIscreenPrivate *sPriv) viaScreen->sareaPrivOffset = gDRIPriv->sarea_priv_offset; - if ( glx_enable_extension != NULL ) { - if ( viaScreen->irqEnabled ) { - (*glx_enable_extension)( psc, "GLX_SGI_swap_control" ); - (*glx_enable_extension)( psc, "GLX_SGI_video_sync" ); - (*glx_enable_extension)( psc, "GLX_MESA_swap_control" ); - } - - (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" ); - (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" ); + i = 0; + viaScreen->extensions[i++] = &driFrameTrackingExtension.base; + viaScreen->extensions[i++] = &driReadDrawableExtension; + if ( viaScreen->irqEnabled ) { + viaScreen->extensions[i++] = &driSwapControlExtension.base; + viaScreen->extensions[i++] = &driMediaStreamCounterExtension.base; } + viaScreen->extensions[i++] = NULL; + sPriv->extensions = viaScreen->extensions; + return GL_TRUE; } @@ -326,7 +324,6 @@ viaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) static struct __DriverAPIRec viaAPI = { - .InitDriver = viaInitDriver, .DestroyScreen = viaDestroyScreen, .CreateContext = viaCreateContext, .DestroyContext = viaDestroyContext, @@ -408,67 +405,47 @@ viaFillInModes( unsigned pixel_bits, GLboolean have_back_buffer ) /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \todo maybe fold this into intelInitDriver + * + * \return the __GLcontextModes supported by this driver */ -PUBLIC -void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, - __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes ) - +__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { VIA_DRIDDX_VERSION_MAJOR, VIA_DRIDDX_VERSION_MINOR, VIA_DRIDDX_VERSION_PATCH }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 2, 3, 0 }; static const char *driver_name = "Unichrome"; - - dri_interface = interface; + VIADRIPtr dri_priv = (VIADRIPtr) psp->pDevPriv; if ( ! driCheckDriDdxDrmVersions2( driver_name, - dri_version, & dri_expected, - ddx_version, & ddx_expected, - drm_version, & drm_expected) ) { + &psp->dri_version, & dri_expected, + &psp->ddx_version, & ddx_expected, + &psp->drm_version, & drm_expected) ) return NULL; - } - - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &viaAPI); - if ( psp != NULL ) { - VIADRIPtr dri_priv = (VIADRIPtr) psp->pDevPriv; - *driver_modes = viaFillInModes( dri_priv->bytesPerPixel * 8, - GL_TRUE ); - - /* Calling driInitExtensions here, with a NULL context pointer, does not actually - * enable the extensions. It just makes sure that all the dispatch offsets for all - * the extensions that *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is called, but we can't - * enable the extensions until we have a context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions( NULL, card_extensions, GL_FALSE ); - } - return (void *) psp; + psp->DriverAPI = viaAPI; + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, card_extensions, GL_FALSE ); + + if (!viaInitDriver(psp)) + return NULL; + + return viaFillInModes( dri_priv->bytesPerPixel * 8, GL_TRUE ); + } diff --git a/src/mesa/drivers/dri/unichrome/via_screen.h b/src/mesa/drivers/dri/unichrome/via_screen.h index 84aa5aef88..c3ef722ff0 100644 --- a/src/mesa/drivers/dri/unichrome/via_screen.h +++ b/src/mesa/drivers/dri/unichrome/via_screen.h @@ -70,6 +70,8 @@ typedef struct { /* Configuration cache with default values for all contexts */ driOptionCache optionCache; + + const __DRIextension *extensions[5]; } viaScreenPrivate; |