Merge branch 'master' of git+ssh://joukj@git.freedesktop.org/git/mesa/mesa

This commit is contained in:
Jouk 2007-10-31 08:18:58 +01:00
commit d1414da8f9
239 changed files with 10518 additions and 6111 deletions

View file

@ -69,6 +69,7 @@ aix-static \
bluegene-osmesa \
bluegene-xlc-osmesa \
beos \
catamount-osmesa-pgi \
darwin \
darwin-static \
darwin-static-x86ppc \
@ -413,6 +414,9 @@ GLUT_FILES = \
$(DIRECTORY)/src/glut/fbdev/Makefile \
$(DIRECTORY)/src/glut/fbdev/*[ch] \
$(DIRECTORY)/src/glut/mini/*[ch] \
$(DIRECTORY)/src/glut/directfb/Makefile \
$(DIRECTORY)/src/glut/directfb/NOTES \
$(DIRECTORY)/src/glut/directfb/*[ch] \
$(DIRECTORY)/windows/VC6/progs/glut/glut.dsp \
$(DIRECTORY)/windows/VC7/progs/glut/glut.vcproj

View file

@ -0,0 +1,32 @@
# Configuration for building only libOSMesa on Cray Xt3
# for the compute nodes running Catamount using the
# Portland Group compiler. The Portland Group toolchain has to be
# enabled before using "module switch PrgEnv-gnu PrgEnv-pgi" .
# This doesn't really have a lot of dependencies, so it should be usable
# on other similar systems too.
# It uses static linking and disables multithreading.
include $(TOP)/configs/default
CONFIG_NAME = catamount-osmesa-pgi
# Compiler and flags
CC = cc
CXX = CC
CFLAGS = -target=catamount -fastsse -O3 -Mnontemporal -Mprefetch=distance:8,nta -fPIC -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE -D_BSD_SOURCE
CXXFLAGS = -target=catamount -fastsse -O3 -Mnontemporal -Mprefetch=distance:8,nta -fPIC -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE -D_BSD_SOURCE
MKLIB_OPTIONS = -static
OSMESA_LIB_NAME = libOSMesa.a
# Directories
SRC_DIRS = mesa glu
DRIVER_DIRS = osmesa
PROGRAM_DIRS = osdemos
# Dependencies
OSMESA_LIB_DEPS = -lm
GLU_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(OSMESA_LIB)
APP_LIB_DEPS = -lOSMesa -lGLU -lm

View file

@ -67,14 +67,16 @@ DRIVER_DIRS = x11 osmesa
PROGRAM_DIRS = demos redbook samples glsl xdemos
# Library/program dependencies
# Library dependencies
#EXTRA_LIB_PATH ?=
GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread
OSMESA_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GL_LIB)
GLU_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) -lm
GLUT_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) $(EXTRA_LIB_PATH) -lX11 -lXmu -lXt -lXi -lm
GLW_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) $(EXTRA_LIB_PATH) -lXt -lX11
APP_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) -lm
# Program dependencies - specific GL/glut libraries added in Makefiles
APP_LIB_DEPS = -lm

View file

@ -12,7 +12,7 @@ WARN_FLAGS = -Wall
OPT_FLAGS = -O -g
EXPAT_INCLUDES = -I/usr/local/include
X11_INCLUDES = -I/usr/X11R6/include
X11_INCLUDES = -I/usr/local/include
DEFINES = -DPTHREADS -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER \
-DGLX_DIRECT_RENDERING -DGLX_INDIRECT_RENDERING \
-DHAVE_ALIAS
@ -28,11 +28,11 @@ ASM_SOURCES =
LIBDRM_CFLAGS = `pkg-config --cflags libdrm`
LIBDRM_LIB = `pkg-config --libs libdrm`
DRI_LIB_DEPS = -L/usr/local/lib -lm -pthread -lexpat $(LIBDRM_LIB)
GL_LIB_DEPS = -L/usr/X11R6/lib -lX11 -lXext -lXxf86vm -lXdamage -lXfixes \
GL_LIB_DEPS = -L/usr/local/lib -lX11 -lXext -lXxf86vm -lXdamage -lXfixes \
-lm -pthread $(LIBDRM_LIB)
GLUT_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -L/usr/X11R6/lib -lGLU -lGL -lX11 -lXmu -lXt -lXi -lm
GLW_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -L/usr/X11R6/lib -lGL -lXt -lX11
GLUT_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -L/usr/local/lib -lGLU -lGL -lX11 -lXmu -lXt -lXi -lm
GLW_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -L/usr/local/lib -lGL -lXt -lX11
# Directories

View file

@ -55,10 +55,10 @@ USING_EGL=0
# Directories
ifeq ($(USING_EGL), 1)
SRC_DIRS = egl glx/x11 mesa glu glut/glx glw
PROGRAM_DIRS = egl
PROGRAM_DIRS = egl xdemos
else
SRC_DIRS = glx/x11 mesa glu glut/glx glw
PROGRAM_DIRS =
PROGRAM_DIRS = xdemos
endif
DRIVER_DIRS = dri

View file

@ -41,8 +41,9 @@ EXTRA_LIB_PATH=`pkg-config --libs-only-L x11`
LIBDRM_CFLAGS = `pkg-config --cflags libdrm`
LIBDRM_LIB = `pkg-config --libs libdrm`
DRI_LIB_DEPS = $(EXTRA_LIB_PATH) -lm -lpthread -lexpat -ldl $(LIBDRM_LIB)
GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lXxf86vm -lm -lpthread -ldl \
$(LIBDRM_LIB) `pkg-config --libs xcb` `pkg-config --libs x11-xcb` `pkg-config --libs xcb-glx`
GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lXxf86vm -lXdamage -lXfixes \
-lm -lpthread -ldl $(LIBDRM_LIB) `pkg-config --libs xcb` \
`pkg-config --libs x11-xcb` `pkg-config --libs xcb-glx`
# This is now 0 by default since it seems to confuse the hell out of people
@ -54,10 +55,10 @@ USING_EGL=0
# Directories
ifeq ($(USING_EGL), 1)
SRC_DIRS = egl glx/x11 mesa glu glut/glx glw
PROGRAM_DIRS = egl
PROGRAM_DIRS = egl xdemos
else
SRC_DIRS = glx/x11 mesa glu glut/glx glw
PROGRAM_DIRS =
PROGRAM_DIRS = xdemos
endif
DRIVER_DIRS = dri

View file

@ -21,6 +21,4 @@ GLUT_LIB_DEPS =
GLW_LIB_DEPS =
# Need to specify all libraries we may need
APP_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) -lm \
-L/usr/X11R6/lib/ -lX11 -lXmu -lXi -lpthread
APP_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXmu -lXt -lXi -lpthread -lstdc++ -lm

View file

@ -19,5 +19,4 @@ OSMESA_LIB_DEPS =
GLU_LIB_DEPS =
GLUT_LIB_DEPS =
GLW_LIB_DEPS =
APP_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) \
$(EXTRA_LIB_PATH) -lX11 -lXmu -lXt -lXi -lpthread -lstdc++ -lm
APP_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXmu -lXt -lXi -lpthread -lstdc++ -lm

View file

@ -19,5 +19,4 @@ OSMESA_LIB_DEPS =
GLU_LIB_DEPS =
GLUT_LIB_DEPS =
GLW_LIB_DEPS =
APP_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) \
$(EXTRA_LIB_PATH) -lX11 -lXmu -lXt -lXi -lpthread -lstdc++ -lm
APP_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXmu -lXt -lXi -lpthread -lstdc++ -lm

View file

@ -48,65 +48,210 @@
* 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.
*/
/*@{*/
/**
* 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.
* 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.
*
* \sa glXGetScreenDriver, glXGetProcAddress, glXGetDriverConfig
*/
typedef const char * (* PFNGLXGETSCREENDRIVERPROC) (__DRInativeDisplay *dpy, int scrNum);
/**
* 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.
* 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.
*
* \sa glXGetDriverConfig, glXGetProcAddress, glXGetScreenDriver
* 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.
*/
typedef const char * (* PFNGLXGETDRIVERCONFIGPROC) (const char *driverName);
struct __DRIextensionRec {
const char *name;
int version;
};
/**
* 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 to indicate support for setting the read drawable.
*/
typedef void (* PFNGLXSCRENABLEEXTENSIONPROC) ( void *psc, const char * name );
/*@}*/
#define __DRI_READ_DRAWABLE "DRI_ReadDrawable"
#define __DRI_READ_DRAWABLE_VERSION 1
/**
* Used by drivers that implement the GLX_MESA_copy_sub_buffer extension.
*/
#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);
};
/**
* Used by drivers that implement the GLX_SGI_swap_control or
* GLX_MESA_swap_control extension.
*/
#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 2
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);
/**
* Like the screen version of getMSC, but also takes a drawable so that
* the appropriate pipe's counter can be retrieved.
*
* 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 2
*/
int (*getDrawableMSC)(__DRIscreen *screen, void *drawablePrivate,
int64_t *msc);
};
#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;
/**
@ -137,11 +282,6 @@ struct __DRIversionRec {
typedef void (*__DRIfuncPtr)(void);
struct __DRIinterfaceMethodsRec {
/**
* Get pointer to named function.
*/
__DRIfuncPtr (*getProcAddress)( const char * proc_name );
/**
* Create a list of \c __GLcontextModes structures.
*/
@ -156,11 +296,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 +305,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 +335,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 +353,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,22 +396,23 @@ struct __DRIscreenRec {
/**
* Method to destroy the private DRI screen data.
*/
void (*destroyScreen)(__DRInativeDisplay *dpy, int scrn, void *screenPrivate);
void (*destroyScreen)(__DRIscreen *screen);
/**
* Method to get screen extensions.
*/
const __DRIextension **(*getExtensions)(__DRIscreen *screen);
/**
* Method to create the private DRI drawable data and initialize the
* drawable dependent methods.
*/
void *(*createNewDrawable)(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
__DRIid draw, __DRIdrawable *pdraw,
void *(*createNewDrawable)(__DRIscreen *screen,
const __GLcontextModes *modes,
__DRIdrawable *pdraw,
drm_drawable_t hwDrawable,
int renderType, const int *attrs);
/**
* Method to return a pointer to the DRI drawable data.
*/
__DRIdrawable *(*getDrawable)(__DRInativeDisplay *dpy, __DRIid draw,
void *drawablePrivate);
/**
* Opaque pointer to private per screen direct rendering data. \c NULL
* if direct rendering is not supported on this screen. Never
@ -319,60 +420,17 @@ 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 +441,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.
@ -392,28 +450,21 @@ 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 +477,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 +490,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

View file

@ -41,6 +41,7 @@
#define GL_CORE_SGI 1
#define GL_CORE_MESA 2
#define GL_CORE_APPLE 4
#define GL_CORE_WINDOWS 8
typedef struct __GLcontextRec __GLcontext;

3
progs/beos/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
demo
GLInfo
sample

View file

@ -10,7 +10,9 @@ include $(TOP)/configs/current
#
# Modified by Philippe Houdoin
LDFLAGS += -soname=_APP_ $(APP_LIB_DEPS)
LDFLAGS += -soname=_APP_
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
INCLUDES = -I. -I- -I../../include
@ -21,13 +23,13 @@ clean:
rm -f *.o
demo: demo.o
$(LD) demo.o $(LDFLAGS) -o $@
$(LD) demo.o $(LDFLAGS) $(LIBS) -o $@
sample: sample.o
$(LD) sample.o $(LDFLAGS) -o $@
$(LD) sample.o $(LDFLAGS) $(LIBS) -o $@
GTLInfo: GLInfo.o
$(LD) GLInfo.o $(INCLUDES) $(LDFLAGS) -o $@
$(LD) GLInfo.o $(INCLUDES) $(LDFLAGS) $(LIBS) -o $@
.cpp.o:
$(CC) -c $< $(INCLUDES) $(CFLAGS) -o $@

View file

@ -4,6 +4,7 @@ arbfslight
arbocclude
bounce
clearspd
copypix
cubemap
drawpix
engine
@ -41,8 +42,8 @@ shadowtex
showbuffer.c
showbuffer.h
singlebuffer
spriteblast
spectex
spriteblast
stex3d
streaming_rect
teapot

View file

@ -13,6 +13,8 @@ OSMESA32_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa32 -lGLU -lGL $(APP_LIB_DEPS)
LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME)
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
PROGS = \
arbfplight \
arbfslight \
@ -75,7 +77,7 @@ PROGS = \
# make executable from .c file:
.c: $(LIB_DEP) readtex.o
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< readtex.o $(APP_LIB_DEPS) -o $@
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< readtex.o $(LIBS) -o $@
##### TARGETS #####
@ -119,35 +121,35 @@ extfuncs.h: $(TOP)/progs/util/extfuncs.h
reflect: reflect.o showbuffer.o readtex.o
$(CC) $(LDFLAGS) reflect.o showbuffer.o readtex.o $(APP_LIB_DEPS) -o $@
$(CC) $(LDFLAGS) reflect.o showbuffer.o readtex.o $(LIBS) -o $@
reflect.o: reflect.c showbuffer.h
$(CC) -c -I$(INCDIR) $(CFLAGS) reflect.c
shadowtex: shadowtex.o showbuffer.o
$(CC) $(LDFLAGS) shadowtex.o showbuffer.o $(APP_LIB_DEPS) -o $@
$(CC) $(LDFLAGS) shadowtex.o showbuffer.o $(LIBS) -o $@
shadowtex.o: shadowtex.c showbuffer.h
$(CC) -c -I$(INCDIR) $(CFLAGS) shadowtex.c
gloss: gloss.o trackball.o readtex.o
$(CC) $(LDFLAGS) gloss.o trackball.o readtex.o $(APP_LIB_DEPS) -o $@
$(CC) $(LDFLAGS) gloss.o trackball.o readtex.o $(LIBS) -o $@
gloss.o: gloss.c trackball.h
$(CC) -c -I$(INCDIR) $(CFLAGS) gloss.c
engine: engine.o trackball.o readtex.o
$(CC) $(LDFLAGS) engine.o trackball.o readtex.o $(APP_LIB_DEPS) -o $@
$(CC) $(LDFLAGS) engine.o trackball.o readtex.o $(LIBS) -o $@
engine.o: engine.c trackball.h
$(CC) -c -I$(INCDIR) $(CFLAGS) engine.c
fslight: fslight.o
$(CC) $(LDFLAGS) fslight.o $(APP_LIB_DEPS) -o $@
$(CC) $(LDFLAGS) fslight.o $(LIBS) -o $@
fslight.o: fslight.c extfuncs.h
$(CC) -c -I$(INCDIR) $(CFLAGS) fslight.c
@ -155,7 +157,7 @@ fslight.o: fslight.c extfuncs.h
viewdds: viewdds.c
$(CC) -I$(INCDIR) $(CFLAGS) $< readtex.o $(APP_LIB_DEPS) -L. -lgltc -o $@
$(CC) -I$(INCDIR) $(CFLAGS) $< readtex.o $(LIBS) -L. -lgltc -o $@
clean:

View file

@ -84,6 +84,7 @@ static const char *FragProgNames[] = {
"program with \"OPTION ARB_fragment_program_shadow\"",
};
static GLboolean HaveShadow = GL_FALSE;
static GLboolean HaveFBO = GL_FALSE;
static GLboolean UseFBO = GL_FALSE;
static GLboolean HaveVP = GL_FALSE;
@ -529,7 +530,10 @@ ShowShadowMap(void)
DisableTexgen();
/* interpret texture's depth values as luminance values */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
if (HaveShadow) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
}
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@ -596,7 +600,9 @@ Display(void)
}
if (DisplayMode == SHOW_DEPTH_MAPPING) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
if (HaveShadow) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
}
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_TEXTURE_2D);
@ -614,8 +620,10 @@ Display(void)
}
else {
assert(DisplayMode == SHOW_SHADOWS);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
GL_COMPARE_R_TO_TEXTURE_ARB);
if (HaveShadow) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
GL_COMPARE_R_TO_TEXTURE_ARB);
}
if (curr_frag > 0) {
glEnable(GL_FRAGMENT_PROGRAM_ARB);
@ -723,6 +731,10 @@ Key(unsigned char key, int x, int y)
break;
case 'M':
curr_frag = (1 + curr_frag) % max_frag;
if (!HaveShadow && (curr_frag == 0)) {
curr_frag = 1;
}
printf("Using fragment %s\n", FragProgNames[curr_frag]);
if (HaveFP) {
@ -740,8 +752,10 @@ Key(unsigned char key, int x, int y)
if (Operator >= 8)
Operator = 0;
printf("Operator: %s\n", OperatorName[Operator]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB,
OperatorFunc[Operator]);
if (HaveShadow) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB,
OperatorFunc[Operator]);
}
}
break;
case 'p':
@ -858,17 +872,31 @@ Init(void)
{
static const GLfloat borderColor[4] = {1.0, 0.0, 0.0, 0.0};
if (!glutExtensionSupported("GL_ARB_depth_texture") ||
!glutExtensionSupported("GL_ARB_shadow")) {
printf("Sorry, this demo requires the GL_ARB_depth_texture and GL_ARB_shadow extensions\n");
if (!glutExtensionSupported("GL_ARB_depth_texture")) {
printf("Sorry, this demo requires the GL_ARB_depth_texture extension\n");
exit(1);
}
printf("Using GL_ARB_depth_texture and GL_ARB_shadow\n");
HaveShadow = glutExtensionSupported("GL_ARB_shadow");
HaveVP = glutExtensionSupported("GL_ARB_vertex_program");
HaveFP = glutExtensionSupported("GL_ARB_fragment_program");
HaveFP_Shadow = glutExtensionSupported("GL_ARB_fragment_program_shadow");
if (!HaveShadow && !HaveFP) {
printf("Sorry, this demo requires either the GL_ARB_shadow extension "
"or the GL_ARB_fragment_program extension\n");
exit(1);
}
printf("Using GL_ARB_depth_texture\n");
if (HaveShadow) {
printf("and GL_ARB_shadow\n");
}
if (HaveFP) {
printf("and GL_ARB_fragment_program\n");
}
HaveShadowAmbient = glutExtensionSupported("GL_ARB_shadow_ambient");
if (HaveShadowAmbient) {
printf("and GL_ARB_shadow_ambient\n");
@ -895,9 +923,12 @@ Init(void)
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
GL_COMPARE_R_TO_TEXTURE_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
if (HaveShadow) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
GL_COMPARE_R_TO_TEXTURE_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
}
if (HaveShadowAmbient) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.3);
@ -954,6 +985,11 @@ Init(void)
max_frag = 3;
}
if (!HaveShadow) {
curr_frag = 1;
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, frag_progs[curr_frag]);
}
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

View file

@ -1,13 +1,9 @@
/*
* GL_ARB_multitexture demo
* GL_ARB_pixel_buffer_object test
*
* Command line options:
* -info print GL implementation information
* -w WIDTH -h HEIGHT sets window size
*
*
* Brian Paul November 1998 This program is in the public domain.
* Modified on 12 Feb 2002 for > 2 texture units.
*/
#define GL_GLEXT_PROTOTYPES
@ -25,6 +21,8 @@
#define PBO 11
#define QUIT 100
static GLuint DrawPBO;
static GLboolean Animate = GL_TRUE;
static GLboolean use_pbo = 1;
static GLboolean whole_rect = 1;
@ -49,7 +47,7 @@ static void Idle( void )
}
}
static int max( int a, int b ) { return a > b ? a : b; }
/*static int max( int a, int b ) { return a > b ? a : b; }*/
static int min( int a, int b ) { return a < b ? a : b; }
static void DrawObject()
@ -62,6 +60,7 @@ static void DrawObject()
* release the old copy of the texture and allocate a new one
* without waiting for outstanding rendering to complete.
*/
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO);
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, size, NULL, GL_STREAM_DRAW_ARB);
{
@ -69,7 +68,7 @@ static void DrawObject()
printf("char %d\n", (unsigned char)(Drift * 255));
memset(image, size, (unsigned char)(Drift * 255));
memset(image, (unsigned char)(Drift * 255), size);
glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT);
}
@ -86,7 +85,9 @@ static void DrawObject()
if (image == NULL)
image = malloc(size);
memset(image, size, (unsigned char)(Drift * 255));
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
memset(image, (unsigned char)(Drift * 255), size);
/* BGRA should be the fast path for regular uploads as well.
*/
@ -227,12 +228,12 @@ static void SpecialKey( int key, int x, int y )
static void Init( int argc, char *argv[] )
{
const char *exten = (const char *) glGetString(GL_EXTENSIONS);
GLuint texObj, DrawPBO;
GLuint texObj;
GLint size;
if (!strstr(exten, "GL_ARB_multitexture")) {
printf("Sorry, GL_ARB_multitexture not supported by this renderer.\n");
if (!strstr(exten, "GL_ARB_pixel_buffer_object")) {
printf("Sorry, GL_ARB_pixel_buffer_object not supported by this renderer.\n");
exit(1);
}

4
progs/directfb/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
df_gears
df_morph3d
df_reflect
multi_window

View file

@ -11,6 +11,8 @@ LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME)
CFLAGS += $(shell pkg-config --cflags directfb)
APP_LIB_DEPS += $(shell pkg-config --libs directfb)
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
PROGS = df_gears \
df_reflect \
df_morph3d \
@ -22,7 +24,7 @@ PROGS = df_gears \
.SUFFIXES: .c
.c: $(LIB_DEP)
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
##### TARGETS #####

5
progs/egl/.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
demo1
demo2
demo3
eglgears
eglinfo

1
progs/fbdev/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
glfbdevtest

View file

@ -15,6 +15,7 @@ INCLUDES = \
-I. \
-I$(TOP)/include
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
##### RULES #####
@ -22,7 +23,7 @@ INCLUDES = \
.SUFFIXES: .c
.c:
$(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@
$(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $< -o $@

42
progs/fp/.gitignore vendored Normal file
View file

@ -0,0 +1,42 @@
point-position
readtex.c
readtex.h
tri-abs
tri-add
tri-cmp
tri-cos
tri-depth
tri-depth2
tri-depthwrite
tri-depthwrite2
tri-dp3
tri-dp4
tri-dph
tri-dst
tri-ex2
tri-flr
tri-frc
tri-kil
tri-lg2
tri-lit
tri-lrp
tri-mad
tri-max
tri-min
tri-mov
tri-mul
tri-param
tri-position
tri-pow
tri-rcp
tri-rsq
tri-scs
tri-sge
tri-sge2
tri-sin
tri-slt
tri-sub
tri-swz
tri-swz2
tri-tex
tri-xpd

View file

@ -8,7 +8,7 @@ TOP = ../..
include $(TOP)/configs/current
LIBS = $(APP_LIB_DEPS)
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
SOURCES = \
tri-abs.c \

13
progs/glsl/.gitignore vendored Normal file
View file

@ -0,0 +1,13 @@
bitmap
brick
bump
deriv
extfuncs.h
mandelbrot
noise
points
readtex.c
readtex.h
texdemo1
trirast
toyball

View file

@ -49,14 +49,15 @@ void main()
inorout += dot(distance, vec4(1.0));
distance.x = dot(p, HalfSpace4);
distance.y = StripeWidth - abs(p.z);
// distance.y = StripeWidth - abs(p.z);
distance.y = StripeWidth - abs(p.y);
distance = smoothstep(-FWidth, FWidth, distance);
inorout += distance.x;
inorout = clamp(inorout, 0.0, 1.0);
surfColor = mix(Yellow, Red, inorout);
surfColor = mix(surfColor, Blue, distance.y);
surfColor = mix(Yellow, Blue, distance.y);
surfColor = mix(surfColor, Red, inorout);
// normal = point on surface for sphere at (0,0,0)
normal = p;

View file

@ -14,10 +14,11 @@ uniform vec4 BallCenter; // ball center in modelling coordinates
void main()
{
//orig: ECposition = gl_ModelViewMatrix * gl_Vertex;
ECposition = gl_ModelViewMatrix * gl_Vertex;
ECposition = gl_TextureMatrix[0] * gl_Vertex;
ECposition = gl_ModelViewMatrix * ECposition;
// ECposition = gl_TextureMatrix[0] * gl_Vertex;
// ECposition = gl_MultiTexCoord0 * gl_Vertex;
// ECposition = gl_ModelViewMatrix * ECposition;
ECballCenter = gl_ModelViewMatrix * BallCenter;
gl_Position = ftransform();

View file

@ -7,6 +7,8 @@ INCDIR = $(TOP)/include
LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME)
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
PROGS = \
bitmap \
brick \
@ -28,7 +30,7 @@ PROGS = \
# make executable from .c file:
.c: $(LIB_DEP)
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
##### TARGETS #####
@ -64,7 +66,7 @@ points.c: extfuncs.h
toyball.c: extfuncs.h
texdemo1: texdemo1.o readtex.o
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) texdemo1.o readtex.o $(APP_LIB_DEPS) -o $@
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) texdemo1.o readtex.o $(LIBS) -o $@
texdemo1.o: texdemo1.c readtex.h extfuncs.h
$(CC) -c -I$(INCDIR) $(CFLAGS) texdemo1.c

View file

@ -247,7 +247,7 @@ LoadAndCompileShader(GLuint shader, const char *text)
GLchar log[1000];
GLsizei len;
glGetShaderInfoLog_func(shader, 1000, &len, log);
fprintf(stderr, "brick: problem compiling shader: %s\n", log);
fprintf(stderr, "bump: problem compiling shader: %s\n", log);
exit(1);
}
else {
@ -267,12 +267,12 @@ ReadShader(GLuint shader, const char *filename)
char *buffer = (char*) malloc(max);
FILE *f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
fprintf(stderr, "bump: Unable to open shader file %s\n", filename);
exit(1);
}
n = fread(buffer, 1, max, f);
printf("brick: read %d bytes from shader file %s\n", n, filename);
printf("bump: read %d bytes from shader file %s\n", n, filename);
if (n > 0) {
buffer[n] = 0;
LoadAndCompileShader(shader, buffer);

View file

@ -172,7 +172,7 @@ LoadAndCompileShader(GLuint shader, const char *text)
GLchar log[1000];
GLsizei len;
glGetShaderInfoLog_func(shader, 1000, &len, log);
fprintf(stderr, "brick: problem compiling shader: %s\n", log);
fprintf(stderr, "mandelbrot: problem compiling shader: %s\n", log);
exit(1);
}
else {
@ -192,12 +192,12 @@ ReadShader(GLuint shader, const char *filename)
char *buffer = (char*) malloc(max);
FILE *f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
fprintf(stderr, "mandelbrot: Unable to open shader file %s\n", filename);
exit(1);
}
n = fread(buffer, 1, max, f);
printf("brick: read %d bytes from shader file %s\n", n, filename);
printf("mandelbrot: read %d bytes from shader file %s\n", n, filename);
if (n > 0) {
buffer[n] = 0;
LoadAndCompileShader(shader, buffer);

View file

@ -188,7 +188,7 @@ LoadAndCompileShader(GLuint shader, const char *text)
GLchar log[1000];
GLsizei len;
glGetShaderInfoLog_func(shader, 1000, &len, log);
fprintf(stderr, "brick: problem compiling shader: %s\n", log);
fprintf(stderr, "noise: problem compiling shader: %s\n", log);
exit(1);
}
else {

View file

@ -185,7 +185,7 @@ LoadAndCompileShader(GLuint shader, const char *text)
GLchar log[1000];
GLsizei len;
glGetShaderInfoLog_func(shader, 1000, &len, log);
fprintf(stderr, "brick: problem compiling shader: %s\n", log);
fprintf(stderr, "toyball: problem compiling shader: %s\n", log);
exit(1);
}
else {
@ -205,12 +205,12 @@ ReadShader(GLuint shader, const char *filename)
char *buffer = (char*) malloc(max);
FILE *f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "brick: Unable to open shader file %s\n", filename);
fprintf(stderr, "toyball: Unable to open shader file %s\n", filename);
exit(1);
}
n = fread(buffer, 1, max, f);
printf("brick: read %d bytes from shader file %s\n", n, filename);
printf("toyball: read %d bytes from shader file %s\n", n, filename);
if (n > 0) {
buffer[n] = 0;
LoadAndCompileShader(shader, buffer);

6
progs/miniglx/.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
manytex
miniglxsample
miniglxtest
sample_server
sample_server2
texline

View file

@ -20,6 +20,8 @@ INCLUDES = \
-I. \
-I$(TOP)/include
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
##### RULES #####
@ -27,7 +29,7 @@ INCLUDES = \
.SUFFIXES: .c
.c:
$(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@
$(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $< -o $@

8
progs/osdemos/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
osdemo
osdemo16
osdemo32
ostest1
readtex.c
readtex.h
showbuffer.c
showbuffer.h

View file

@ -13,6 +13,8 @@ OSMESA32_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa32 -lGLU -lGL $(APP_LIB_DEPS)
LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME)
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
PROGS = \
osdemo \
ostest1
@ -26,7 +28,7 @@ PROGS = \
# make executable from .c file:
.c: $(LIB_DEP) readtex.o
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< readtex.o $(APP_LIB_DEPS) -o $@
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< readtex.o $(LIBS) -o $@
##### TARGETS #####

View file

@ -7,6 +7,8 @@ INCDIR = $(TOP)/include
LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME)
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
PROGS = aaindex aapoly aargb accanti accpersp alpha alpha3D anti \
bezcurve bezmesh checker clip colormat cube depthcue dof \
double drawf feedback fog fogindex font hello image light \
@ -24,7 +26,7 @@ PROGS = aaindex aapoly aargb accanti accpersp alpha alpha3D anti \
.SUFFIXES: .c
.c: $(LIB_DEP)
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@

View file

@ -1,24 +1,41 @@
.cvsignore
accum
anywin
bdemo
binfo
bitmap1
bitmap2
blendeq
blendxor
bugger
copy
cursor
demo
depth
eval
ffset
fog
font
font
incopy
line
logo
lthreads
lxdemo
lxgears
lxheads
lxinfo
lxpixmap
nurb
oglinfo
olympic
overlay
pend
point
prim
quad
readtex.c
readtex.h
select
shape
sphere
@ -28,18 +45,3 @@ stretch
texture
tri
wave
bugger
pend
lthreads
lxdemo
lxgears
lxheads
lxinfo
lxpixmap
anywin
ffset
bdemo
binfo
incopy
demo
font

View file

@ -7,6 +7,8 @@ INCDIR = $(TOP)/include
LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME)
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
PROGS = accum bitmap1 bitmap2 blendeq blendxor copy cursor depth eval fog \
font line logo nurb olympic overlay point prim quad select \
shape sphere star stencil stretch texture tri wave
@ -18,7 +20,7 @@ PROGS = accum bitmap1 bitmap2 blendeq blendxor copy cursor depth eval fog \
.SUFFIXES: .c
.c: $(LIB_DEP)
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
##### TARGETS #####
@ -27,7 +29,7 @@ default: $(PROGS)
sphere: sphere.o readtex.o
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) sphere.o readtex.o $(APP_LIB_DEPS) -o $@
$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) sphere.o readtex.o $(LIBS) -o $@
sphere.o: sphere.c readtex.h
$(CC) -c -I$(INCDIR) $(CFLAGS) sphere.c

3
progs/slang/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
cltest
sotest
vstest

View file

@ -8,6 +8,8 @@ INCDIR = $(TOP)/include
LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
#
# targets
#
@ -29,13 +31,13 @@ clean:
#
cltest: cltest.o framework.o $(LIB_DEP)
$(CC) $(LDFLAGS) cltest.o framework.o $(APP_LIB_DEPS) -o cltest
$(CC) $(LDFLAGS) cltest.o framework.o $(LIBS) -o cltest
sotest: sotest.o framework.o $(LIB_DEP)
$(CC) $(LDFLAGS) sotest.o framework.o $(APP_LIB_DEPS) -o sotest
$(CC) $(LDFLAGS) sotest.o framework.o $(LIBS) -o sotest
vstest: vstest.o framework.o $(LIB_DEP)
$(CC) $(LDFLAGS) vstest.o framework.o $(APP_LIB_DEPS) -o vstest
$(CC) $(LDFLAGS) vstest.o framework.o $(LIBS) -o vstest
#
# objects

View file

@ -1,5 +1,4 @@
.cvsignore
getproclist.h
afsmultiarb
antialias
arbfpspec
@ -34,17 +33,18 @@ fogcoord
fptest1
fptexture
getprocaddress
jkrahntest
getproclist.h
interleave
invert
jkrahntest
manytex
mipmap_limits
multipal
no_s3tc
packedpixels
pbo
projtex
prog_parameter
projtex
random
readrate
readtex.c

View file

@ -8,7 +8,7 @@ TOP = ../..
include $(TOP)/configs/current
LIBS = $(APP_LIB_DEPS)
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
SOURCES = \
afsmultiarb.c \

View file

@ -268,6 +268,32 @@ test_VertexAttrib4dvNV(generic_func func)
}
static GLboolean
test_StencilFuncSeparateATI(generic_func func)
{
#ifdef GL_ATI_separate_stencil
PFNGLSTENCILFUNCSEPARATEATIPROC stencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC) func;
GLint frontFunc, backFunc;
GLint frontRef, backRef;
GLint frontMask, backMask;
(*stencilFuncSeparateATI)(GL_LESS, GL_GREATER, 2, 0xa);
glGetIntegerv(GL_STENCIL_FUNC, &frontFunc);
glGetIntegerv(GL_STENCIL_BACK_FUNC, &backFunc);
glGetIntegerv(GL_STENCIL_REF, &frontRef);
glGetIntegerv(GL_STENCIL_BACK_REF, &backRef);
glGetIntegerv(GL_STENCIL_VALUE_MASK, &frontMask);
glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &backMask);
if (frontFunc != GL_LESS ||
backFunc != GL_GREATER ||
frontRef != 2 ||
backRef != 2 ||
frontMask != 0xa ||
backMask != 0xa)
return GL_FALSE;
#endif
return GL_TRUE;
}
static GLboolean
test_StencilFuncSeparate(generic_func func)
{

1
progs/tools/trace/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
gltrace.cc

65
progs/trivial/.gitignore vendored Normal file
View file

@ -0,0 +1,65 @@
clear
dlist-dangling
dlist-edgeflag
dlist-edgeflag-dangling
drawarrays
drawelements
drawrange
line
line-clip
line-cull
line-userclip
line-userclip-clip
line-userclip-nop
line-userclip-nop-clip
lineloop
lineloop-clip
point
point-clip
point-param
point-wide
poly
poly-flat
poly-unfilled
quad
quad-clip
quad-clip-all-vertices
quad-clip-nearplane
quad-degenerate
quad-flat
quad-offset-factor
quad-offset-unfilled
quad-offset-units
quad-tex-2d
quad-tex-3d
quad-tex-pbo
quad-unfilled
quads
quadstrip
quadstrip-flat
readtex.c
readtex.h
tri
tri-blend
tri-clip
tri-cull
tri-dlist
tri-edgeflag
tri-flat
tri-flat-clip
tri-tex-3d
tri-unfilled
tri-unfilled-clip
tri-unfilled-smooth
tri-unfilled-userclip
tri-userclip
tristrip
tristrip-clip
vbo-drawarrays
vbo-drawelements
vbo-drawrange
vp-array
vp-clip
vp-line-clip
vp-tri
vp-unfilled

View file

@ -8,7 +8,7 @@ TOP = ../..
include $(TOP)/configs/current
LIBS = $(APP_LIB_DEPS)
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
SOURCES = \
clear.c \

1
progs/vp/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
vp-tris

View file

@ -8,7 +8,7 @@ TOP = ../..
include $(TOP)/configs/current
LIBS = $(APP_LIB_DEPS)
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
SOURCES = \
vp-tris.c

View file

@ -1,3 +1,4 @@
corender
glthreads
glxcontexts
glxdemo
@ -5,14 +6,15 @@ glxgears
glxgears_fbconfig
glxheads
glxinfo
glxpixmap
glxpbdemo
glxpixmap
glxsnoop
glxswapcontrol
manywin
offset
overlay
pbinfo
pbdemo
pbinfo
texture_from_pixmap
wincopy
xdemo

View file

@ -8,7 +8,11 @@ INCDIR = $(TOP)/include
LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME)
PROGS = glthreads \
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
PROGS = \
corender \
glthreads \
glxdemo \
glxgears \
glxgears_fbconfig \
@ -17,6 +21,7 @@ PROGS = glthreads \
glxinfo \
glxpixmap \
glxpbdemo \
glxsnoop \
glxswapcontrol \
manywin \
offset \
@ -38,7 +43,7 @@ PROGS = glthreads \
.SUFFIXES: .c
.c: $(LIB_DEP)
$(CC) -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@
$(CC) -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
##### TARGETS #####
@ -53,10 +58,10 @@ clean:
# special cases
pbinfo: pbinfo.o pbutil.o
$(CC) $(LDFLAGS) pbinfo.o pbutil.o $(APP_LIB_DEPS) -o $@
$(CC) $(LDFLAGS) pbinfo.o pbutil.o $(LIBS) -o $@
pbdemo: pbdemo.o pbutil.o
$(CC) $(LDFLAGS) pbdemo.o pbutil.o $(APP_LIB_DEPS) -o $@
$(CC) $(LDFLAGS) pbdemo.o pbutil.o $(LIBS) -o $@
pbinfo.o: pbinfo.c pbutil.h
$(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) pbinfo.c
@ -68,13 +73,13 @@ pbutil.o: pbutil.c pbutil.h
$(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) pbutil.c
glxgears_fbconfig: glxgears_fbconfig.o pbutil.o
$(CC) $(LDFLAGS) glxgears_fbconfig.o pbutil.o $(APP_LIB_DEPS) -o $@
$(CC) $(LDFLAGS) glxgears_fbconfig.o pbutil.o $(LIBS) -o $@
glxgears_fbconfig.o: glxgears_fbconfig.c pbutil.h
$(CC) -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) -c -I. $(CFLAGS) glxgears_fbconfig.c
xrotfontdemo: xrotfontdemo.o xuserotfont.o
$(CC) $(LDFLAGS) xrotfontdemo.o xuserotfont.o $(APP_LIB_DEPS) -o $@
$(CC) $(LDFLAGS) xrotfontdemo.o xuserotfont.o $(LIBS) -o $@
xuserotfont.o: xuserotfont.c xuserotfont.h
$(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) xuserotfont.c
@ -82,3 +87,11 @@ xuserotfont.o: xuserotfont.c xuserotfont.h
xrotfontdemo.o: xrotfontdemo.c xuserotfont.h
$(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) xrotfontdemo.c
corender: corender.o ipc.o
$(CC) $(CFLAGS) corender.o ipc.o $(LIBS) -o $@
corender.o: corender.c ipc.h
$(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) corender.c
ipc.o: ipc.c ipc.h
$(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) ipc.c

396
progs/xdemos/corender.c Normal file
View file

@ -0,0 +1,396 @@
/**
* Example of cooperative rendering into one window by two processes.
* The first instance of the program creates the GLX window.
* The second instance of the program gets the window ID from the first
* and draws into it.
* Socket IPC is used for synchronization.
*
* Usage:
* 1. run 'corender &'
* 2. run 'corender 2' (any arg will do)
*
* Brian Paul
* 11 Oct 2007
*/
#include <GL/gl.h>
#include <GL/glx.h>
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/keysym.h>
#include <unistd.h>
#include "ipc.h"
static int MyID = 0; /* 0 or 1 */
static int WindowID = 0;
static GLXContext Context = 0;
static int Width = 700, Height = 350;
static int Rot = 0;
static int Sock = 0;
static GLfloat Red[4] = {1.0, 0.2, 0.2, 1.0};
static GLfloat Blue[4] = {0.2, 0.2, 1.0, 1.0};
static int Sync = 1; /** synchronized rendering? */
static void
setup_ipc(void)
{
int k, port = 10001;
if (MyID == 0) {
/* I'm the first one, wait for connection from second */
k = CreatePort(&port);
assert(k != -1);
printf("Waiting for connection from another 'corender'\n");
Sock = AcceptConnection(k);
printf("Got connection, sending windowID\n");
/* send windowID */
SendData(Sock, &WindowID, sizeof(WindowID));
}
else {
/* I'm the second one, connect to first */
char hostname[1000];
MyHostName(hostname, 1000);
Sock = Connect(hostname, port);
assert(Sock != -1);
/* get windowID */
ReceiveData(Sock, &WindowID, sizeof(WindowID));
printf("Contacted first 'corender', getting WindowID\n");
}
}
/** from GLUT */
static void
doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
{
int i, j;
GLfloat theta, phi, theta1;
GLfloat cosTheta, sinTheta;
GLfloat cosTheta1, sinTheta1;
GLfloat ringDelta, sideDelta;
ringDelta = 2.0 * M_PI / rings;
sideDelta = 2.0 * M_PI / nsides;
theta = 0.0;
cosTheta = 1.0;
sinTheta = 0.0;
for (i = rings - 1; i >= 0; i--) {
theta1 = theta + ringDelta;
cosTheta1 = cos(theta1);
sinTheta1 = sin(theta1);
glBegin(GL_QUAD_STRIP);
phi = 0.0;
for (j = nsides; j >= 0; j--) {
GLfloat cosPhi, sinPhi, dist;
phi += sideDelta;
cosPhi = cos(phi);
sinPhi = sin(phi);
dist = R + r * cosPhi;
glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
}
glEnd();
theta = theta1;
cosTheta = cosTheta1;
sinTheta = sinTheta1;
}
}
static void
redraw(Display *dpy)
{
int dbg = 0;
glXMakeCurrent(dpy, WindowID, Context);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glClearColor(0.5, 0.5, 0.5, 0.0);
if (MyID == 0) {
/* First process */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(-1, 0, 0);
glRotatef(Rot, 1, 0, 0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Red);
doughnut(0.5, 2.0, 20, 30);
glPopMatrix();
glFinish();
if (!Sync) {
usleep(1000*10);
}
/* signal second process to render */
if (Sync) {
int code = 1;
if (dbg) printf("0: send signal\n");
SendData(Sock, &code, sizeof(code));
SendData(Sock, &Rot, sizeof(Rot));
}
/* wait for second process to finish rendering */
if (Sync) {
int code = 0;
if (dbg) printf("0: wait signal\n");
ReceiveData(Sock, &code, sizeof(code));
if (dbg) printf("0: got signal\n");
assert(code == 2);
}
}
else {
/* Second process */
/* wait for first process's signal for me to render */
if (Sync) {
int code = 0;
if (dbg) printf("1: wait signal\n");
ReceiveData(Sock, &code, sizeof(code));
ReceiveData(Sock, &Rot, sizeof(Rot));
if (dbg) printf("1: got signal\n");
assert(code == 1);
}
/* XXX this clear should not be here, but for some reason, it
* makes things _mostly_ work correctly w/ NVIDIA's driver.
* There's only occasional glitches.
* Without this glClear(), depth buffer for the second process
* is pretty much broken.
*/
//glClear(GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(1, 0, 0);
glRotatef(Rot + 90 , 1, 0, 0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Blue);
doughnut(0.5, 2.0, 20, 30);
glPopMatrix();
glFinish();
glXSwapBuffers(dpy, WindowID);
usleep(1000*10);
/* signal first process that I'm done rendering */
if (Sync) {
int code = 2;
if (dbg) printf("1: send signal\n");
SendData(Sock, &code, sizeof(code));
}
}
}
static void
resize(Display *dpy, int width, int height)
{
float ar = (float) width / height;
glXMakeCurrent(dpy, WindowID, Context);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, 1.0, -1.0, 5.0, 200.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -15);
Width = width;
Height = height;
}
static void
set_window_title(Display *dpy, Window win, const char *title)
{
XSizeHints sizehints;
sizehints.flags = 0;
XSetStandardProperties(dpy, win, title, title,
None, (char **)NULL, 0, &sizehints);
}
static Window
make_gl_window(Display *dpy, XVisualInfo *visinfo, int width, int height)
{
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
Window win;
int x = 0, y = 0;
char *name = NULL;
scrnum = DefaultScreen( dpy );
root = RootWindow( dpy, scrnum );
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow( dpy, root, x, y, width, height,
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = x;
sizehints.y = y;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(dpy, win, &sizehints);
XSetStandardProperties(dpy, win, name, name,
None, (char **)NULL, 0, &sizehints);
}
return win;
}
static void
set_event_mask(Display *dpy, Window win)
{
XSetWindowAttributes attr;
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
XChangeWindowAttributes(dpy, win, CWEventMask, &attr);
}
static void
event_loop(Display *dpy)
{
while (1) {
while (XPending(dpy) > 0) {
XEvent event;
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
redraw(dpy);
break;
case ConfigureNotify:
resize(dpy, event.xconfigure.width, event.xconfigure.height);
break;
case KeyPress:
{
char buffer[10];
int r, code;
code = XLookupKeysym(&event.xkey, 0);
if (code == XK_Left) {
}
else {
r = XLookupString(&event.xkey, buffer, sizeof(buffer),
NULL, NULL);
if (buffer[0] == 27) {
exit(0);
}
}
}
default:
/* nothing */
;
}
}
if (MyID == 0 || !Sync)
Rot += 1;
redraw(dpy);
}
}
static XVisualInfo *
choose_visual(Display *dpy)
{
int attribs[] = { GLX_RGBA,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DOUBLEBUFFER,
GLX_DEPTH_SIZE, 1,
None };
int scrnum = DefaultScreen( dpy );
return glXChooseVisual(dpy, scrnum, attribs);
}
static void
parse_opts(int argc, char *argv[])
{
if (argc > 1) {
MyID = 1;
}
}
int
main( int argc, char *argv[] )
{
Display *dpy;
XVisualInfo *visinfo;
parse_opts(argc, argv);
dpy = XOpenDisplay(NULL);
visinfo = choose_visual(dpy);
Context = glXCreateContext( dpy, visinfo, NULL, True );
if (!Context) {
printf("Error: glXCreateContext failed\n");
exit(1);
}
if (MyID == 0) {
WindowID = make_gl_window(dpy, visinfo, Width, Height);
set_window_title(dpy, WindowID, "corender");
XMapWindow(dpy, WindowID);
/*printf("WindowID 0x%x\n", (int) WindowID);*/
}
/* do ipc hand-shake here */
setup_ipc();
assert(Sock);
assert(WindowID);
if (MyID == 1) {
set_event_mask(dpy, WindowID);
}
resize(dpy, Width, Height);
event_loop(dpy);
return 0;
}

View file

@ -52,6 +52,13 @@
#define GLX_TRANSPARENT_RGB 0x8008
#endif
#ifndef GLX_RGBA_BIT
#define GLX_RGBA_BIT 0x00000001
#endif
#ifndef GLX_COLOR_INDEX_BIT
#define GLX_COLOR_INDEX_BIT 0x00000002
#endif
typedef enum
{
@ -81,7 +88,7 @@ struct visual_attribs
int transparentIndexValue;
int bufferSize;
int level;
int rgba;
int render_type;
int doubleBuffer;
int stereo;
int auxBuffers;
@ -388,20 +395,61 @@ print_screen_info(Display *dpy, int scrnum, Bool allowDirect, GLboolean limits)
XSetWindowAttributes attr;
unsigned long mask;
Window root;
GLXContext ctx;
GLXContext ctx = NULL;
XVisualInfo *visinfo;
int width = 100, height = 100;
root = RootWindow(dpy, scrnum);
visinfo = glXChooseVisual(dpy, scrnum, attribSingle);
if (!visinfo) {
if (!visinfo)
visinfo = glXChooseVisual(dpy, scrnum, attribDouble);
if (!visinfo) {
fprintf(stderr, "Error: couldn't find RGB GLX visual\n");
return;
if (visinfo)
ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect );
#ifdef GLX_VERSION_1_3
{
int fbAttribSingle[] = {
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DOUBLEBUFFER, GL_TRUE,
None };
int fbAttribDouble[] = {
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
None };
GLXFBConfig *configs = NULL;
int nConfigs;
if (!visinfo)
configs = glXChooseFBConfig(dpy, scrnum, fbAttribSingle, &nConfigs);
if (!visinfo)
configs = glXChooseFBConfig(dpy, scrnum, fbAttribDouble, &nConfigs);
if (configs) {
visinfo = glXGetVisualFromFBConfig(dpy, configs[0]);
ctx = glXCreateNewContext(dpy, configs[0], GLX_RGBA_TYPE, NULL, allowDirect);
XFree(configs);
}
}
#endif
if (!visinfo) {
fprintf(stderr, "Error: couldn't find RGB GLX visual or fbconfig\n");
return;
}
if (!ctx) {
fprintf(stderr, "Error: glXCreateContext failed\n");
XFree(visinfo);
XDestroyWindow(dpy, win);
return;
}
attr.background_pixel = 0;
attr.border_pixel = 0;
@ -412,14 +460,6 @@ print_screen_info(Display *dpy, int scrnum, Bool allowDirect, GLboolean limits)
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &attr);
ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect );
if (!ctx) {
fprintf(stderr, "Error: glXCreateContext failed\n");
XFree(visinfo);
XDestroyWindow(dpy, win);
return;
}
if (glXMakeCurrent(dpy, win, ctx)) {
const char *serverVendor = glXQueryServerString(dpy, scrnum, GLX_VENDOR);
const char *serverVersion = glXQueryServerString(dpy, scrnum, GLX_VERSION);
@ -541,12 +581,27 @@ visual_class_abbrev(int cls)
}
}
static const char *
visual_render_type_name(int type)
{
switch (type) {
case GLX_RGBA_BIT:
return "rgba";
case GLX_COLOR_INDEX_BIT:
return "ci";
case GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT:
return "rgba|ci";
default:
return "";
}
}
static void
static GLboolean
get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
struct visual_attribs *attribs)
{
const char *ext = glXQueryExtensionsString(dpy, vInfo->screen);
int rgba;
memset(attribs, 0, sizeof(struct visual_attribs));
@ -563,11 +618,17 @@ get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
attribs->colormapSize = vInfo->colormap_size;
attribs->bitsPerRGB = vInfo->bits_per_rgb;
if (glXGetConfig(dpy, vInfo, GLX_USE_GL, &attribs->supportsGL) != 0)
return;
if (glXGetConfig(dpy, vInfo, GLX_USE_GL, &attribs->supportsGL) != 0 ||
!attribs->supportsGL)
return GL_FALSE;
glXGetConfig(dpy, vInfo, GLX_BUFFER_SIZE, &attribs->bufferSize);
glXGetConfig(dpy, vInfo, GLX_LEVEL, &attribs->level);
glXGetConfig(dpy, vInfo, GLX_RGBA, &attribs->rgba);
glXGetConfig(dpy, vInfo, GLX_RGBA, &rgba);
if (rgba)
attribs->render_type = GLX_RGBA_BIT;
else
attribs->render_type = GLX_COLOR_INDEX_BIT;
glXGetConfig(dpy, vInfo, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
glXGetConfig(dpy, vInfo, GLX_STEREO, &attribs->stereo);
glXGetConfig(dpy, vInfo, GLX_AUX_BUFFERS, &attribs->auxBuffers);
@ -616,8 +677,97 @@ get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
#else
attribs->visualCaveat = 0;
#endif
return GL_TRUE;
}
#ifdef GLX_VERSION_1_3
static int
glx_token_to_visual_class(int visual_type)
{
switch (visual_type) {
case GLX_TRUE_COLOR:
return TrueColor;
case GLX_DIRECT_COLOR:
return DirectColor;
case GLX_PSEUDO_COLOR:
return PseudoColor;
case GLX_STATIC_COLOR:
return StaticColor;
case GLX_GRAY_SCALE:
return GrayScale;
case GLX_STATIC_GRAY:
return StaticGray;
case GLX_NONE:
default:
return None;
}
}
static GLboolean
get_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig,
struct visual_attribs *attribs)
{
int visual_type;
memset(attribs, 0, sizeof(struct visual_attribs));
glXGetFBConfigAttrib(dpy, fbconfig, GLX_FBCONFIG_ID, &attribs->id);
#if 0
attribs->depth = vInfo->depth;
attribs->redMask = vInfo->red_mask;
attribs->greenMask = vInfo->green_mask;
attribs->blueMask = vInfo->blue_mask;
attribs->colormapSize = vInfo->colormap_size;
attribs->bitsPerRGB = vInfo->bits_per_rgb;
#endif
glXGetFBConfigAttrib(dpy, fbconfig, GLX_X_VISUAL_TYPE, &visual_type);
attribs->klass = glx_token_to_visual_class(visual_type);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_BUFFER_SIZE, &attribs->bufferSize);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_LEVEL, &attribs->level);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_RENDER_TYPE, &attribs->render_type);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_STEREO, &attribs->stereo);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_AUX_BUFFERS, &attribs->auxBuffers);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_RED_SIZE, &attribs->redSize);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_GREEN_SIZE, &attribs->greenSize);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_BLUE_SIZE, &attribs->blueSize);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_ALPHA_SIZE, &attribs->alphaSize);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_DEPTH_SIZE, &attribs->depthSize);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_STENCIL_SIZE, &attribs->stencilSize);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize);
/* get transparent pixel stuff */
glXGetFBConfigAttrib(dpy, fbconfig,GLX_TRANSPARENT_TYPE, &attribs->transparentType);
if (attribs->transparentType == GLX_TRANSPARENT_RGB) {
glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue);
}
else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) {
glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue);
}
glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLE_BUFFERS, &attribs->numMultisample);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLES, &attribs->numSamples);
glXGetFBConfigAttrib(dpy, fbconfig, GLX_CONFIG_CAVEAT, &attribs->visualCaveat);
return GL_TRUE;
}
#endif
static void
print_visual_attribs_verbose(const struct visual_attribs *attribs)
@ -625,7 +775,8 @@ print_visual_attribs_verbose(const struct visual_attribs *attribs)
printf("Visual ID: %x depth=%d class=%s\n",
attribs->id, attribs->depth, visual_class_name(attribs->klass));
printf(" bufferSize=%d level=%d renderType=%s doubleBuffer=%d stereo=%d\n",
attribs->bufferSize, attribs->level, attribs->rgba ? "rgba" : "ci",
attribs->bufferSize, attribs->level,
visual_render_type_name(attribs->render_type),
attribs->doubleBuffer, attribs->stereo);
printf(" rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n",
attribs->redSize, attribs->greenSize,
@ -683,16 +834,17 @@ print_visual_attribs_short(const struct visual_attribs *attribs)
caveat = "None";
#endif
printf("0x%2x %2d %2s %2d %2d %2d %1s %2s %2s %2d %2d %2d %2d %2d %2d %2d",
printf("0x%02x %2d %2s %2d %2d %2d %c%c %c %c %2d %2d %2d %2d %2d %2d %2d",
attribs->id,
attribs->depth,
visual_class_abbrev(attribs->klass),
attribs->transparentType != GLX_NONE,
attribs->bufferSize,
attribs->level,
attribs->rgba ? "r" : "c",
attribs->doubleBuffer ? "y" : ".",
attribs->stereo ? "y" : ".",
(attribs->render_type & GLX_RGBA_BIT) ? 'r' : ' ',
(attribs->render_type & GLX_COLOR_INDEX_BIT) ? 'c' : ' ',
attribs->doubleBuffer ? 'y' : '.',
attribs->stereo ? 'y' : '.',
attribs->redSize, attribs->greenSize,
attribs->blueSize, attribs->alphaSize,
attribs->auxBuffers,
@ -728,7 +880,7 @@ print_visual_attribs_long(const struct visual_attribs *attribs)
attribs->transparentType != GLX_NONE,
attribs->bufferSize,
attribs->level,
attribs->rgba ? "rgba" : "ci ",
visual_render_type_name(attribs->render_type),
attribs->doubleBuffer,
attribs->stereo,
attribs->redSize, attribs->greenSize,
@ -751,42 +903,86 @@ print_visual_info(Display *dpy, int scrnum, InfoMode mode)
{
XVisualInfo theTemplate;
XVisualInfo *visuals;
int numVisuals;
int numVisuals, numGlxVisuals;
long mask;
int i;
struct visual_attribs attribs;
/* get list of all visuals on this screen */
theTemplate.screen = scrnum;
mask = VisualScreenMask;
visuals = XGetVisualInfo(dpy, mask, &theTemplate, &numVisuals);
if (mode == Verbose) {
for (i = 0; i < numVisuals; i++) {
struct visual_attribs attribs;
get_visual_attribs(dpy, &visuals[i], &attribs);
print_visual_attribs_verbose(&attribs);
}
numGlxVisuals = 0;
for (i = 0; i < numVisuals; i++) {
if (get_visual_attribs(dpy, &visuals[i], &attribs))
numGlxVisuals++;
}
else if (mode == Normal) {
if (numGlxVisuals == 0)
return;
printf("%d GLX Visuals\n", numGlxVisuals);
if (mode == Normal)
print_visual_attribs_short_header();
for (i = 0; i < numVisuals; i++) {
struct visual_attribs attribs;
get_visual_attribs(dpy, &visuals[i], &attribs);
print_visual_attribs_short(&attribs);
}
}
else if (mode == Wide) {
else if (mode == Wide)
print_visual_attribs_long_header();
for (i = 0; i < numVisuals; i++) {
struct visual_attribs attribs;
get_visual_attribs(dpy, &visuals[i], &attribs);
for (i = 0; i < numVisuals; i++) {
if (!get_visual_attribs(dpy, &visuals[i], &attribs))
continue;
if (mode == Verbose)
print_visual_attribs_verbose(&attribs);
else if (mode == Normal)
print_visual_attribs_short(&attribs);
else if (mode == Wide)
print_visual_attribs_long(&attribs);
}
}
printf("\n");
XFree(visuals);
}
#ifdef GLX_VERSION_1_3
static void
print_fbconfig_info(Display *dpy, int scrnum, InfoMode mode)
{
int numFBConfigs;
struct visual_attribs attribs;
GLXFBConfig *fbconfigs;
int i;
/* get list of all fbconfigs on this screen */
fbconfigs = glXGetFBConfigs(dpy, scrnum, &numFBConfigs);
if (numFBConfigs == 0)
return;
printf("%d GLXFBConfigs:\n", numFBConfigs);
if (mode == Normal)
print_visual_attribs_short_header();
else if (mode == Wide)
print_visual_attribs_long_header();
for (i = 0; i < numFBConfigs; i++) {
get_fbconfig_attribs(dpy, fbconfigs[i], &attribs);
if (mode == Verbose)
print_visual_attribs_verbose(&attribs);
else if (mode == Normal)
print_visual_attribs_short(&attribs);
else if (mode == Wide)
print_visual_attribs_long(&attribs);
}
printf("\n");
XFree(fbconfigs);
}
#endif
/*
* Stand-alone Mesa doesn't really implement the GLX protocol so it
@ -860,7 +1056,7 @@ find_best_visual(Display *dpy, int scrnum)
/* see if this vis is better than bestVis */
if ((!bestVis.supportsGL && vis.supportsGL) ||
(bestVis.visualCaveat != GLX_NONE_EXT) ||
(!bestVis.rgba && vis.rgba) ||
(!(bestVis.render_type & GLX_RGBA_BIT) && (vis.render_type & GLX_RGBA_BIT)) ||
(!bestVis.doubleBuffer && vis.doubleBuffer) ||
(bestVis.redSize < vis.redSize) ||
(bestVis.greenSize < vis.greenSize) ||
@ -957,6 +1153,9 @@ main(int argc, char *argv[])
print_screen_info(dpy, scrnum, allowDirect, limits);
printf("\n");
print_visual_info(dpy, scrnum, mode);
#ifdef GLX_VERSION_1_3
print_fbconfig_info(dpy, scrnum, mode);
#endif
if (scrnum + 1 < numScreens)
printf("\n\n");
}

377
progs/xdemos/glxsnoop.c Normal file
View file

@ -0,0 +1,377 @@
/**
* Display/snoop the z/stencil/back/front buffers of another app's window.
* Also, an example of the need for shared ancillary renderbuffers.
*
* Hint: use 'xwininfo' to get a window's ID.
*
* Brian Paul
* 11 Oct 2007
*/
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glx.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/keysym.h>
#define Z_BUFFER 1
#define STENCIL_BUFFER 2
#define BACK_BUFFER 3
#define FRONT_BUFFER 4
static int Buffer = BACK_BUFFER;
static int WindowID = 0;
static const char *DisplayName = NULL;
static GLXContext Context = 0;
static int Width, Height;
/**
* Grab the z/stencil/back/front image from the srcWin and display it
* (possibly converted to grayscale) in the dstWin.
*/
static void
redraw(Display *dpy, Window srcWin, Window dstWin )
{
GLubyte *image = malloc(Width * Height * 4);
glXMakeCurrent(dpy, srcWin, Context);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
if (Buffer == BACK_BUFFER) {
glReadBuffer(GL_BACK);
glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, image);
}
else if (Buffer == FRONT_BUFFER) {
glReadBuffer(GL_FRONT);
glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, image);
}
else if (Buffer == Z_BUFFER) {
GLfloat *z = malloc(Width * Height * sizeof(GLfloat));
int i;
glReadPixels(0, 0, Width, Height, GL_DEPTH_COMPONENT, GL_FLOAT, z);
for (i = 0; i < Width * Height; i++) {
image[i*4+0] =
image[i*4+1] =
image[i*4+2] = (GLint) (255.0 * z[i]);
image[i*4+3] = 255;
}
free(z);
}
else if (Buffer == STENCIL_BUFFER) {
GLubyte *sten = malloc(Width * Height * sizeof(GLubyte));
int i, min = 100, max = -1;
float step;
int sz;
glGetIntegerv(GL_STENCIL_BITS, &sz);
glReadPixels(0, 0, Width, Height,
GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, sten);
/* find min/max for converting stencil to grayscale */
for (i = 0; i < Width * Height; i++) {
if (sten[i] < min)
min = sten[i];
if (sten[i] > max)
max = sten[i];
}
if (min == max)
step = 0;
else
step = 255.0 / (float) (max - min);
for (i = 0; i < Width * Height; i++) {
image[i*4+0] =
image[i*4+1] =
image[i*4+2] = (GLint) ((sten[i] - min) * step);
image[i*4+3] = 255;
}
free(sten);
}
glXMakeCurrent(dpy, dstWin, Context);
glWindowPos2iARB(0, 0);
glDrawBuffer(GL_FRONT);
glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, image);
glFlush();
free(image);
}
static void
set_window_title(Display *dpy, Window win, const char *title)
{
XSizeHints sizehints;
sizehints.flags = 0;
XSetStandardProperties(dpy, win, title, title,
None, (char **)NULL, 0, &sizehints);
}
static Window
make_gl_window(Display *dpy, XVisualInfo *visinfo, int width, int height)
{
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
Window win;
int x = 0, y = 0;
char *name = NULL;
scrnum = DefaultScreen( dpy );
root = RootWindow( dpy, scrnum );
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow( dpy, root, x, y, width, height,
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = x;
sizehints.y = y;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(dpy, win, &sizehints);
XSetStandardProperties(dpy, win, name, name,
None, (char **)NULL, 0, &sizehints);
}
return win;
}
static void
update_window_title(Display *dpy, Window win)
{
char title[1000], *buf;
switch (Buffer) {
case Z_BUFFER:
buf = "Z";
break;
case STENCIL_BUFFER:
buf = "Stencil";
break;
case BACK_BUFFER:
buf = "Back";
break;
case FRONT_BUFFER:
buf = "Front";
break;
default:
buf = "";
}
sprintf(title, "glxsnoop window 0x%x (%s buffer)", (int) WindowID, buf);
set_window_title(dpy, win, title);
}
static void
keypress(Display *dpy, Window win, char key)
{
switch (key) {
case 27:
/* escape */
exit(0);
break;
case 's':
Buffer = STENCIL_BUFFER;
break;
case 'z':
Buffer = Z_BUFFER;
break;
case 'f':
Buffer = FRONT_BUFFER;
break;
case 'b':
Buffer = BACK_BUFFER;
break;
default:
return;
}
update_window_title(dpy, win);
redraw(dpy, WindowID, win);
}
static void
event_loop(Display *dpy, Window win)
{
XEvent event;
while (1) {
XNextEvent( dpy, &event );
switch (event.type) {
case Expose:
redraw(dpy, WindowID, win);
break;
case ConfigureNotify:
/*resize( event.xconfigure.width, event.xconfigure.height );*/
break;
case KeyPress:
{
char buffer[10];
int r, code;
code = XLookupKeysym(&event.xkey, 0);
if (code == XK_Left) {
}
else {
r = XLookupString(&event.xkey, buffer, sizeof(buffer),
NULL, NULL);
keypress(dpy, win, buffer[0]);
}
}
default:
/* nothing */
;
}
}
}
static VisualID
get_window_visualid(Display *dpy, Window win)
{
XWindowAttributes attr;
if (XGetWindowAttributes(dpy, win, &attr)) {
return attr.visual->visualid;
}
else {
return 0;
}
}
static void
get_window_size(Display *dpy, Window win, int *w, int *h)
{
XWindowAttributes attr;
if (XGetWindowAttributes(dpy, win, &attr)) {
*w = attr.width;
*h = attr.height;
}
else {
*w = *h = 0;
}
}
static XVisualInfo *
visualid_to_visualinfo(Display *dpy, VisualID vid)
{
XVisualInfo *vinfo, templ;
long mask;
int n;
templ.visualid = vid;
mask = VisualIDMask;
vinfo = XGetVisualInfo(dpy, mask, &templ, &n);
return vinfo;
}
static void
key_usage(void)
{
printf("Keyboard:\n");
printf(" z - display Z buffer\n");
printf(" s - display stencil buffer\n");
printf(" f - display front color buffer\n");
printf(" b - display back buffer\n");
}
static void
usage(void)
{
printf("Usage: glxsnoop [-display dpy] windowID\n");
key_usage();
}
static void
parse_opts(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0) {
usage();
exit(0);
}
else if (strcmp(argv[i], "-display") == 0) {
DisplayName = argv[i + 1];
i++;
}
else {
if (argv[i][0] == '0' && argv[i][1] == 'x') {
/* hex */
WindowID = strtol(argv[i], NULL, 16);
}
else {
WindowID = atoi(argv[i]);
}
break;
}
}
if (!WindowID) {
usage();
exit(0);
}
}
int
main( int argc, char *argv[] )
{
Display *dpy;
VisualID vid;
XVisualInfo *visinfo;
Window win;
parse_opts(argc, argv);
key_usage();
dpy = XOpenDisplay(DisplayName);
/* find the VisualID for the named window */
vid = get_window_visualid(dpy, WindowID);
get_window_size(dpy, WindowID, &Width, &Height);
visinfo = visualid_to_visualinfo(dpy, vid);
Context = glXCreateContext( dpy, visinfo, NULL, True );
if (!Context) {
printf("Error: glXCreateContext failed\n");
exit(1);
}
win = make_gl_window(dpy, visinfo, Width, Height);
XMapWindow(dpy, win);
update_window_title(dpy, win);
event_loop( dpy, win );
return 0;
}

264
progs/xdemos/ipc.c Normal file
View file

@ -0,0 +1,264 @@
/* Copyright (c) 2003 Tungsten Graphics, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files ("the
* Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions: The above copyright notice, the Tungsten
* Graphics splash screen, and this permission notice shall be included
* in all copies or substantial portions of the Software. THE SOFTWARE
* IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
* SHALL THE AUTHORS OR COPYRIGHT HOLDERS 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.
*/
/*
* Simple IPC API
* Brian Paul
*/
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "ipc.h"
#if defined(IRIX) || defined(irix)
typedef int socklen_t;
#endif
#define NO_DELAY 1
#define DEFAULT_MASTER_PORT 7011
/*
* Return my hostname in <nameOut>.
* Return 1 for success, 0 for error.
*/
int
MyHostName(char *nameOut, int maxNameLength)
{
int k = gethostname(nameOut, maxNameLength);
return k==0;
}
/*
* Create a socket attached to a port. Later, we can call AcceptConnection
* on the socket returned from this function.
* Return the new socket number or -1 if error.
*/
int
CreatePort(int *port)
{
char hostname[1000];
struct sockaddr_in servaddr;
struct hostent *hp;
int so_reuseaddr = 1;
int tcp_nodelay = 1;
int sock, k;
/* create socket */
sock = socket(AF_INET, SOCK_STREAM, 0);
assert(sock > 2);
/* get my host name */
k = gethostname(hostname, 1000);
assert(k == 0);
/* get hostent info */
hp = gethostbyname(hostname);
assert(hp);
/* initialize the servaddr struct */
memset(&servaddr, 0, sizeof(servaddr) );
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons((unsigned short) (*port));
memcpy((char *) &servaddr.sin_addr, hp->h_addr,
sizeof(servaddr.sin_addr));
/* deallocate when we exit */
k = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char *) &so_reuseaddr, sizeof(so_reuseaddr));
assert(k==0);
/* send packets immediately */
#if NO_DELAY
k = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(char *) &tcp_nodelay, sizeof(tcp_nodelay));
assert(k==0);
#endif
if (*port == 0)
*port = DEFAULT_MASTER_PORT;
k = 1;
while (k && (*port < 65534)) {
/* bind our address to the socket */
servaddr.sin_port = htons((unsigned short) (*port));
k = bind(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
if (k)
*port = *port + 1;
}
#if 0
printf("###### Real Port: %d\n", *port);
#endif
/* listen for connections */
k = listen(sock, 100);
assert(k == 0);
return sock;
}
/*
* Accept a connection on the named socket.
* Return a new socket for the new connection, or -1 if error.
*/
int
AcceptConnection(int socket)
{
struct sockaddr addr;
socklen_t addrLen;
int newSock;
addrLen = sizeof(addr);
newSock = accept(socket, &addr, &addrLen);
if (newSock == 1)
return -1;
else
return newSock;
}
/*
* Contact the server running on the given host on the named port.
* Return socket number or -1 if error.
*/
int
Connect(const char *hostname, int port)
{
struct sockaddr_in servaddr;
struct hostent *hp;
int sock, k;
int tcp_nodelay = 1;
assert(port);
sock = socket(AF_INET, SOCK_STREAM, 0);
assert(sock >= 0);
hp = gethostbyname(hostname);
assert(hp);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons((unsigned short) port);
memcpy((char *) &servaddr.sin_addr, hp->h_addr, sizeof(servaddr.sin_addr));
k = connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
if (k != 0) {
perror("Connect:");
return -1;
}
#if NO_DELAY
/* send packets immediately */
k = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(char *) &tcp_nodelay, sizeof(tcp_nodelay));
assert(k==0);
#endif
return sock;
}
void
CloseSocket(int socket)
{
close(socket);
}
int
SendData(int socket, const void *data, int bytes)
{
int sent = 0;
int b;
while (sent < bytes) {
b = write(socket, (char *) data + sent, bytes - sent);
if (b <= 0)
return -1; /* something broke */
sent += b;
}
return sent;
}
int
ReceiveData(int socket, void *data, int bytes)
{
int received = 0, b;
while (received < bytes) {
b = read(socket, (char *) data + received, bytes - received);
if (b <= 0)
return -1;
received += b;
}
return received;
}
int
SendString(int socket, const char *str)
{
const int len = strlen(str);
int sent, b;
/* first, send a 4-byte length indicator */
b = write(socket, &len, sizeof(len));
if (b <= 0)
return -1;
sent = SendData(socket, str, len);
assert(sent == len);
return sent;
}
int
ReceiveString(int socket, char *str, int maxLen)
{
int len, received, b;
/* first, read 4 bytes to see how long of string to receive */
b = read(socket, &len, sizeof(len));
if (b <= 0)
return -1;
assert(len <= maxLen); /* XXX fix someday */
assert(len >= 0);
received = ReceiveData(socket, str, len);
assert(received != -1);
assert(received == len);
str[len] = 0;
return received;
}

16
progs/xdemos/ipc.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef IPC_H
#define IPC_H
extern int MyHostName(char *nameOut, int maxNameLength);
extern int CreatePort(int *port);
extern int AcceptConnection(int socket);
extern int Connect(const char *hostname, int port);
extern void CloseSocket(int socket);
extern int SendData(int socket, const void *data, int bytes);
extern int ReceiveData(int socket, void *data, int bytes);
extern int SendString(int socket, const char *str);
extern int ReceiveString(int socket, char *str, int maxLen);
#endif /* IPC_H */

View file

@ -18,12 +18,12 @@
* Test if we pixel buffers are available for a particular X screen.
* Input: dpy - the X display
* screen - screen number
* Return: 0 = pixel buffers not available.
* 1 = pixel buffers are available via GLX 1.3.
* 2 = pixel buffers are available via GLX_SGIX_fbconfig/pbuffer.
* Return: 0 = fbconfigs not available.
* 1 = fbconfigs are available via GLX 1.3.
* 2 = fbconfigs and pbuffers are available via GLX_SGIX_fbconfig
*/
int
QueryPbuffers(Display *dpy, int screen)
QueryFBConfig(Display *dpy, int screen)
{
#if defined(GLX_VERSION_1_3)
{
@ -40,36 +40,55 @@ QueryPbuffers(Display *dpy, int screen)
}
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
/* Try the SGIX extensions */
{
char *extensions;
extensions = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
if (!extensions ||
!strstr(extensions,"GLX_SGIX_fbconfig") ||
!strstr(extensions,"GLX_SGIX_pbuffer")) {
return 0;
if (extensions && strstr(extensions,"GLX_SGIX_fbconfig")) {
return 2;
}
return 2;
}
#endif
return 0;
}
/**
* Test if we pixel buffers are available for a particular X screen.
* Input: dpy - the X display
* screen - screen number
* Return: 0 = pixel buffers not available.
* 1 = pixel buffers are available via GLX 1.3.
* 2 = pixel buffers are available via GLX_SGIX_fbconfig/pbuffer.
*/
int
QueryPbuffers(Display *dpy, int screen)
{
int ret;
ret = QueryFBConfig(dpy, screen);
if (ret == 2) {
char *extensions;
extensions = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
if (extensions && strstr(extensions, "GLX_SGIX_pbuffer"))
return 2;
else
return 0;
}
else
return ret;
}
FBCONFIG *
ChooseFBConfig(Display *dpy, int screen, const int attribs[], int *nConfigs)
{
int pbSupport = QueryPbuffers(dpy, screen);
int fbcSupport = QueryPbuffers(dpy, screen);
#if defined(GLX_VERSION_1_3)
if (pbSupport == 1) {
if (fbcSupport == 1) {
return glXChooseFBConfig(dpy, screen, attribs, nConfigs);
}
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
if (pbSupport == 2) {
if (fbcSupport == 2) {
return glXChooseFBConfigSGIX(dpy, screen, (int *) attribs, nConfigs);
}
#endif
@ -80,14 +99,14 @@ ChooseFBConfig(Display *dpy, int screen, const int attribs[], int *nConfigs)
FBCONFIG *
GetAllFBConfigs(Display *dpy, int screen, int *nConfigs)
{
int pbSupport = QueryPbuffers(dpy, screen);
int fbcSupport = QueryFBConfig(dpy, screen);
#if defined(GLX_VERSION_1_3)
if (pbSupport == 1) {
if (fbcSupport == 1) {
return glXGetFBConfigs(dpy, screen, nConfigs);
}
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
if (pbSupport == 2) {
if (fbcSupport == 2) {
/* The GLX_SGIX_fbconfig extensions says to pass NULL to get list
* of all available configurations.
*/
@ -101,14 +120,14 @@ GetAllFBConfigs(Display *dpy, int screen, int *nConfigs)
XVisualInfo *
GetVisualFromFBConfig(Display *dpy, int screen, FBCONFIG config)
{
int pbSupport = QueryPbuffers(dpy, screen);
int fbcSupport = QueryFBConfig(dpy, screen);
#if defined(GLX_VERSION_1_3)
if (pbSupport == 1) {
if (fbcSupport == 1) {
return glXGetVisualFromFBConfig(dpy, config);
}
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
if (pbSupport == 2) {
if (fbcSupport == 2) {
return glXGetVisualFromFBConfigSGIX(dpy, config);
}
#endif
@ -130,11 +149,11 @@ GetFBConfigAttrib(Display *dpy, int screen,
int attrib
)
{
int pbSupport = QueryPbuffers(dpy, screen);
int fbcSupport = QueryFBConfig(dpy, screen);
int value = 0;
#if defined(GLX_VERSION_1_3)
if (pbSupport == 1) {
if (fbcSupport == 1) {
/* ok */
if (glXGetFBConfigAttrib(dpy, config, attrib, &value) != 0) {
value = 0;
@ -145,7 +164,7 @@ GetFBConfigAttrib(Display *dpy, int screen,
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
if (pbSupport == 2) {
if (fbcSupport == 2) {
if (glXGetFBConfigAttribSGIX(dpy, config, attrib, &value) != 0) {
value = 0;
}
@ -295,9 +314,9 @@ PrintFBConfigInfo(Display *dpy, int screen, FBCONFIG config, Bool horizFormat)
GLXContext
CreateContext(Display *dpy, int screen, FBCONFIG config)
{
int pbSupport = QueryPbuffers(dpy, screen);
int fbcSupport = QueryFBConfig(dpy, screen);
#if defined(GLX_VERSION_1_3)
if (pbSupport == 1) {
if (fbcSupport == 1) {
/* GLX 1.3 */
GLXContext c;
c = glXCreateNewContext(dpy, config, GLX_RGBA_TYPE, NULL, True);
@ -309,7 +328,7 @@ CreateContext(Display *dpy, int screen, FBCONFIG config)
}
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
if (pbSupport == 2) {
if (fbcSupport == 2) {
GLXContext c;
c = glXCreateContextWithConfigSGIX(dpy, config, GLX_RGBA_TYPE_SGIX, NULL, True);
if (!c) {
@ -393,6 +412,7 @@ CreatePbuffer(Display *dpy, int screen, FBCONFIG config,
pBuffer = None;
}
XSync(dpy, False);
/* Restore original X error handler */
(void) XSetErrorHandler(oldHandler);

View file

@ -26,6 +26,9 @@
#endif
extern int
QueryFBConfig(Display *dpy, int screen);
extern int
QueryPbuffers(Display *dpy, int screen);

View file

@ -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

View file

@ -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;
}

View file

@ -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;
/**

View file

@ -460,8 +460,24 @@ glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
PUBLIC GLXPbuffer
glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attrib_list)
{
int i, width, height;
width = 0;
height = 0;
for (i = 0; attrib_list[i * 2]; i++) {
switch (attrib_list[i * 2]) {
case GLX_PBUFFER_WIDTH:
width = attrib_list[i * 2 + 1];
break;
case GLX_PBUFFER_HEIGHT:
height = attrib_list[i * 2 + 1];
break;
}
}
return (GLXPbuffer) CreatePbuffer( dpy, (__GLcontextModes *) config,
0, 0,
width, height,
attrib_list, GL_TRUE );
}

View file

@ -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,12 +473,36 @@ 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
/**
* Linked list of configurations for this screen.
* Linked list of glx visuals and fbconfigs for this screen.
*/
__GLcontextModes *configs;
__GLcontextModes *visuals, *configs;
/**
* Per-screen dynamic GLX extension tracking. The \c direct_support
@ -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__ */

View file

@ -61,41 +61,88 @@ 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);
}
XSync(dpy, GL_FALSE);
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 +377,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 +396,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 +531,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 +860,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
@ -841,12 +904,12 @@ PUBLIC int glXGetConfig(Display *dpy, XVisualInfo *vis, int attribute,
{
__GLXdisplayPrivate *priv;
__GLXscreenConfigs *psc;
__GLcontextModes *modes;
int status;
status = GetGLXPrivScreenConfig( dpy, vis->screen, & priv, & psc );
if ( status == Success ) {
const __GLcontextModes * const modes = _gl_context_modes_find_visual(
psc->configs, vis->visualid );
modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
/* Lookup attribute after first finding a match on the visual */
if ( modes != NULL ) {
@ -1224,7 +1287,7 @@ PUBLIC XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList)
** Compute a score for those that do
** Remember which visual, if any, got the highest score
*/
for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) {
for ( modes = psc->visuals ; modes != NULL ; modes = modes->next ) {
if ( fbconfigs_compatible( & test_config, modes )
&& ((best_config == NULL)
|| (fbconfig_compare( (const __GLcontextModes * const * const)&modes, &best_config ) < 0)) ) {
@ -1592,6 +1655,7 @@ PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements)
__GLcontextModes ** config = NULL;
int i;
*nelements = 0;
if ( (priv->screenConfigs != NULL)
&& (screen >= 0) && (screen <= ScreenCount(dpy))
&& (priv->screenConfigs[screen].configs != NULL)
@ -1616,8 +1680,10 @@ PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements)
for ( modes = priv->screenConfigs[screen].configs
; modes != NULL
; modes = modes->next ) {
config[i] = modes;
i++;
if ( modes->fbconfigID != GLX_DONT_CARE ) {
config[i] = modes;
i++;
}
}
}
}
@ -1669,16 +1735,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 +1781,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 +1792,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 +1811,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 +1839,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 +1857,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 +1876,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 +1904,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,21 +1935,31 @@ 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) {
int ret;
int64_t temp;
ret = psc->driScreen.getMSC( psc->driScreen.private, & temp );
*count = (unsigned) temp;
return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
if ( psc->msc && psc->driScreen.private ) {
__DRIdrawable * const pdraw =
GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
int64_t temp;
int ret;
/*
* Try to use getDrawableMSC first so we get the right
* counter...
*/
if (psc->msc->base.version >= 2 && psc->msc->getDrawableMSC)
ret = (*psc->msc->getDrawableMSC)( &psc->driScreen,
pdraw->private,
& temp);
else
ret = (*psc->msc->getMSC)( &psc->driScreen, & temp);
*count = (unsigned) temp;
return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
}
}
#else
@ -1907,7 +1970,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,23 +1979,17 @@ 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) ) {
int ret;
int64_t msc;
int64_t sbc;
GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
int ret;
int64_t msc;
int64_t sbc;
ret = (*pdraw->waitForMSC)( gc->currentDpy, pdraw->private,
0, divisor, remainder,
& msc, & sbc );
*count = (unsigned) msc;
return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
}
ret = (*psc->msc->waitForMSC)(pdraw, 0, divisor, remainder, &msc,
&sbc);
*count = (unsigned) msc;
return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
}
}
#else
@ -2084,7 +2141,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 +2150,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 +2182,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 +2242,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 +2258,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 +2273,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 +2293,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 +2307,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 +2334,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 +2346,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 +2375,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 +2398,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 +2415,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 +2493,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 +2934,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

View file

@ -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,10 @@ 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;
if (psc->drawHash)
__glxHashDestroy(psc->drawHash);
#endif
}
XFree((char*) priv->screenConfigs);
@ -694,21 +692,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 +715,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 +725,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 +737,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 +761,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 +817,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 +938,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 +953,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,8 +997,131 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
return psp;
}
#endif /* GLX_DIRECT_RENDERING */
static __GLcontextModes *
createConfigsFromProperties(Display *dpy, int nvisuals, int nprops,
int screen, GLboolean tagged_only)
{
INT32 buf[__GLX_TOTAL_CONFIG], *props;
unsigned prop_size;
__GLcontextModes *modes, *m;
int i;
if (nprops == 0)
return NULL;
/* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
/* Check number of properties */
if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
return NULL;
/* Allocate memory for our config structure */
modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes));
if (!modes)
return NULL;
prop_size = nprops * __GLX_SIZE_INT32;
if (prop_size <= sizeof(buf))
props = buf;
else
props = Xmalloc(prop_size);
/* Read each config structure and convert it into our format */
m = modes;
for (i = 0; i < nvisuals; i++) {
_XRead(dpy, (char *)props, prop_size);
/* Older X servers don't send this so we default it here. */
m->drawableType = GLX_WINDOW_BIT;
__glXInitializeVisualConfigFromTags(m, nprops, props,
tagged_only, GL_TRUE);
m->screen = screen;
m = m->next;
}
if (props != buf)
Xfree(props);
return modes;
}
static GLboolean
getVisualConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen)
{
xGLXGetVisualConfigsReq *req;
__GLXscreenConfigs *psc;
xGLXGetVisualConfigsReply reply;
LockDisplay(dpy);
psc = priv->screenConfigs + screen;
psc->visuals = NULL;
GetReq(GLXGetVisualConfigs, req);
req->reqType = priv->majorOpcode;
req->glxCode = X_GLXGetVisualConfigs;
req->screen = screen;
if (!_XReply(dpy, (xReply*) &reply, 0, False))
goto out;
psc->visuals = createConfigsFromProperties(dpy,
reply.numVisuals,
reply.numProps,
screen, GL_FALSE);
out:
UnlockDisplay(dpy);
return psc->visuals != NULL;
}
static GLboolean
getFBConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen)
{
xGLXGetFBConfigsReq *fb_req;
xGLXGetFBConfigsSGIXReq *sgi_req;
xGLXVendorPrivateWithReplyReq *vpreq;
xGLXGetFBConfigsReply reply;
__GLXscreenConfigs *psc;
psc = priv->screenConfigs + screen;
psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode,
X_GLXQueryServerString,
screen, GLX_EXTENSIONS);
LockDisplay(dpy);
psc->configs = NULL;
if (atof(priv->serverGLXversion) >= 1.3) {
GetReq(GLXGetFBConfigs, fb_req);
fb_req->reqType = priv->majorOpcode;
fb_req->glxCode = X_GLXGetFBConfigs;
fb_req->screen = screen;
} else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
GetReqExtra(GLXVendorPrivateWithReply,
sz_xGLXGetFBConfigsSGIXReq +
sz_xGLXVendorPrivateWithReplyReq, vpreq);
sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
sgi_req->reqType = priv->majorOpcode;
sgi_req->glxCode = X_GLXVendorPrivateWithReply;
sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
sgi_req->screen = screen;
} else
goto out;
if (!_XReply(dpy, (xReply*) &reply, 0, False))
goto out;
psc->configs = createConfigsFromProperties(dpy,
reply.numFBConfigs,
reply.numAttribs * 2,
screen, GL_TRUE);
out:
UnlockDisplay(dpy);
return psc->configs != NULL;
}
/*
** Allocate the memory for the per screen configs for each screen.
@ -1008,17 +1129,8 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
*/
static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
{
xGLXGetVisualConfigsReq *req;
xGLXGetFBConfigsReq *fb_req;
xGLXVendorPrivateWithReplyReq *vpreq;
xGLXGetFBConfigsSGIXReq *sgi_req;
xGLXGetVisualConfigsReply reply;
__GLXscreenConfigs *psc;
__GLcontextModes *config;
GLint i, j, nprops, screens;
INT32 buf[__GLX_TOTAL_CONFIG], *props;
unsigned supported_request = 0;
unsigned prop_size;
GLint i, screens;
/*
** First allocate memory for the array of per screen configs.
@ -1032,143 +1144,28 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
priv->screenConfigs = psc;
priv->serverGLXversion = __glXGetStringFromServer(dpy, priv->majorOpcode,
X_GLXQueryServerString,
0, GLX_VERSION);
X_GLXQueryServerString,
0, GLX_VERSION);
if ( priv->serverGLXversion == NULL ) {
FreeScreenConfigs(priv);
return GL_FALSE;
}
if ( atof( priv->serverGLXversion ) >= 1.3 ) {
supported_request = 1;
}
/*
** Now fetch each screens configs structures. If a screen supports
** GL (by returning a numVisuals > 0) then allocate memory for our
** config structure and then fill it in.
*/
for (i = 0; i < screens; i++, psc++) {
if ( supported_request != 1 ) {
psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode,
X_GLXQueryServerString,
i, GLX_EXTENSIONS);
if ( strstr( psc->serverGLXexts, "GLX_SGIX_fbconfig" ) != NULL ) {
supported_request = 2;
}
else {
supported_request = 3;
}
}
LockDisplay(dpy);
switch( supported_request ) {
case 1:
GetReq(GLXGetFBConfigs,fb_req);
fb_req->reqType = priv->majorOpcode;
fb_req->glxCode = X_GLXGetFBConfigs;
fb_req->screen = i;
break;
case 2:
GetReqExtra(GLXVendorPrivateWithReply,
sz_xGLXGetFBConfigsSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
sgi_req->reqType = priv->majorOpcode;
sgi_req->glxCode = X_GLXVendorPrivateWithReply;
sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
sgi_req->screen = i;
break;
case 3:
GetReq(GLXGetVisualConfigs,req);
req->reqType = priv->majorOpcode;
req->glxCode = X_GLXGetVisualConfigs;
req->screen = i;
break;
}
if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
/* Something is busted. Punt. */
UnlockDisplay(dpy);
SyncHandle();
FreeScreenConfigs(priv);
return GL_FALSE;
}
if (!reply.numVisuals) {
/* This screen does not support GL rendering */
UnlockDisplay(dpy);
continue;
}
/* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for
* FIXME: FBconfigs?
*/
/* Check number of properties */
nprops = reply.numProps;
if ((nprops < __GLX_MIN_CONFIG_PROPS) ||
(nprops > __GLX_MAX_CONFIG_PROPS)) {
/* Huh? Not in protocol defined limits. Punt */
UnlockDisplay(dpy);
SyncHandle();
FreeScreenConfigs(priv);
return GL_FALSE;
}
/* Allocate memory for our config structure */
psc->configs = _gl_context_modes_create(reply.numVisuals,
sizeof(__GLcontextModes));
if (!psc->configs) {
UnlockDisplay(dpy);
SyncHandle();
FreeScreenConfigs(priv);
return GL_FALSE;
}
/* Allocate memory for the properties, if needed */
if ( supported_request != 3 ) {
nprops *= 2;
}
prop_size = nprops * __GLX_SIZE_INT32;
if (prop_size <= sizeof(buf)) {
props = buf;
} else {
props = (INT32 *) Xmalloc(prop_size);
}
/* Read each config structure and convert it into our format */
config = psc->configs;
for (j = 0; j < reply.numVisuals; j++) {
assert( config != NULL );
_XRead(dpy, (char *)props, prop_size);
if ( supported_request != 3 ) {
config->rgbMode = GL_TRUE;
config->drawableType = GLX_WINDOW_BIT;
}
else {
config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
}
__glXInitializeVisualConfigFromTags( config, nprops, props,
(supported_request != 3),
GL_TRUE );
if ( config->fbconfigID == GLX_DONT_CARE ) {
config->fbconfigID = config->visualID;
}
config->screen = i;
config = config->next;
}
if (props != buf) {
Xfree((char *)props);
}
UnlockDisplay(dpy);
getVisualConfigs(dpy, priv, i);
getFBConfigs(dpy, priv, i);
#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 +1176,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
@ -1363,7 +1361,8 @@ GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)
if ( (dpy != NULL) && (size > 0) ) {
#ifdef USE_XCB
xcb_glx_render(c, ctx->currentContextTag, size, (char *)ctx->buf);
xcb_glx_render(c, ctx->currentContextTag, size,
(const uint8_t *)ctx->buf);
#else
/* Send the entire buffer as an X request */
LockDisplay(dpy);
@ -1504,33 +1503,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,
@ -1617,20 +1589,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 +1765,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;
}
}

View file

@ -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.

View file

@ -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 );

411
src/glx/x11/glxhash.c Normal file
View file

@ -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

16
src/glx/x11/glxhash.h Normal file
View file

@ -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_ */

View file

@ -300,7 +300,9 @@ __indirect_glNewList(GLuint list, GLenum mode)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -324,7 +326,9 @@ __indirect_glEndList(void)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 0;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -393,7 +397,9 @@ __indirect_glDeleteLists(GLuint list, GLsizei range)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -418,7 +424,9 @@ __indirect_glGenLists(GLsizei range)
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
GLuint retval = (GLuint) 0;
#ifndef USE_XCB
const GLuint cmdlen = 4;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -3716,7 +3724,9 @@ __indirect_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 28;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -3808,7 +3818,9 @@ __indirect_glGetClipPlane(GLenum plane, GLdouble * equation)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 4;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -3841,7 +3853,9 @@ __indirect_glGetLightfv(GLenum light, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -3879,7 +3893,9 @@ __indirect_glGetLightiv(GLenum light, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -3917,7 +3933,9 @@ __indirect_glGetMapdv(GLenum target, GLenum query, GLdouble * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -3953,7 +3971,9 @@ __indirect_glGetMapfv(GLenum target, GLenum query, GLfloat * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -3989,7 +4009,9 @@ __indirect_glGetMapiv(GLenum target, GLenum query, GLint * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4025,7 +4047,9 @@ __indirect_glGetMaterialfv(GLenum face, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4063,7 +4087,9 @@ __indirect_glGetMaterialiv(GLenum face, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4101,7 +4127,9 @@ __indirect_glGetPixelMapfv(GLenum map, GLfloat * values)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 4;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4137,7 +4165,9 @@ __indirect_glGetPixelMapuiv(GLenum map, GLuint * values)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 4;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4174,7 +4204,9 @@ __indirect_glGetPixelMapusv(GLenum map, GLushort * values)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 4;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4210,9 +4242,10 @@ void
__indirect_glGetPolygonStipple(GLubyte *mask)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 4;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4247,7 +4280,9 @@ __indirect_glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4285,7 +4320,9 @@ __indirect_glGetTexEnviv(GLenum target, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4323,7 +4360,9 @@ __indirect_glGetTexGendv(GLenum coord, GLenum pname, GLdouble * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4361,7 +4400,9 @@ __indirect_glGetTexGenfv(GLenum coord, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4399,7 +4440,9 @@ __indirect_glGetTexGeniv(GLenum coord, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4439,7 +4482,9 @@ __indirect_glGetTexImage(GLenum target, GLint level, GLenum format,
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 20;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4483,7 +4528,9 @@ __indirect_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4522,7 +4569,9 @@ __indirect_glGetTexParameteriv(GLenum target, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4562,7 +4611,9 @@ __indirect_glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 12;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4603,7 +4654,9 @@ __indirect_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 12;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -4644,7 +4697,9 @@ __indirect_glIsList(GLuint list)
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
GLboolean retval = (GLboolean) 0;
#ifndef USE_XCB
const GLuint cmdlen = 4;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -5012,7 +5067,9 @@ __indirect_glAreTexturesResident(GLsizei n, const GLuint * textures,
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
GLboolean retval = (GLboolean) 0;
#ifndef USE_XCB
const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
#endif
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -5163,7 +5220,9 @@ __indirect_glDeleteTextures(GLsizei n, const GLuint * textures)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
#endif
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -5212,7 +5271,9 @@ __indirect_glGenTextures(GLsizei n, GLuint * textures)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 4;
#endif
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -5271,7 +5332,9 @@ __indirect_glIsTexture(GLuint texture)
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
GLboolean retval = (GLboolean) 0;
#ifndef USE_XCB
const GLuint cmdlen = 4;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -5565,7 +5628,9 @@ __indirect_glGetColorTable(GLenum target, GLenum format, GLenum type,
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 16;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -5641,7 +5706,9 @@ __indirect_glGetColorTableParameterfv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -5709,7 +5776,9 @@ __indirect_glGetColorTableParameteriv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -6029,7 +6098,9 @@ __indirect_glGetConvolutionFilter(GLenum target, GLenum format, GLenum type,
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 16;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -6103,7 +6174,9 @@ __indirect_glGetConvolutionParameterfv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -6171,7 +6244,9 @@ __indirect_glGetConvolutionParameteriv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -6240,7 +6315,9 @@ __indirect_glGetHistogram(GLenum target, GLboolean reset, GLenum format,
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 16;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -6319,7 +6396,9 @@ __indirect_glGetHistogramParameterfv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -6385,7 +6464,9 @@ __indirect_glGetHistogramParameteriv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -6452,7 +6533,9 @@ __indirect_glGetMinmax(GLenum target, GLboolean reset, GLenum format,
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 16;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -6526,7 +6609,9 @@ __indirect_glGetMinmaxParameterfv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -6589,7 +6674,9 @@ __indirect_glGetMinmaxParameteriv(GLenum target, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -8240,7 +8327,9 @@ __indirect_glDeleteQueriesARB(GLsizei n, const GLuint * ids)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
#endif
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -8278,7 +8367,9 @@ __indirect_glGenQueriesARB(GLsizei n, GLuint * ids)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 4;
#endif
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -8311,7 +8402,9 @@ __indirect_glGetQueryObjectivARB(GLuint id, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -8347,7 +8440,9 @@ __indirect_glGetQueryObjectuivARB(GLuint id, GLenum pname, GLuint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -8383,7 +8478,9 @@ __indirect_glGetQueryivARB(GLenum target, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
#ifndef USE_XCB
const GLuint cmdlen = 8;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@ -8423,7 +8520,9 @@ __indirect_glIsQueryARB(GLuint id)
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
GLboolean retval = (GLboolean) 0;
#ifndef USE_XCB
const GLuint cmdlen = 4;
#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);

View file

@ -65,8 +65,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef _XF86DRI_SERVER_
#include <GL/internal/dri_interface.h>
_XFUNCPROTOBEGIN
Bool XF86DRIQueryExtension( Display *dpy, int *event_base, int *error_base );
@ -94,14 +92,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,

View file

@ -153,8 +153,13 @@ depend: $(ALL_SOURCES)
subdirs:
@ (cd x86 ; $(MAKE))
@ (cd x86-64 ; $(MAKE))
@ if echo "$(ASM_FLAGS)" | grep -q USE_X86_ASM ; then \
(cd x86 ; $(MAKE)) ; \
fi
@ if echo "$(ASM_FLAGS)" | grep -q USE_X86_64_ASM ; then \
(cd x86 ; $(MAKE)) ; \
(cd x86-64 ; $(MAKE)) ; \
fi
install: default gl.pc

View file

@ -13,7 +13,6 @@ COMMON_SOURCES = \
COMMON_BM_SOURCES = \
../common/dri_bufmgr.c \
../common/dri_bufmgr_ttm.c \
../common/dri_bufmgr_fake.c

View file

@ -88,18 +88,6 @@ dri_bo_unmap(dri_bo *buf)
return buf->bufmgr->bo_unmap(buf);
}
int
dri_bo_validate(dri_bo *buf, unsigned int flags)
{
return buf->bufmgr->bo_validate(buf, flags);
}
dri_fence *
dri_fence_validated(dri_bufmgr *bufmgr, const char *name, GLboolean flushed)
{
return bufmgr->fence_validated(bufmgr, name, flushed);
}
void
dri_fence_wait(dri_fence *fence)
{
@ -150,3 +138,19 @@ dri_bufmgr_destroy(dri_bufmgr *bufmgr)
{
bufmgr->destroy(bufmgr);
}
void dri_emit_reloc(dri_bo *batch_buf, GLuint flags, GLuint delta, GLuint offset, dri_bo *relocatee)
{
batch_buf->bufmgr->emit_reloc(batch_buf, flags, delta, offset, relocatee);
}
void *dri_process_relocs(dri_bo *batch_buf, GLuint *count)
{
return batch_buf->bufmgr->process_relocs(batch_buf, count);
}
void dri_post_submit(dri_bo *batch_buf, dri_fence **last_fence)
{
batch_buf->bufmgr->post_submit(batch_buf, last_fence);
}

View file

@ -116,30 +116,6 @@ struct _dri_bufmgr {
/** Reduces the refcount on the userspace mapping of the buffer object. */
int (*bo_unmap)(dri_bo *buf);
/**
* Makes the buffer accessible to the graphics chip.
*
* The resulting offset of the buffer within the graphics aperture is then
* available at buf->offset until the buffer is fenced.
*
* Flags should consist of the memory types that the buffer may be validated
* into and the read/write/exe flags appropriate to the use of the buffer.
*/
int (*bo_validate)(dri_bo *buf, unsigned int flags);
/**
* Associates the current set of validated buffers with a fence.
*
* Once fenced, the buffer manager will allow the validated buffers to be
* evicted when the graphics device's execution has passed the fence
* command.
*
* The fence object will have flags for the sum of the read/write/exe flags
* of the validated buffers associated with it.
*/
dri_fence * (*fence_validated)(dri_bufmgr *bufmgr, const char *name,
GLboolean flushed);
/** Takes a reference on a fence object */
void (*fence_reference)(dri_fence *fence);
@ -158,6 +134,15 @@ struct _dri_bufmgr {
* Tears down the buffer manager instance.
*/
void (*destroy)(dri_bufmgr *bufmgr);
/**
* Add relocation
*/
void (*emit_reloc)(dri_bo *batch_buf, GLuint flags, GLuint delta, GLuint offset, dri_bo *relocatee);
void *(*process_relocs)(dri_bo *batch_buf, GLuint *count);
void (*post_submit)(dri_bo *batch_buf, dri_fence **fence);
};
dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size,
@ -169,9 +154,6 @@ void dri_bo_reference(dri_bo *bo);
void dri_bo_unreference(dri_bo *bo);
int dri_bo_map(dri_bo *buf, GLboolean write_enable);
int dri_bo_unmap(dri_bo *buf);
int dri_bo_validate(dri_bo *buf, unsigned int flags);
dri_fence *dri_fence_validated(dri_bufmgr *bufmgr, const char *name,
GLboolean flushed);
void dri_fence_wait(dri_fence *fence);
void dri_fence_reference(dri_fence *fence);
void dri_fence_unreference(dri_fence *fence);
@ -195,4 +177,8 @@ void dri_bufmgr_destroy(dri_bufmgr *bufmgr);
dri_bo *dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
unsigned int handle);
void dri_emit_reloc(dri_bo *batch_buf, GLuint flags, GLuint delta, GLuint offset, dri_bo *relocatee);
void *dri_process_relocs(dri_bo *batch_buf, uint32_t *count);
void dri_post_process_relocs(dri_bo *batch_buf);
void dri_post_submit(dri_bo *batch_buf, dri_fence **last_fence);
#endif

View file

@ -59,6 +59,16 @@
* processed through the command queue wouldn't need to care about
* fences.
*/
#define MAX_RELOCS 4096
struct fake_buffer_reloc
{
dri_bo *buf;
GLuint offset;
GLuint delta; /* not needed? */
GLuint validate_flags;
};
struct block {
struct block *next, *prev;
struct mem_block *mem; /* BM_MEM_AGP */
@ -107,6 +117,12 @@ typedef struct _bufmgr_fake {
int (*fence_wait)(void *private, unsigned int fence_cookie);
/** Driver-supplied argument to driver callbacks */
void *driver_priv;
/** fake relocation list */
struct fake_buffer_reloc reloc[MAX_RELOCS];
GLuint nr_relocs;
GLboolean performed_rendering;
} dri_bufmgr_fake;
typedef struct _dri_bo_fake {
@ -837,6 +853,120 @@ dri_fake_destroy(dri_bufmgr *bufmgr)
free(bufmgr);
}
static void
dri_fake_emit_reloc(dri_bo *batch_buf, GLuint flags, GLuint delta, GLuint offset,
dri_bo *relocatee)
{
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)batch_buf->bufmgr;
struct fake_buffer_reloc *r = &bufmgr_fake->reloc[bufmgr_fake->nr_relocs++];
assert(bufmgr_fake->nr_relocs <= MAX_RELOCS);
dri_bo_reference(relocatee);
r->buf = relocatee;
r->offset = offset;
r->delta = delta;
r->validate_flags = flags;
return;
}
static int
relocation_sort(const void *a_in, const void *b_in) {
const struct fake_buffer_reloc *a = a_in, *b = b_in;
return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1;
}
static void *
dri_fake_process_relocs(dri_bo *batch_buf, GLuint *count_p)
{
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)batch_buf->bufmgr;
GLuint i;
GLuint *ptr;
GLuint count = 0;
assert(batch_buf->virtual != NULL);
ptr = batch_buf->virtual;
bufmgr_fake->performed_rendering = GL_FALSE;
/* Sort our relocation list in terms of referenced buffer pointer.
* This lets us uniquely validate the buffers with the sum of all the flags,
* while avoiding O(n^2) on number of relocations.
*/
qsort(bufmgr_fake->reloc, bufmgr_fake->nr_relocs, sizeof(bufmgr_fake->reloc[0]),
relocation_sort);
/* Perform the necessary validations of buffers, and enter the relocations
* in the batchbuffer.
*/
for (i = 0; i < bufmgr_fake->nr_relocs; i++) {
struct fake_buffer_reloc *r = &bufmgr_fake->reloc[i];
if (r->validate_flags & DRM_BO_FLAG_WRITE)
bufmgr_fake->performed_rendering = GL_TRUE;
/* If this is the first time we've seen this buffer in the relocation
* list, figure out our flags and validate it.
*/
if (i == 0 || bufmgr_fake->reloc[i - 1].buf != r->buf) {
uint32_t validate_flags;
int j, ret;
/* Accumulate the flags we need for validating this buffer. */
validate_flags = r->validate_flags;
for (j = i + 1; j < bufmgr_fake->nr_relocs; j++) {
if (bufmgr_fake->reloc[j].buf != r->buf)
break;
validate_flags |= bufmgr_fake->reloc[j].validate_flags;
}
/* Validate. If we fail, fence to clear the unfenced list and bail
* out.
*/
ret = dri_fake_bo_validate(r->buf, validate_flags);
if (ret != 0) {
dri_fence *fo;
dri_bo_unmap(batch_buf);
fo = dri_fake_fence_validated(batch_buf->bufmgr,
"batchbuffer failure fence", GL_TRUE);
dri_fence_unreference(fo);
goto done;
}
count++;
}
ptr[r->offset / 4] = r->buf->offset + r->delta;
dri_bo_unreference(r->buf);
}
dri_bo_unmap(batch_buf);
dri_fake_bo_validate(batch_buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE);
*count_p = count;
bufmgr_fake->nr_relocs = 0;
done:
return NULL;
}
static void
dri_fake_post_submit(dri_bo *batch_buf, dri_fence **last_fence)
{
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)batch_buf->bufmgr;
dri_fence *fo;
fo = dri_fake_fence_validated(batch_buf->bufmgr, "Batch fence", GL_TRUE);
if (bufmgr_fake->performed_rendering) {
dri_fence_unreference(*last_fence);
*last_fence = fo;
} else {
dri_fence_unreference(fo);
}
}
dri_bufmgr *
dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,
unsigned long size,
@ -867,13 +997,13 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,
bufmgr_fake->bufmgr.bo_unreference = dri_fake_bo_unreference;
bufmgr_fake->bufmgr.bo_map = dri_fake_bo_map;
bufmgr_fake->bufmgr.bo_unmap = dri_fake_bo_unmap;
bufmgr_fake->bufmgr.bo_validate = dri_fake_bo_validate;
bufmgr_fake->bufmgr.fence_validated = dri_fake_fence_validated;
bufmgr_fake->bufmgr.fence_wait = dri_fake_fence_wait;
bufmgr_fake->bufmgr.fence_reference = dri_fake_fence_reference;
bufmgr_fake->bufmgr.fence_unreference = dri_fake_fence_unreference;
bufmgr_fake->bufmgr.destroy = dri_fake_destroy;
bufmgr_fake->bufmgr.emit_reloc = dri_fake_emit_reloc;
bufmgr_fake->bufmgr.process_relocs = dri_fake_process_relocs;
bufmgr_fake->bufmgr.post_submit = dri_fake_post_submit;
bufmgr_fake->fence_emit = fence_emit;
bufmgr_fake->fence_wait = fence_wait;
bufmgr_fake->driver_priv = driver_priv;

View file

@ -1,469 +0,0 @@
/**************************************************************************
*
* Copyright © 2007 Intel Corporation
* Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
*
**************************************************************************/
/*
* Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
* Keith Whitwell <keithw-at-tungstengraphics-dot-com>
* Eric Anholt <eric@anholt.net>
*/
#include <xf86drm.h>
#include <stdlib.h>
#include <unistd.h>
#include "glthread.h"
#include "errno.h"
#include "mtypes.h"
#include "dri_bufmgr.h"
#include "string.h"
#include "imports.h"
#define BUFMGR_DEBUG 0
typedef struct _dri_bufmgr_ttm {
dri_bufmgr bufmgr;
int fd;
_glthread_Mutex mutex;
unsigned int fence_type;
unsigned int fence_type_flush;
} dri_bufmgr_ttm;
typedef struct _dri_bo_ttm {
dri_bo bo;
int refcount; /* Protected by bufmgr->mutex */
drmBO drm_bo;
const char *name;
/**
* Note whether we are the owner of the buffer, to determine if we must
* drmBODestroy or drmBOUnreference to unreference the buffer.
*/
GLboolean owner;
} dri_bo_ttm;
typedef struct _dri_fence_ttm
{
dri_fence fence;
int refcount; /* Protected by bufmgr->mutex */
const char *name;
drmFence drm_fence;
} dri_fence_ttm;
#if 0
int
driFenceSignaled(DriFenceObject * fence, unsigned type)
{
int signaled;
int ret;
if (fence == NULL)
return GL_TRUE;
_glthread_LOCK_MUTEX(fence->mutex);
ret = drmFenceSignaled(bufmgr_ttm->fd, &fence->fence, type, &signaled);
_glthread_UNLOCK_MUTEX(fence->mutex);
BM_CKFATAL(ret);
return signaled;
}
#endif
static dri_bo *
dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name,
unsigned long size, unsigned int alignment,
unsigned int location_mask)
{
dri_bufmgr_ttm *ttm_bufmgr;
dri_bo_ttm *ttm_buf;
unsigned int pageSize = getpagesize();
int ret;
unsigned int flags, hint;
ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
ttm_buf = malloc(sizeof(*ttm_buf));
if (!ttm_buf)
return NULL;
/* The mask argument doesn't do anything for us that we want other than
* determine which pool (TTM or local) the buffer is allocated into, so just
* pass all of the allocation class flags.
*/
flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
DRM_BO_FLAG_EXE;
/* No hints we want to use. */
hint = 0;
ret = drmBOCreate(ttm_bufmgr->fd, 0, size, alignment / pageSize,
NULL, drm_bo_type_dc,
flags, hint, &ttm_buf->drm_bo);
if (ret != 0) {
free(ttm_buf);
return NULL;
}
ttm_buf->bo.size = ttm_buf->drm_bo.size;
ttm_buf->bo.offset = ttm_buf->drm_bo.offset;
ttm_buf->bo.virtual = NULL;
ttm_buf->bo.bufmgr = bufmgr;
ttm_buf->name = name;
ttm_buf->refcount = 1;
ttm_buf->owner = GL_TRUE;
#if BUFMGR_DEBUG
fprintf(stderr, "bo_create: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
#endif
return &ttm_buf->bo;
}
/* Our TTM backend doesn't allow creation of static buffers, as that requires
* privelege for the non-fake case, and the lock in the fake case where we were
* working around the X Server not creating buffers and passing handles to us.
*/
static dri_bo *
dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name,
unsigned long offset, unsigned long size, void *virtual,
unsigned int location_mask)
{
return NULL;
}
/** Returns a dri_bo wrapping the given buffer object handle.
*
* This can be used when one application needs to pass a buffer object
* to another.
*/
dri_bo *
dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
unsigned int handle)
{
dri_bufmgr_ttm *ttm_bufmgr;
dri_bo_ttm *ttm_buf;
int ret;
ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
ttm_buf = malloc(sizeof(*ttm_buf));
if (!ttm_buf)
return NULL;
ret = drmBOReference(ttm_bufmgr->fd, handle, &ttm_buf->drm_bo);
if (ret != 0) {
free(ttm_buf);
return NULL;
}
ttm_buf->bo.size = ttm_buf->drm_bo.size;
ttm_buf->bo.offset = ttm_buf->drm_bo.offset;
ttm_buf->bo.virtual = NULL;
ttm_buf->bo.bufmgr = bufmgr;
ttm_buf->name = name;
ttm_buf->refcount = 1;
ttm_buf->owner = GL_FALSE;
#if BUFMGR_DEBUG
fprintf(stderr, "bo_create_from_handle: %p (%s)\n", &ttm_buf->bo,
ttm_buf->name);
#endif
return &ttm_buf->bo;
}
static void
dri_ttm_bo_reference(dri_bo *buf)
{
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
ttm_buf->refcount++;
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
}
static void
dri_ttm_bo_unreference(dri_bo *buf)
{
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
if (!buf)
return;
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
if (--ttm_buf->refcount == 0) {
int ret;
/* XXX Having to use drmBODestroy as the opposite of drmBOCreate instead
* of simply unreferencing is madness, and leads to behaviors we may not
* want (making the buffer unsharable).
*/
if (ttm_buf->owner)
ret = drmBODestroy(bufmgr_ttm->fd, &ttm_buf->drm_bo);
else
ret = drmBOUnReference(bufmgr_ttm->fd, &ttm_buf->drm_bo);
if (ret != 0) {
fprintf(stderr, "drmBOUnReference failed (%s): %s\n", ttm_buf->name,
strerror(-ret));
}
#if BUFMGR_DEBUG
fprintf(stderr, "bo_unreference final: %p (%s)\n",
&ttm_buf->bo, ttm_buf->name);
#endif
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
free(buf);
return;
}
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
}
static int
dri_ttm_bo_map(dri_bo *buf, GLboolean write_enable)
{
dri_bufmgr_ttm *bufmgr_ttm;
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
unsigned int flags;
bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
flags = DRM_BO_FLAG_READ;
if (write_enable)
flags |= DRM_BO_FLAG_WRITE;
assert(buf->virtual == NULL);
#if BUFMGR_DEBUG
fprintf(stderr, "bo_map: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
#endif
return drmBOMap(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, 0, &buf->virtual);
}
static int
dri_ttm_bo_unmap(dri_bo *buf)
{
dri_bufmgr_ttm *bufmgr_ttm;
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
if (buf == NULL)
return 0;
bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
assert(buf->virtual != NULL);
buf->virtual = NULL;
#if BUFMGR_DEBUG
fprintf(stderr, "bo_unmap: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
#endif
return drmBOUnmap(bufmgr_ttm->fd, &ttm_buf->drm_bo);
}
static int
dri_ttm_validate(dri_bo *buf, unsigned int flags)
{
dri_bufmgr_ttm *bufmgr_ttm;
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
unsigned int mask;
int err;
/* XXX: Sanity-check whether we've already validated this one under
* different flags. See drmAddValidateItem().
*/
bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
/* Calculate the appropriate mask to pass to the DRM. There appears to be
* be a direct relationship to flags, so it's unnecessary to have it passed
* in as an argument.
*/
mask = DRM_BO_MASK_MEM;
mask |= flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE);
err = drmBOValidate(bufmgr_ttm->fd, &ttm_buf->drm_bo, 0, flags, mask, 0);
if (err == 0) {
/* XXX: add to fence list for sanity checking */
} else {
fprintf(stderr, "failed to validate buffer (%s): %s\n",
ttm_buf->name, strerror(-err));
}
buf->offset = ttm_buf->drm_bo.offset;
#if BUFMGR_DEBUG
fprintf(stderr, "bo_validate: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
#endif
return err;
}
static dri_fence *
dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name,
GLboolean flushed)
{
dri_fence_ttm *fence_ttm = malloc(sizeof(*fence_ttm));
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr;
int ret;
unsigned int type;
if (!fence_ttm)
return NULL;
if (flushed)
type = bufmgr_ttm->fence_type_flush;
else
type = bufmgr_ttm->fence_type;
fence_ttm->refcount = 1;
fence_ttm->name = name;
fence_ttm->fence.bufmgr = bufmgr;
ret = drmFenceBuffers(bufmgr_ttm->fd, type, 0, &fence_ttm->drm_fence);
if (ret) {
fprintf(stderr, "failed to fence (%s): %s\n", name, strerror(-ret));
free(fence_ttm);
return NULL;
}
#if BUFMGR_DEBUG
fprintf(stderr, "fence_validated: %p (%s)\n", &fence_ttm->fence,
fence_ttm->name);
#endif
return &fence_ttm->fence;
}
static void
dri_ttm_fence_reference(dri_fence *fence)
{
dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
++fence_ttm->refcount;
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
}
static void
dri_ttm_fence_unreference(dri_fence *fence)
{
dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
if (!fence)
return;
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
if (--fence_ttm->refcount == 0) {
int ret;
/* XXX Having to use drmFenceDestroy as the opposite of drmFenceBuffers
* instead of simply unreferencing is madness, and leads to behaviors we
* may not want (making the fence unsharable). This behavior by the DRM
* ioctls should be fixed, and drmFenceDestroy eliminated.
*/
ret = drmFenceDestroy(bufmgr_ttm->fd, &fence_ttm->drm_fence);
if (ret != 0) {
fprintf(stderr, "drmFenceDestroy failed (%s): %s\n",
fence_ttm->name, strerror(-ret));
}
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
free(fence);
return;
}
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
}
static void
dri_ttm_fence_wait(dri_fence *fence)
{
dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
int ret;
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
ret = drmFenceWait(bufmgr_ttm->fd, 0, &fence_ttm->drm_fence, 0);
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
if (ret != 0) {
_mesa_printf("%s:%d: Error %d waiting for fence %s.\n",
__FILE__, __LINE__, ret, fence_ttm->name);
abort();
}
#if BUFMGR_DEBUG
fprintf(stderr, "fence_wait: %p (%s)\n", &fence_ttm->fence,
fence_ttm->name);
#endif
}
static void
dri_bufmgr_ttm_destroy(dri_bufmgr *bufmgr)
{
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr;
_glthread_DESTROY_MUTEX(bufmgr_ttm->mutex);
free(bufmgr);
}
/**
* Initializes the TTM buffer manager, which uses the kernel to allocate, map,
* and manage map buffer objections.
*
* \param fd File descriptor of the opened DRM device.
* \param fence_type Driver-specific fence type used for fences with no flush.
* \param fence_type_flush Driver-specific fence type used for fences with a
* flush.
*/
dri_bufmgr *
dri_bufmgr_ttm_init(int fd, unsigned int fence_type,
unsigned int fence_type_flush)
{
dri_bufmgr_ttm *bufmgr_ttm;
bufmgr_ttm = malloc(sizeof(*bufmgr_ttm));
bufmgr_ttm->fd = fd;
bufmgr_ttm->fence_type = fence_type;
bufmgr_ttm->fence_type_flush = fence_type_flush;
_glthread_INIT_MUTEX(bufmgr_ttm->mutex);
bufmgr_ttm->bufmgr.bo_alloc = dri_ttm_alloc;
bufmgr_ttm->bufmgr.bo_alloc_static = dri_ttm_alloc_static;
bufmgr_ttm->bufmgr.bo_reference = dri_ttm_bo_reference;
bufmgr_ttm->bufmgr.bo_unreference = dri_ttm_bo_unreference;
bufmgr_ttm->bufmgr.bo_map = dri_ttm_bo_map;
bufmgr_ttm->bufmgr.bo_unmap = dri_ttm_bo_unmap;
bufmgr_ttm->bufmgr.bo_validate = dri_ttm_validate;
bufmgr_ttm->bufmgr.fence_validated = dri_ttm_fence_validated;
bufmgr_ttm->bufmgr.fence_reference = dri_ttm_fence_reference;
bufmgr_ttm->bufmgr.fence_unreference = dri_ttm_fence_unreference;
bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait;
bufmgr_ttm->bufmgr.destroy = dri_bufmgr_ttm_destroy;
return &bufmgr_ttm->bufmgr;
}

View file

@ -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!
@ -46,23 +46,27 @@ const __DRIinterfaceMethods * dri_interface = NULL;
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);
/**
@ -88,63 +92,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,33 @@ 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);
}
static int driDrawableGetMSC( __DRIscreen *screen, void *drawablePrivate,
int64_t *msc )
{
__DRIscreenPrivate *sPriv = screen->private;
return sPriv->DriverAPI.GetDrawableMSC( sPriv, drawablePrivate, msc );
}
/**
* Called directly from a number of higher-level GLX functions.
*/
static int driGetMSC( void *screenPrivate, int64_t *msc )
static int driGetMSC( __DRIscreen *screen, void *drawablePrivate, 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 +400,56 @@ 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 )
{
__DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
{ __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
driGetMSC,
driWaitForMSC,
driDrawableGetMSC,
};
return dPriv->driScreenPriv->DriverAPI.SwapBuffersMSC( dPriv, target_msc,
divisor,
remainder );
}
static void driCopySubBuffer( __DRInativeDisplay *dpy, void *drawablePrivate,
static void driCopySubBuffer(__DRIdrawable *drawable,
int x, int y, int w, int h)
{
__DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
__DRIdrawablePrivate *dPriv = drawable->private;
dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
(void) dpy;
}
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 unsigned int driGetSwapInterval(__DRIdrawable *drawable)
{
__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 +461,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 +480,15 @@ static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
pdp->numBackClipRects = 0;
pdp->pClipRects = NULL;
pdp->pBackClipRects = NULL;
pdp->display = dpy;
pdp->screen = modes->screen;
pdp->vblSeq = 0;
pdp->vblFlags = 0;
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;
}
@ -656,63 +496,28 @@ static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
pdraw->private = pdp;
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;
pdp->msc_base = 0;
/* 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 +541,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 +548,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 +566,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 +581,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 +606,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 +618,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 +651,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 +666,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 +674,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 +700,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) {
psp = _mesa_malloc(sizeof(*psp));
if (!psp)
return NULL;
}
/* Create the hash table */
psp->drawHash = drmHashCreate();
if ( psp->drawHash == NULL ) {
_mesa_free( 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 +734,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 +749,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 +761,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 +802,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 +831,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 +875,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

View file

@ -66,6 +66,22 @@ typedef struct __DRIswapInfoRec __DRIswapInfo;
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
*/
@ -109,11 +125,6 @@ do { \
* this structure.
*/
struct __DriverAPIRec {
/**
* Driver initialization callback
*/
GLboolean (*InitDriver)(__DRIscreenPrivate *driScrnPriv);
/**
* Screen destruction callback
*/
@ -195,6 +206,14 @@ struct __DriverAPIRec {
*/
void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
unsigned long long offset, GLint depth, GLuint pitch);
/**
* New version of GetMSC so we can pass drawable data to the low level
* DRM driver (e.g. pipe info).
*/
int (*GetDrawableMSC) ( __DRIscreenPrivate * priv,
__DRIdrawablePrivate *drawablePrivate,
int64_t *count);
};
@ -248,7 +267,6 @@ struct __DRIdrawablePrivateRec {
/**
* X's drawable ID associated with this private drawable.
*/
__DRIid draw;
__DRIdrawable *pdraw;
/**
@ -307,6 +325,32 @@ struct __DRIdrawablePrivateRec {
drm_clip_rect_t *pBackClipRects;
/*@}*/
/**
* \name Vertical blank tracking information
* Used for waiting on vertical blank events.
*/
/*@{*/
unsigned int vblSeq;
unsigned int vblFlags;
/*@}*/
/**
* \name Monotonic MSC tracking
*
* Low level driver is responsible for updating msc_base and
* vblSeq values so that higher level code can calculate
* a new msc value or msc target for a WaitMSC call. The new value
* will be:
* msc = msc_base + get_vblank_count() - vblank_base;
*
* And for waiting on a value, core code will use:
* actual_target = target_msc - msc_base + vblank_base;
*/
/*@{*/
int64_t vblank_base;
int64_t msc_base;
/*@}*/
/**
* Pointer to context to which this drawable is currently bound.
*/
@ -317,32 +361,22 @@ struct __DRIdrawablePrivateRec {
*/
__DRIscreenPrivate *driScreenPriv;
/**
* \name Display and screen information.
*
* Basically just need these for when the locking code needs to call
* \c __driUtilUpdateDrawableInfo.
*/
/*@{*/
__DRInativeDisplay *display;
int screen;
/*@}*/
/**
* Called via glXSwapBuffers().
*/
void (*swapBuffers)( __DRIdrawablePrivate *dPriv );
/**
* Controls swap interval as used by GLX_SGI_swap_control and
* GLX_MESA_swap_control.
*/
unsigned int swap_interval;
};
/**
* Per-context private driver information.
*/
struct __DRIcontextPrivateRec {
/**
* Kernel context handle used to access the device lock.
*/
__DRIid contextID;
/**
* Kernel context handle used to access the device lock.
*/
@ -354,9 +388,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.
@ -378,11 +412,6 @@ struct __DRIcontextPrivateRec {
* Per-screen private driver information.
*/
struct __DRIscreenPrivateRec {
/**
* Display for this screen
*/
__DRInativeDisplay *display;
/**
* Current screen's number
*/
@ -394,37 +423,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.
@ -489,11 +500,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).
*
@ -501,22 +507,15 @@ 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.
*/
__GLcontextModes *modes;
/**
* Pointer back to the \c __DRIscreen that contains this structure.
*/
__DRIscreen *psc;
/**
* Extensions provided by this driver.
*/
const __DRIextension **extensions;
};
@ -540,8 +539,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,

View file

@ -1105,10 +1105,11 @@ static const char IsRenderbufferEXT_names[] =
"";
#endif
#if defined(need_GL_VERSION_2_0)
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ATI_separate_stencil)
static const char StencilOpSeparate_names[] =
"iiii\0" /* Parameter signature */
"glStencilOpSeparate\0"
"glStencilOpSeparateATI\0"
"";
#endif
@ -4179,6 +4180,13 @@ static const char ActiveStencilFaceEXT_names[] =
"";
#endif
#if defined(need_GL_ATI_separate_stencil)
static const char StencilFuncSeparateATI_names[] =
"iiii\0" /* Parameter signature */
"glStencilFuncSeparateATI\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
static const char GetShaderSourceARB_names[] =
"iipp\0" /* Parameter signature */
@ -5182,6 +5190,14 @@ static const struct dri_extension_function GL_ATI_fragment_shader_functions[] =
};
#endif
#if defined(need_GL_ATI_separate_stencil)
static const struct dri_extension_function GL_ATI_separate_stencil_functions[] = {
{ StencilOpSeparate_names, StencilOpSeparate_remap_index, -1 },
{ StencilFuncSeparateATI_names, StencilFuncSeparateATI_remap_index, -1 },
{ NULL, 0, 0 }
};
#endif
#if defined(need_GL_EXT_blend_color)
static const struct dri_extension_function GL_EXT_blend_color_functions[] = {
{ BlendColor_names, -1, 336 },

View file

@ -35,8 +35,62 @@
#include "vblank.h"
#include "xmlpool.h"
static unsigned int msc_to_vblank(__DRIdrawablePrivate * dPriv, int64_t msc)
{
return (unsigned int)(msc - dPriv->msc_base + dPriv->vblank_base);
}
static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank)
{
return (int64_t)(vblank - dPriv->vblank_base + dPriv->msc_base);
}
/****************************************************************************/
/**
* Get the current MSC refresh counter.
*
* Stores the 64-bit count of vertical refreshes since some (arbitrary)
* point in time in \c count. Unless the value wraps around, which it
* may, it will never decrease for a given drawable.
*
* \warning This function is called from \c glXGetVideoSyncSGI, which expects
* a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which
* expects a \c count of type \c int64_t (signed 64-bit). The kernel ioctl
* currently always returns a \c sequence of type \c unsigned.
*
* \param priv Pointer to the DRI screen private struct.
* \param dPriv Pointer to the DRI drawable private struct
* \param count Storage to hold MSC counter.
* \return Zero is returned on success. A negative errno value
* is returned on failure.
*/
int driDrawableGetMSC32( __DRIscreenPrivate * priv,
__DRIdrawablePrivate * dPriv,
int64_t * count)
{
drmVBlank vbl;
int ret;
/* Don't wait for anything. Just get the current refresh count. */
vbl.request.type = DRM_VBLANK_RELATIVE;
vbl.request.sequence = 0;
if ( dPriv && dPriv->vblFlags & VBLANK_FLAG_SECONDARY )
vbl.request.type |= DRM_VBLANK_SECONDARY;
ret = drmWaitVBlank( priv->fd, &vbl );
if (dPriv) {
*count = vblank_to_msc(dPriv, vbl.reply.sequence);
} else {
/* Old driver (no knowledge of drawable MSC callback) */
*count = vbl.reply.sequence;
}
return ret;
}
/**
* Get the current MSC refresh counter.
*
@ -49,6 +103,10 @@
* expects a \c count of type \c int64_t (signed 64-bit). The kernel ioctl
* currently always returns a \c sequence of type \c unsigned.
*
* Since this function doesn't take a drawable, it may end up getting the MSC
* value from a pipe not associated with the caller's context, resuling in
* undesired behavior.
*
* \param priv Pointer to the DRI screen private struct.
* \param count Storage to hold MSC counter.
* \return Zero is returned on success. A negative errno value
@ -56,21 +114,9 @@
*/
int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
{
drmVBlank vbl;
int ret;
/* Don't wait for anything. Just get the current refresh count. */
vbl.request.type = DRM_VBLANK_RELATIVE;
vbl.request.sequence = 0;
ret = drmWaitVBlank( priv->fd, &vbl );
*count = (int64_t)vbl.reply.sequence;
return ret;
return driDrawableGetMSC32(priv, NULL, count);
}
/****************************************************************************/
/**
* Wait for a specified refresh count. This implements most of the
@ -123,7 +169,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
*/
vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE :
DRM_VBLANK_ABSOLUTE;
vbl.request.sequence = next;
vbl.request.sequence = next ? msc_to_vblank(priv, next) : 0;
if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
vbl.request.type |= DRM_VBLANK_SECONDARY;
if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) {
/* FIXME: This doesn't seem like the right thing to return here.
@ -131,8 +179,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
return GLX_BAD_CONTEXT;
}
*msc = vblank_to_msc(priv, vbl.reply.sequence);
dont_wait = 0;
if (target_msc != 0 && vbl.reply.sequence == target)
if (target_msc != 0 && *msc == target)
break;
/* Assuming the wait-done test fails, the next refresh to wait for
@ -142,9 +192,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
* If this refresh has already happened, we add divisor to obtain
* the next refresh after the current one that will satisfy it.
*/
r = (vbl.reply.sequence % (unsigned int)divisor);
next = (vbl.reply.sequence - r + (unsigned int)remainder);
if (next <= vbl.reply.sequence) next += (unsigned int)divisor;
r = (*msc % (unsigned int)divisor);
next = (*msc - r + (unsigned int)remainder);
if (next <= *msc) next += (unsigned int)divisor;
} while ( r != (unsigned int)remainder );
}
@ -154,7 +204,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
*/
vbl.request.type = DRM_VBLANK_ABSOLUTE;
vbl.request.sequence = target_msc;
vbl.request.sequence = target_msc ? msc_to_vblank(priv, target_msc) : 0;
if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
vbl.request.type |= DRM_VBLANK_SECONDARY;
if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) {
/* FIXME: This doesn't seem like the right thing to return here.
@ -163,8 +216,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
}
}
*msc = (target_msc & 0xffffffff00000000LL);
*msc |= vbl.reply.sequence;
*msc = vblank_to_msc(priv, vbl.reply.sequence);
if ( *msc < target_msc ) {
*msc += 0x0000000100000000LL;
}
@ -248,40 +301,13 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd )
/****************************************************************************/
/**
* Sets the default swap interval when the drawable is first bound to a
* direct rendering context.
* Returns the default swap interval of the given drawable.
*/
void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags,
GLuint *vbl_seq )
static unsigned
driGetDefaultVBlankInterval( const __DRIdrawablePrivate *priv )
{
if ( priv->pdraw->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;
}
}
/****************************************************************************/
/**
* Returns the current swap interval of the given drawable.
*/
unsigned
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 );
return priv->pdraw->swap_interval;
}
else if ( (flags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) {
if ( (priv->vblFlags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) {
return 1;
}
else {
@ -290,24 +316,68 @@ driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags )
}
/****************************************************************************/
/**
* Sets the default swap interval when the drawable is first bound to a
* direct rendering context.
*/
void driDrawableInitVBlank( __DRIdrawablePrivate *priv )
{
if ( priv->swap_interval == (unsigned)-1 &&
!( priv->vblFlags & VBLANK_FLAG_NO_IRQ ) ) {
/* Get current vertical blank sequence */
drmVBlank vbl;
vbl.request.type = DRM_VBLANK_RELATIVE;
if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
vbl.request.type |= DRM_VBLANK_SECONDARY;
vbl.request.sequence = 0;
do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd );
priv->vblank_base = priv->vblSeq;
priv->swap_interval = driGetDefaultVBlankInterval( priv );
}
}
/****************************************************************************/
/**
* Returns the current swap interval of the given drawable.
*/
unsigned
driGetVBlankInterval( const __DRIdrawablePrivate *priv )
{
if ( (priv->vblFlags & VBLANK_FLAG_INTERVAL) != 0 ) {
/* this must have been initialized when the drawable was first bound
* to a direct rendering context. */
assert ( priv->swap_interval != (unsigned)-1 );
return priv->swap_interval;
}
else
return driGetDefaultVBlankInterval( priv );
}
/****************************************************************************/
/**
* Returns the current vertical blank sequence number of the given drawable.
*/
void
driGetCurrentVBlank( const __DRIdrawablePrivate *priv, GLuint flags,
GLuint *vbl_seq )
driGetCurrentVBlank( __DRIdrawablePrivate *priv )
{
drmVBlank vbl;
vbl.request.type = DRM_VBLANK_RELATIVE;
if ( flags & VBLANK_FLAG_SECONDARY ) {
if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) {
vbl.request.type |= DRM_VBLANK_SECONDARY;
}
vbl.request.sequence = 0;
(void) do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
(void) do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd );
}
@ -315,19 +385,15 @@ driGetCurrentVBlank( const __DRIdrawablePrivate *priv, GLuint flags,
/**
* Waits for the vertical blank for use with glXSwapBuffers.
*
* \param vbl_seq Vertical blank sequence number (MSC) after the last buffer
* swap. Updated after this wait.
* \param flags \c VBLANK_FLAG bits that control how long to wait.
* \param missed_deadline Set to \c GL_TRUE if the MSC after waiting is later
* than the "target" based on \c flags. The idea is that if
* \c missed_deadline is set, then the application is not
* achieving its desired framerate.
* than the "target" based on \c priv->vblFlags. The idea is
* that if \c missed_deadline is set, then the application is
* not achieving its desired framerate.
* \return Zero on success, -1 on error.
*/
int
driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq,
GLuint flags, GLboolean * missed_deadline )
driWaitForVBlank( __DRIdrawablePrivate *priv, GLboolean * missed_deadline )
{
drmVBlank vbl;
unsigned original_seq;
@ -336,10 +402,10 @@ driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq,
unsigned diff;
*missed_deadline = GL_FALSE;
if ( (flags & (VBLANK_FLAG_INTERVAL |
VBLANK_FLAG_THROTTLE |
VBLANK_FLAG_SYNC)) == 0 ||
(flags & VBLANK_FLAG_NO_IRQ) != 0 ) {
if ( (priv->vblFlags & (VBLANK_FLAG_INTERVAL |
VBLANK_FLAG_THROTTLE |
VBLANK_FLAG_SYNC)) == 0 ||
(priv->vblFlags & VBLANK_FLAG_NO_IRQ) != 0 ) {
return 0;
}
@ -350,44 +416,45 @@ driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq,
*
* VBLANK_FLAG_INTERVAL and VBLANK_FLAG_THROTTLE mean to wait for at
* least one vertical blank since the last wait. Since do_wait modifies
* vbl_seq, we have to save the original value of vbl_seq for the
* priv->vblSeq, we have to save the original value of priv->vblSeq for the
* VBLANK_FLAG_INTERVAL / VBLANK_FLAG_THROTTLE calculation later.
*/
original_seq = *vbl_seq;
interval = driGetVBlankInterval(priv, flags);
original_seq = priv->vblSeq;
interval = driGetVBlankInterval(priv);
deadline = original_seq + interval;
vbl.request.type = DRM_VBLANK_RELATIVE;
if ( flags & VBLANK_FLAG_SECONDARY ) {
if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) {
vbl.request.type |= DRM_VBLANK_SECONDARY;
}
vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0;
vbl.request.sequence = ((priv->vblFlags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0;
if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) {
return -1;
}
diff = *vbl_seq - deadline;
diff = priv->vblSeq - deadline;
/* No need to wait again if we've already reached the target */
if (diff <= (1 << 23)) {
*missed_deadline = (flags & VBLANK_FLAG_SYNC) ? (diff > 0) : GL_TRUE;
*missed_deadline = (priv->vblFlags & VBLANK_FLAG_SYNC) ? (diff > 0) :
GL_TRUE;
return 0;
}
/* Wait until the target vertical blank. */
vbl.request.type = DRM_VBLANK_ABSOLUTE;
if ( flags & VBLANK_FLAG_SECONDARY ) {
if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) {
vbl.request.type |= DRM_VBLANK_SECONDARY;
}
vbl.request.sequence = deadline;
if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) {
return -1;
}
diff = *vbl_seq - deadline;
diff = priv->vblSeq - deadline;
*missed_deadline = diff > 0 && diff <= (1 << 23);
return 0;

View file

@ -46,17 +46,17 @@
*/
extern int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count );
extern int driDrawableGetMSC32( __DRIscreenPrivate * priv,
__DRIdrawablePrivate * drawablePrivate,
int64_t * count);
extern int driWaitForMSC32( __DRIdrawablePrivate *priv,
int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc );
extern GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache );
extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv, GLuint flags,
GLuint *vbl_seq );
extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv,
GLuint flags );
extern void driGetCurrentVBlank( const __DRIdrawablePrivate *priv,
GLuint flags, GLuint *vbl_seq );
extern int driWaitForVBlank( const __DRIdrawablePrivate *priv,
GLuint * vbl_seq, GLuint flags, GLboolean * missed_deadline );
extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv );
extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv );
extern void driGetCurrentVBlank( __DRIdrawablePrivate *priv );
extern int driWaitForVBlank( __DRIdrawablePrivate *priv,
GLboolean * missed_deadline );
#undef usleep
#include <unistd.h> /* for usleep() */

View file

@ -605,7 +605,6 @@ void ffbXMesaUpdateState(ffbContextPtr fmesa)
}
static const struct __DriverAPIRec ffbAPI = {
.InitDriver = ffbInitDriver,
.DestroyScreen = ffbDestroyScreen,
.CreateContext = ffbCreateContext,
.DestroyContext = ffbDestroyContext,
@ -616,6 +615,7 @@ static const struct __DriverAPIRec ffbAPI = {
.UnbindContext = ffbUnbindContext,
.GetSwapInfo = NULL,
.GetMSC = NULL,
.GetDrawableMSC = NULL,
.WaitForMSC = NULL,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
@ -704,49 +704,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;
return (void *) psp;
if (!ffbInitDriver(psp))
return NULL;
return ffbFillInModes( 32, 16, 0, GL_TRUE );
}

View file

@ -403,7 +403,6 @@ i810DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
static const struct __DriverAPIRec i810API = {
.InitDriver = i810InitDriver,
.DestroyScreen = i810DestroyScreen,
.CreateContext = i810CreateContext,
.DestroyContext = i810DestroyContext,
@ -414,6 +413,7 @@ static const struct __DriverAPIRec i810API = {
.UnbindContext = i810UnbindContext,
.GetSwapInfo = NULL,
.GetMSC = NULL,
.GetDrawableMSC = NULL,
.WaitForMSC = NULL,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
@ -421,52 +421,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 );
return (void *) psp;
if (!i810InitDriver(psp))
return NULL;
return i810FillInModes(16, 16, 0, 1);
}

View file

@ -52,7 +52,8 @@ DRIVER_SOURCES = \
intel_state.c \
intel_tris.c \
intel_fbo.c \
intel_depthstencil.c
intel_depthstencil.c \
intel_bufmgr_ttm.c
C_SOURCES = \
$(COMMON_SOURCES) \
@ -61,7 +62,8 @@ C_SOURCES = \
ASM_SOURCES =
DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \
DRIVER_DEFINES = -I../intel -I../intel/server \
$(shell pkg-config libdrm --atleast-version=2.3.1 \
&& echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
include ../Makefile.template

View file

@ -376,20 +376,25 @@ static void BR13( struct debug_stream *stream,
}
static void BR22( struct debug_stream *stream,
GLuint val )
static void BR2223( struct debug_stream *stream,
GLuint val22, GLuint val23 )
{
PRINTF("\t0x%08x\n", val);
BITS(val, 31, 16, "dest y1");
BITS(val, 15, 0, "dest x1");
}
union { GLuint val; short field[2]; } BR22, BR23;
static void BR23( struct debug_stream *stream,
GLuint val )
{
PRINTF("\t0x%08x\n", val);
BITS(val, 31, 16, "dest y2");
BITS(val, 15, 0, "dest x2");
BR22.val = val22;
BR23.val = val23;
PRINTF("\t0x%08x\n", val22);
BITS(val22, 31, 16, "dest y1");
BITS(val22, 15, 0, "dest x1");
PRINTF("\t0x%08x\n", val23);
BITS(val23, 31, 16, "dest y2");
BITS(val23, 15, 0, "dest x2");
/* The blit engine may produce unexpected results when these aren't met */
assert(BR22.field[0] < BR23.field[0]);
assert(BR22.field[1] < BR23.field[1]);
}
static void BR09( struct debug_stream *stream,
@ -436,8 +441,8 @@ static GLboolean debug_copy_blit( struct debug_stream *stream,
PRINTF("\t0x%08x\n", ptr[j++]);
BR13(stream, ptr[j++]);
BR22(stream, ptr[j++]);
BR23(stream, ptr[j++]);
BR2223(stream, ptr[j], ptr[j+1]);
j += 2;
BR09(stream, ptr[j++]);
BR26(stream, ptr[j++]);
BR11(stream, ptr[j++]);
@ -459,8 +464,8 @@ static GLboolean debug_color_blit( struct debug_stream *stream,
PRINTF("\t0x%08x\n", ptr[j++]);
BR13(stream, ptr[j++]);
BR22(stream, ptr[j++]);
BR23(stream, ptr[j++]);
BR2223(stream, ptr[j], ptr[j+1]);
j += 2;
BR09(stream, ptr[j++]);
BR16(stream, ptr[j++]);

View file

@ -34,8 +34,6 @@
#define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
#define CMD_3D (0x3<<29)
#define PRIM3D_INLINE (CMD_3D | (0x1f<<24))
#define PRIM3D_TRILIST (0x0<<18)
#define PRIM3D_TRISTRIP (0x1<<18)

View file

@ -28,7 +28,7 @@
#include "intel_batchbuffer.h"
#include "intel_ioctl.h"
#include "intel_decode.h"
#include "i915_debug.h"
#include "intel_reg.h"
/* Relocations in kernel space:
* - pass dma buffer seperately
@ -116,85 +116,23 @@ intel_batchbuffer_free(struct intel_batchbuffer *batch)
free(batch);
}
static int
relocation_sort(const void *a_in, const void *b_in) {
const struct buffer_reloc *a = a_in, *b = b_in;
return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1;
}
/* TODO: Push this whole function into bufmgr.
*/
static void
do_flush_locked(struct intel_batchbuffer *batch,
GLuint used,
GLboolean ignore_cliprects, GLboolean allow_unlock)
GLuint used,
GLboolean ignore_cliprects, GLboolean allow_unlock)
{
GLuint *ptr;
GLuint i;
struct intel_context *intel = batch->intel;
dri_fence *fo;
GLboolean performed_rendering = GL_FALSE;
void *start;
GLuint count;
assert(batch->buf->virtual != NULL);
ptr = batch->buf->virtual;
start = dri_process_relocs(batch->buf, &count);
/* Sort our relocation list in terms of referenced buffer pointer.
* This lets us uniquely validate the buffers with the sum of all the flags,
* while avoiding O(n^2) on number of relocations.
*/
qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]),
relocation_sort);
/* Perform the necessary validations of buffers, and enter the relocations
* in the batchbuffer.
*/
for (i = 0; i < batch->nr_relocs; i++) {
struct buffer_reloc *r = &batch->reloc[i];
if (r->validate_flags & DRM_BO_FLAG_WRITE)
performed_rendering = GL_TRUE;
/* If this is the first time we've seen this buffer in the relocation
* list, figure out our flags and validate it.
*/
if (i == 0 || batch->reloc[i - 1].buf != r->buf) {
uint32_t validate_flags;
int j, ret;
/* Accumulate the flags we need for validating this buffer. */
validate_flags = r->validate_flags;
for (j = i + 1; j < batch->nr_relocs; j++) {
if (batch->reloc[j].buf != r->buf)
break;
validate_flags |= batch->reloc[j].validate_flags;
}
/* Validate. If we fail, fence to clear the unfenced list and bail
* out.
*/
ret = dri_bo_validate(r->buf, validate_flags);
if (ret != 0) {
dri_bo_unmap(batch->buf);
fo = dri_fence_validated(intel->intelScreen->bufmgr,
"batchbuffer failure fence", GL_TRUE);
dri_fence_unreference(fo);
goto done;
}
}
ptr[r->offset / 4] = r->buf->offset + r->delta;
dri_bo_unreference(r->buf);
}
dri_bo_unmap(batch->buf);
batch->map = NULL;
batch->ptr = NULL;
dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE);
batch->list_count = 0;
batch->nr_relocs = 0;
batch->flags = 0;
/* Throw away non-effective packets. Won't work once we have
@ -203,26 +141,18 @@ do_flush_locked(struct intel_batchbuffer *batch,
*/
if (!(intel->numClipRects == 0 && !ignore_cliprects)) {
intel_batch_ioctl(batch->intel,
batch->buf->offset,
used, ignore_cliprects, allow_unlock);
}
/* Associate a fence with the validated buffers, and note that we included
* a flush at the end.
*/
fo = dri_fence_validated(intel->intelScreen->bufmgr,
"Batch fence", GL_TRUE);
if (performed_rendering) {
dri_fence_unreference(batch->last_fence);
batch->last_fence = fo;
} else {
/* If we didn't validate any buffers for writing by the card, we don't
* need to track the fence for glFinish().
*/
dri_fence_unreference(fo);
if (intel->intelScreen->ttm == GL_TRUE) {
intel_exec_ioctl(batch->intel,
used, ignore_cliprects, allow_unlock,
start, count, &batch->last_fence);
} else {
intel_batch_ioctl(batch->intel,
batch->buf->offset,
used, ignore_cliprects, allow_unlock);
}
}
dri_post_submit(batch->buf, &batch->last_fence);
if (intel->numClipRects == 0 && !ignore_cliprects) {
if (allow_unlock) {
@ -237,16 +167,14 @@ do_flush_locked(struct intel_batchbuffer *batch,
intel->vtbl.lost_hardware(intel);
}
done:
if (INTEL_DEBUG & DEBUG_BATCH) {
dri_bo_map(batch->buf, GL_FALSE);
intel_decode(ptr, used / 4, batch->buf->offset,
intel->intelScreen->deviceID);
dri_bo_unmap(batch->buf);
// dri_bo_map(batch->buf, GL_FALSE);
// intel_decode(ptr, used / 4, batch->buf->offset,
// intel->intelScreen->deviceID);
// dri_bo_unmap(batch->buf);
}
}
void
intel_batchbuffer_flush(struct intel_batchbuffer *batch)
{
@ -280,7 +208,7 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch)
do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS),
GL_FALSE);
if (!was_locked)
UNLOCK_HARDWARE(intel);
@ -305,22 +233,12 @@ intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
dri_bo *buffer,
GLuint flags, GLuint delta)
{
struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++];
assert(batch->nr_relocs <= MAX_RELOCS);
dri_bo_reference(buffer);
r->buf = buffer;
r->offset = batch->ptr - batch->map;
r->delta = delta;
r->validate_flags = flags;
dri_emit_reloc(batch->buf, flags, delta, batch->ptr - batch->map, buffer);
batch->ptr += 4;
return GL_TRUE;
}
void
intel_batchbuffer_data(struct intel_batchbuffer *batch,
const void *data, GLuint bytes, GLuint flags)

View file

@ -2,6 +2,7 @@
#define INTEL_BATCHBUFFER_H
#include "mtypes.h"
#include "dri_bufmgr.h"
struct intel_context;
@ -9,19 +10,9 @@ struct intel_context;
#define BATCH_SZ 16384
#define BATCH_RESERVED 16
#define MAX_RELOCS 4096
#define INTEL_BATCH_NO_CLIPRECTS 0x1
#define INTEL_BATCH_CLIPRECTS 0x2
struct buffer_reloc
{
dri_bo *buf;
GLuint offset;
GLuint delta; /* not needed? */
GLuint validate_flags;
};
struct intel_batchbuffer
{
struct intel_context *intel;
@ -30,13 +21,9 @@ struct intel_batchbuffer
dri_fence *last_fence;
GLuint flags;
drmBOList list;
GLuint list_count;
GLubyte *map;
GLubyte *ptr;
struct buffer_reloc reloc[MAX_RELOCS];
GLuint nr_relocs;
GLuint size;
};

View file

@ -40,7 +40,6 @@
#include "intel_fbo.h"
#include "intel_reg.h"
#include "intel_regions.h"
#include "vblank.h"
#define FILE_DEBUG_FLAG DEBUG_BLIT
@ -105,8 +104,7 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
}
else {
BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
CMD = (XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB);
}
for (i = 0; i < nbox; i++, pbox++) {
@ -184,8 +182,7 @@ intelEmitFillBlit(struct intel_context *intel,
break;
case 4:
BR13 = dst_pitch | (0xF0 << 16) | (1 << 24) | (1 << 25);
CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
XY_COLOR_BLT_WRITE_RGB);
CMD = (XY_COLOR_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB);
break;
default:
return;
@ -273,8 +270,7 @@ intelEmitCopyBlit(struct intel_context *intel,
(((GLint) dst_pitch) & 0xffff) |
(translate_raster_op(logic_op) << 16) | (1 << 24) | (1 << 25);
CMD =
(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
(XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB);
break;
default:
return;
@ -405,6 +401,9 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask)
b = *box;
}
if (b.x1 >= b.x2 || b.y1 >= b.y2)
continue;
if (0)
_mesa_printf("clear %d,%d..%d,%d, mask %x\n",
b.x1, b.y1, b.x2, b.y2, mask);
@ -443,15 +442,14 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask)
if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) {
CMD = XY_COLOR_BLT_CMD;
if (clearMask & BUFFER_BIT_DEPTH)
CMD |= XY_COLOR_BLT_WRITE_RGB;
CMD |= XY_BLT_WRITE_RGB;
if (clearMask & BUFFER_BIT_STENCIL)
CMD |= XY_COLOR_BLT_WRITE_ALPHA;
CMD |= XY_BLT_WRITE_ALPHA;
}
else {
/* clearing RGBA */
CMD = (XY_COLOR_BLT_CMD |
XY_COLOR_BLT_WRITE_ALPHA |
XY_COLOR_BLT_WRITE_RGB);
CMD = XY_COLOR_BLT_CMD |
XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
}
}
else {

View file

@ -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 };
@ -243,7 +243,7 @@ intelWindowMoved(struct intel_context *intel)
.y2 = sarea->planeB_y + sarea->planeB_h };
GLint areaA = driIntersectArea( drw_rect, planeA_rect );
GLint areaB = driIntersectArea( drw_rect, planeB_rect );
GLuint flags = intel_fb->vblank_flags;
GLuint flags = dPriv->vblFlags;
GLboolean pf_active;
GLint pf_planes;
@ -311,19 +311,24 @@ intelWindowMoved(struct intel_context *intel)
/* Update vblank info
*/
if (areaB > areaA || (areaA == areaB && areaB > 0)) {
flags = intel_fb->vblank_flags | VBLANK_FLAG_SECONDARY;
flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
} else {
flags = intel_fb->vblank_flags & ~VBLANK_FLAG_SECONDARY;
flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
}
if (flags != intel_fb->vblank_flags && intel_fb->vblank_flags &&
!(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ)) {
/* Check to see if we changed pipes */
if (flags != dPriv->vblFlags && dPriv->vblFlags &&
!(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {
int64_t count;
drmVBlank vbl;
int i;
/*
* Deal with page flipping
*/
vbl.request.type = DRM_VBLANK_ABSOLUTE;
if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
vbl.request.type |= DRM_VBLANK_SECONDARY;
}
@ -337,9 +342,19 @@ intelWindowMoved(struct intel_context *intel)
drmWaitVBlank(intel->driFd, &vbl);
}
intel_fb->vblank_flags = flags;
driGetCurrentVBlank(dPriv, intel_fb->vblank_flags, &intel_fb->vbl_seq);
intel_fb->vbl_waited = intel_fb->vbl_seq;
/*
* Update msc_base from old pipe
*/
driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count);
dPriv->msc_base = count;
/*
* Then get new vblank_base and vblSeq values
*/
dPriv->vblFlags = flags;
driGetCurrentVBlank(dPriv);
dPriv->vblank_base = dPriv->vblSeq;
intel_fb->vbl_waited = dPriv->vblSeq;
for (i = 0; i < intel_fb->pf_num_pages; i++) {
if (intel_fb->color_rb[i])
@ -347,7 +362,7 @@ intelWindowMoved(struct intel_context *intel)
}
}
} else {
intel_fb->vblank_flags &= ~VBLANK_FLAG_SECONDARY;
dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
}
/* Update Mesa's notion of window size */
@ -820,10 +835,10 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
*/
static GLboolean
intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
intelScheduleSwap(__DRIdrawablePrivate * dPriv, GLboolean *missed_target)
{
struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
unsigned int interval = driGetVBlankInterval(dPriv, intel_fb->vblank_flags);
unsigned int interval;
struct intel_context *intel =
intelScreenContext(dPriv->driScreenPriv->private);
const intelScreenPrivate *intelScreen = intel->intelScreen;
@ -831,24 +846,26 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
drm_i915_vblank_swap_t swap;
GLboolean ret;
if (!intel_fb->vblank_flags ||
(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) ||
if (!dPriv->vblFlags ||
(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) ||
intelScreen->current_rotation != 0 ||
intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6))
return GL_FALSE;
interval = driGetVBlankInterval(dPriv);
swap.seqtype = DRM_VBLANK_ABSOLUTE;
if (intel_fb->vblank_flags & VBLANK_FLAG_SYNC) {
if (dPriv->vblFlags & VBLANK_FLAG_SYNC) {
swap.seqtype |= DRM_VBLANK_NEXTONMISS;
} else if (interval == 0) {
return GL_FALSE;
}
swap.drawable = dPriv->hHWDrawable;
target = swap.sequence = intel_fb->vbl_seq + interval;
target = swap.sequence = dPriv->vblSeq + interval;
if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
swap.seqtype |= DRM_VBLANK_SECONDARY;
}
@ -866,14 +883,14 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap,
sizeof(swap))) {
intel_fb->vbl_seq = swap.sequence;
dPriv->vblSeq = swap.sequence;
swap.sequence -= target;
*missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23);
intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->vbl_pending =
intel_get_renderbuffer(&intel_fb->Base,
BUFFER_FRONT_LEFT)->vbl_pending =
intel_fb->vbl_seq;
dPriv->vblSeq;
if (swap.seqtype & DRM_VBLANK_FLIP) {
intel_flip_renderbuffers(intel_fb);
@ -918,8 +935,7 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
if (screen->current_rotation != 0 ||
!intelScheduleSwap(dPriv, &missed_target)) {
driWaitForVBlank(dPriv, &intel_fb->vbl_seq, intel_fb->vblank_flags,
&missed_target);
driWaitForVBlank(dPriv, &missed_target);
if (screen->current_rotation != 0 || !intelPageFlip(dPriv)) {
intelCopyBuffer(dPriv, NULL);

View file

@ -0,0 +1,833 @@
/**************************************************************************
*
* Copyright © 2007 Red Hat Inc.
* Copyright © 2007 Intel Corporation
* Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
*
**************************************************************************/
/*
* Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
* Keith Whitwell <keithw-at-tungstengraphics-dot-com>
* Eric Anholt <eric@anholt.net>
* Dave Airlie <airlied@linux.ie>
*/
#include <xf86drm.h>
#include <stdlib.h>
#include <unistd.h>
#include "glthread.h"
#include "errno.h"
#include "mtypes.h"
#include "dri_bufmgr.h"
#include "string.h"
#include "imports.h"
#include "i915_drm.h"
#include "intel_bufmgr_ttm.h"
#define BUFMGR_DEBUG 0
struct intel_reloc_info
{
GLuint type;
GLuint reloc;
GLuint delta; /* not needed? */
GLuint index;
drm_handle_t handle;
};
struct intel_bo_node
{
drmMMListHead head;
drmBO *buf;
struct drm_i915_op_arg bo_arg;
unsigned long arg0;
unsigned long arg1;
void (*destroy)(void *);
void *priv;
};
struct intel_bo_reloc_list
{
drmMMListHead head;
drmBO buf;
uint32_t *relocs;
};
struct intel_bo_reloc_node
{
drmMMListHead head;
drm_handle_t handle;
uint32_t nr_reloc_types;
struct intel_bo_reloc_list type_list;
};
struct intel_bo_list {
unsigned numCurrent;
drmMMListHead list;
void (*destroy)(void *node);
};
typedef struct _dri_bufmgr_ttm {
dri_bufmgr bufmgr;
int fd;
_glthread_Mutex mutex;
unsigned int fence_type;
unsigned int fence_type_flush;
uint32_t max_relocs;
/** ttm relocation list */
struct intel_bo_list list;
struct intel_bo_list reloc_list;
} dri_bufmgr_ttm;
typedef struct _dri_bo_ttm {
dri_bo bo;
int refcount; /* Protected by bufmgr->mutex */
drmBO drm_bo;
const char *name;
} dri_bo_ttm;
typedef struct _dri_fence_ttm
{
dri_fence fence;
int refcount; /* Protected by bufmgr->mutex */
const char *name;
drmFence drm_fence;
} dri_fence_ttm;
static void intel_bo_free_list(struct intel_bo_list *list)
{
struct intel_bo_node *node;
drmMMListHead *l;
l = list->list.next;
while(l != &list->list) {
DRMLISTDEL(l);
node = DRMLISTENTRY(struct intel_bo_node, l, head);
list->destroy(node);
l = list->list.next;
list->numCurrent--;
}
}
static void generic_destroy(void *nodep)
{
free(nodep);
}
static int intel_create_bo_list(int numTarget, struct intel_bo_list *list, void (*destroy)(void *))
{
DRMINITLISTHEAD(&list->list);
list->numCurrent = 0;
if (destroy)
list->destroy = destroy;
else
list->destroy = generic_destroy;
return 0;
}
static struct drm_i915_op_arg *
intel_setup_validate_list(int fd, struct intel_bo_list *list, struct intel_bo_list *reloc_list, GLuint *count_p)
{
struct intel_bo_node *node;
struct intel_bo_reloc_node *rl_node;
drmMMListHead *l, *rl;
struct drm_i915_op_arg *arg, *first;
struct drm_bo_op_req *req;
uint64_t *prevNext = NULL;
GLuint count = 0;
first = NULL;
for (l = list->list.next; l != &list->list; l = l->next) {
node = DRMLISTENTRY(struct intel_bo_node, l, head);
arg = &node->bo_arg;
req = &arg->d.req;
if (!first)
first = arg;
if (prevNext)
*prevNext = (unsigned long) arg;
memset(arg, 0, sizeof(*arg));
prevNext = &arg->next;
req->bo_req.handle = node->buf->handle;
req->op = drm_bo_validate;
req->bo_req.flags = node->arg0;
req->bo_req.hint = 0;
req->bo_req.mask = node->arg1;
req->bo_req.fence_class = 0; /* Backwards compat. */
arg->reloc_handle = 0;
for (rl = reloc_list->list.next; rl != &reloc_list->list; rl = rl->next) {
rl_node = DRMLISTENTRY(struct intel_bo_reloc_node, rl, head);
if (rl_node->handle == node->buf->handle) {
arg->reloc_handle = rl_node->type_list.buf.handle;
}
}
count++;
}
if (!first)
return 0;
*count_p = count;
return first;
}
static void intel_free_validate_list(int fd, struct intel_bo_list *list)
{
struct intel_bo_node *node;
drmMMListHead *l;
for (l = list->list.next; l != &list->list; l = l->next) {
node = DRMLISTENTRY(struct intel_bo_node, l, head);
if (node->destroy)
(*node->destroy)(node->priv);
}
}
static void intel_free_reloc_list(int fd, struct intel_bo_list *reloc_list)
{
struct intel_bo_reloc_node *reloc_node;
drmMMListHead *rl, *tmp;
for (rl = reloc_list->list.next, tmp = rl->next; rl != &reloc_list->list; rl = tmp, tmp = rl->next) {
reloc_node = DRMLISTENTRY(struct intel_bo_reloc_node, rl, head);
DRMLISTDEL(rl);
if (reloc_node->nr_reloc_types > 1) {
/* TODO */
}
drmBOUnmap(fd, &reloc_node->type_list.buf);
drmBOUnreference(fd, &reloc_node->type_list.buf);
free(reloc_node);
}
}
static int intel_add_validate_buffer(struct intel_bo_list *list, dri_bo *buf, unsigned flags,
unsigned mask, int *itemLoc, void (*destroy_cb)(void *))
{
struct intel_bo_node *node, *cur;
drmMMListHead *l;
int count = 0;
int ret = 0;
drmBO *buf_bo = &((dri_bo_ttm *)buf)->drm_bo;
cur = NULL;
for (l = list->list.next; l != &list->list; l = l->next) {
node = DRMLISTENTRY(struct intel_bo_node, l, head);
if (node->buf->handle == buf_bo->handle) {
cur = node;
break;
}
count++;
}
if (!cur) {
cur = drmMalloc(sizeof(*cur));
if (!cur) {
return -ENOMEM;
}
cur->buf = buf_bo;
cur->priv = buf;
cur->arg0 = flags;
cur->arg1 = mask;
cur->destroy = destroy_cb;
ret = 1;
DRMLISTADDTAIL(&cur->head, &list->list);
} else {
unsigned memMask = (cur->arg1 | mask) & DRM_BO_MASK_MEM;
unsigned memFlags = cur->arg0 & flags & memMask;
if (!memFlags) {
return -EINVAL;
}
if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) {
return -EINVAL;
}
cur->arg1 |= mask;
cur->arg0 = memFlags | ((cur->arg0 | flags) &
cur->arg1 & ~DRM_BO_MASK_MEM);
}
*itemLoc = count;
return ret;
}
#define RELOC_BUF_SIZE(x) ((I915_RELOC_HEADER + x * I915_RELOC0_STRIDE) * sizeof(uint32_t))
static int intel_create_new_reloc_type_list(int fd, struct intel_bo_reloc_list *cur_type, int max_relocs)
{
int ret;
/* should allocate a drmBO here */
ret = drmBOCreate(fd, RELOC_BUF_SIZE(max_relocs), 0,
NULL,
DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MAPPABLE | DRM_BO_FLAG_CACHED,
0, &cur_type->buf);
if (ret)
return ret;
ret = drmBOMap(fd, &cur_type->buf, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, (void **)&cur_type->relocs);
if (ret)
return ret;
return 0;
}
static int intel_add_validate_reloc(int fd, struct intel_bo_list *reloc_list, struct intel_reloc_info *reloc_info, uint32_t max_relocs)
{
struct intel_bo_reloc_node *rl_node, *cur;
drmMMListHead *rl, *l;
int ret = 0;
uint32_t *reloc_start;
int num_relocs;
struct intel_bo_reloc_list *cur_type;
cur = NULL;
for (rl = reloc_list->list.next; rl != &reloc_list->list; rl = rl->next) {
rl_node = DRMLISTENTRY(struct intel_bo_reloc_node, rl, head);
if (rl_node->handle == reloc_info->handle) {
cur = rl_node;
break;
}
}
if (!cur) {
cur = malloc(sizeof(*cur));
if (!cur)
return -ENOMEM;
cur->nr_reloc_types = 1;
cur->handle = reloc_info->handle;
cur_type = &cur->type_list;
DRMINITLISTHEAD(&cur->type_list.head);
ret = intel_create_new_reloc_type_list(fd, cur_type, max_relocs);
if (ret) {
return -1;
}
DRMLISTADDTAIL(&cur->head, &reloc_list->list);
cur_type->relocs[0] = 0 | (reloc_info->type << 16);
cur_type->relocs[1] = 0; // next reloc buffer handle is 0
} else {
int found = 0;
if ((cur->type_list.relocs[0] >> 16) == reloc_info->type) {
cur_type = &cur->type_list;
found = 1;
} else {
for (l = cur->type_list.head.next; l != &cur->type_list.head; l = l->next) {
cur_type = DRMLISTENTRY(struct intel_bo_reloc_list, l, head);
if (((cur_type->relocs[0] >> 16) & 0xffff) == reloc_info->type)
found = 1;
break;
}
}
/* didn't find the relocation type */
if (!found) {
cur_type = malloc(sizeof(*cur_type));
if (!cur_type) {
return -ENOMEM;
}
ret = intel_create_new_reloc_type_list(fd, cur_type, max_relocs);
DRMLISTADDTAIL(&cur_type->head, &cur->type_list.head);
cur_type->relocs[0] = (reloc_info->type << 16);
cur_type->relocs[1] = 0;
cur->nr_reloc_types++;
}
}
reloc_start = cur_type->relocs;
num_relocs = (reloc_start[0] & 0xffff);
reloc_start[num_relocs*I915_RELOC0_STRIDE + I915_RELOC_HEADER] = reloc_info->reloc;
reloc_start[num_relocs*I915_RELOC0_STRIDE + I915_RELOC_HEADER+1] = reloc_info->delta;
reloc_start[num_relocs*I915_RELOC0_STRIDE + I915_RELOC_HEADER+2] = reloc_info->index;
reloc_start[0]++;
if (((reloc_start[0] & 0xffff)) > (max_relocs)) {
return -ENOMEM;
}
return 0;
}
#if 0
int
driFenceSignaled(DriFenceObject * fence, unsigned type)
{
int signaled;
int ret;
if (fence == NULL)
return GL_TRUE;
_glthread_LOCK_MUTEX(fence->mutex);
ret = drmFenceSignaled(bufmgr_ttm->fd, &fence->fence, type, &signaled);
_glthread_UNLOCK_MUTEX(fence->mutex);
BM_CKFATAL(ret);
return signaled;
}
#endif
static dri_bo *
dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name,
unsigned long size, unsigned int alignment,
unsigned int location_mask)
{
dri_bufmgr_ttm *ttm_bufmgr;
dri_bo_ttm *ttm_buf;
unsigned int pageSize = getpagesize();
int ret;
unsigned int flags, hint;
ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
ttm_buf = malloc(sizeof(*ttm_buf));
if (!ttm_buf)
return NULL;
/* The mask argument doesn't do anything for us that we want other than
* determine which pool (TTM or local) the buffer is allocated into, so just
* pass all of the allocation class flags.
*/
flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
DRM_BO_FLAG_EXE;
/* No hints we want to use. */
hint = 0;
ret = drmBOCreate(ttm_bufmgr->fd, size, alignment / pageSize,
NULL, flags, hint, &ttm_buf->drm_bo);
if (ret != 0) {
free(ttm_buf);
return NULL;
}
ttm_buf->bo.size = ttm_buf->drm_bo.size;
ttm_buf->bo.offset = ttm_buf->drm_bo.offset;
ttm_buf->bo.virtual = NULL;
ttm_buf->bo.bufmgr = bufmgr;
ttm_buf->name = name;
ttm_buf->refcount = 1;
#if BUFMGR_DEBUG
fprintf(stderr, "bo_create: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
#endif
return &ttm_buf->bo;
}
/* Our TTM backend doesn't allow creation of static buffers, as that requires
* privelege for the non-fake case, and the lock in the fake case where we were
* working around the X Server not creating buffers and passing handles to us.
*/
static dri_bo *
dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name,
unsigned long offset, unsigned long size, void *virtual,
unsigned int location_mask)
{
return NULL;
}
/** Returns a dri_bo wrapping the given buffer object handle.
*
* This can be used when one application needs to pass a buffer object
* to another.
*/
dri_bo *
intel_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
unsigned int handle)
{
dri_bufmgr_ttm *ttm_bufmgr;
dri_bo_ttm *ttm_buf;
int ret;
ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
ttm_buf = malloc(sizeof(*ttm_buf));
if (!ttm_buf)
return NULL;
ret = drmBOReference(ttm_bufmgr->fd, handle, &ttm_buf->drm_bo);
if (ret != 0) {
free(ttm_buf);
return NULL;
}
ttm_buf->bo.size = ttm_buf->drm_bo.size;
ttm_buf->bo.offset = ttm_buf->drm_bo.offset;
ttm_buf->bo.virtual = NULL;
ttm_buf->bo.bufmgr = bufmgr;
ttm_buf->name = name;
ttm_buf->refcount = 1;
#if BUFMGR_DEBUG
fprintf(stderr, "bo_create_from_handle: %p %08x (%s)\n", &ttm_buf->bo, handle,
ttm_buf->name);
#endif
return &ttm_buf->bo;
}
static void
dri_ttm_bo_reference(dri_bo *buf)
{
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
ttm_buf->refcount++;
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
}
static void
dri_ttm_bo_unreference(dri_bo *buf)
{
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
if (!buf)
return;
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
if (--ttm_buf->refcount == 0) {
int ret;
ret = drmBOUnreference(bufmgr_ttm->fd, &ttm_buf->drm_bo);
if (ret != 0) {
fprintf(stderr, "drmBOUnreference failed (%s): %s\n", ttm_buf->name,
strerror(-ret));
}
#if BUFMGR_DEBUG
fprintf(stderr, "bo_unreference final: %p (%s)\n",
&ttm_buf->bo, ttm_buf->name);
#endif
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
free(buf);
return;
}
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
}
static int
dri_ttm_bo_map(dri_bo *buf, GLboolean write_enable)
{
dri_bufmgr_ttm *bufmgr_ttm;
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
unsigned int flags;
bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
flags = DRM_BO_FLAG_READ;
if (write_enable)
flags |= DRM_BO_FLAG_WRITE;
assert(buf->virtual == NULL);
#if BUFMGR_DEBUG
fprintf(stderr, "bo_map: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
#endif
return drmBOMap(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, 0, &buf->virtual);
}
static int
dri_ttm_bo_unmap(dri_bo *buf)
{
dri_bufmgr_ttm *bufmgr_ttm;
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
if (buf == NULL)
return 0;
bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
assert(buf->virtual != NULL);
buf->virtual = NULL;
#if BUFMGR_DEBUG
fprintf(stderr, "bo_unmap: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
#endif
return drmBOUnmap(bufmgr_ttm->fd, &ttm_buf->drm_bo);
}
/* Returns a dri_bo wrapping the given buffer object handle.
*
* This can be used when one application needs to pass a buffer object
* to another.
*/
dri_fence *
intel_ttm_fence_create_from_arg(dri_bufmgr *bufmgr, const char *name,
drm_fence_arg_t *arg)
{
dri_bufmgr_ttm *ttm_bufmgr;
dri_fence_ttm *ttm_fence;
ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
ttm_fence = malloc(sizeof(*ttm_fence));
if (!ttm_fence)
return NULL;
ttm_fence->drm_fence.handle = arg->handle;
ttm_fence->drm_fence.fence_class = arg->fence_class;
ttm_fence->drm_fence.type = arg->type;
ttm_fence->drm_fence.flags = arg->flags;
ttm_fence->drm_fence.signaled = 0;
ttm_fence->drm_fence.sequence = arg->sequence;
ttm_fence->fence.bufmgr = bufmgr;
ttm_fence->name = name;
ttm_fence->refcount = 1;
#if BUFMGR_DEBUG
fprintf(stderr, "fence_create_from_handle: %p (%s)\n", &ttm_fence->fence,
ttm_fence->name);
#endif
return &ttm_fence->fence;
}
static void
dri_ttm_fence_reference(dri_fence *fence)
{
dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
++fence_ttm->refcount;
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
#if BUFMGR_DEBUG
fprintf(stderr, "fence_reference: %p (%s)\n", &fence_ttm->fence,
fence_ttm->name);
#endif
}
static void
dri_ttm_fence_unreference(dri_fence *fence)
{
dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
if (!fence)
return;
#if BUFMGR_DEBUG
fprintf(stderr, "fence_unreference: %p (%s)\n", &fence_ttm->fence,
fence_ttm->name);
#endif
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
if (--fence_ttm->refcount == 0) {
int ret;
ret = drmFenceUnreference(bufmgr_ttm->fd, &fence_ttm->drm_fence);
if (ret != 0) {
fprintf(stderr, "drmFenceUnreference failed (%s): %s\n",
fence_ttm->name, strerror(-ret));
}
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
free(fence);
return;
}
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
}
static void
dri_ttm_fence_wait(dri_fence *fence)
{
dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
int ret;
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
ret = drmFenceWait(bufmgr_ttm->fd, 0, &fence_ttm->drm_fence, 0);
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
if (ret != 0) {
_mesa_printf("%s:%d: Error %d waiting for fence %s.\n",
__FILE__, __LINE__, ret, fence_ttm->name);
abort();
}
#if BUFMGR_DEBUG
fprintf(stderr, "fence_wait: %p (%s)\n", &fence_ttm->fence,
fence_ttm->name);
#endif
}
static void
dri_bufmgr_ttm_destroy(dri_bufmgr *bufmgr)
{
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr;
intel_bo_free_list(&bufmgr_ttm->list);
intel_bo_free_list(&bufmgr_ttm->reloc_list);
_glthread_DESTROY_MUTEX(bufmgr_ttm->mutex);
free(bufmgr);
}
static void intel_dribo_destroy_callback(void *priv)
{
dri_bo *dribo = priv;
if (dribo) {
dri_bo_unreference(dribo);
}
}
static void
dri_ttm_emit_reloc(dri_bo *batch_buf, GLuint flags, GLuint delta, GLuint offset,
dri_bo *relocatee)
{
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)batch_buf;
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
int newItem;
struct intel_reloc_info reloc;
int mask;
int ret;
mask = DRM_BO_MASK_MEM;
mask |= flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE);
ret = intel_add_validate_buffer(&bufmgr_ttm->list, relocatee, flags, mask, &newItem, intel_dribo_destroy_callback);
if (ret < 0)
return;
if (ret == 1) {
dri_bo_reference(relocatee);
}
reloc.type = I915_RELOC_TYPE_0;
reloc.reloc = offset;
reloc.delta = delta;
reloc.index = newItem;
reloc.handle = ttm_buf->drm_bo.handle;
intel_add_validate_reloc(bufmgr_ttm->fd, &bufmgr_ttm->reloc_list, &reloc, bufmgr_ttm->max_relocs);
return;
}
static void *
dri_ttm_process_reloc(dri_bo *batch_buf, GLuint *count)
{
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
void *ptr;
int itemLoc;
dri_bo_unmap(batch_buf);
intel_add_validate_buffer(&bufmgr_ttm->list, batch_buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE,
DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE, &itemLoc, NULL);
ptr = intel_setup_validate_list(bufmgr_ttm->fd, &bufmgr_ttm->list, &bufmgr_ttm->reloc_list, count);
return ptr;
}
static void
dri_ttm_post_submit(dri_bo *batch_buf, dri_fence **last_fence)
{
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
intel_free_validate_list(bufmgr_ttm->fd, &bufmgr_ttm->list);
intel_free_reloc_list(bufmgr_ttm->fd, &bufmgr_ttm->reloc_list);
intel_bo_free_list(&bufmgr_ttm->list);
}
/**
* Initializes the TTM buffer manager, which uses the kernel to allocate, map,
* and manage map buffer objections.
*
* \param fd File descriptor of the opened DRM device.
* \param fence_type Driver-specific fence type used for fences with no flush.
* \param fence_type_flush Driver-specific fence type used for fences with a
* flush.
*/
dri_bufmgr *
intel_bufmgr_ttm_init(int fd, unsigned int fence_type,
unsigned int fence_type_flush, int batch_size)
{
dri_bufmgr_ttm *bufmgr_ttm;
bufmgr_ttm = malloc(sizeof(*bufmgr_ttm));
bufmgr_ttm->fd = fd;
bufmgr_ttm->fence_type = fence_type;
bufmgr_ttm->fence_type_flush = fence_type_flush;
_glthread_INIT_MUTEX(bufmgr_ttm->mutex);
/* lets go with one relocation per every four dwords - purely heuristic */
bufmgr_ttm->max_relocs = batch_size / sizeof(uint32_t) / 4;
intel_create_bo_list(10, &bufmgr_ttm->list, NULL);
intel_create_bo_list(1, &bufmgr_ttm->reloc_list, NULL);
bufmgr_ttm->bufmgr.bo_alloc = dri_ttm_alloc;
bufmgr_ttm->bufmgr.bo_alloc_static = dri_ttm_alloc_static;
bufmgr_ttm->bufmgr.bo_reference = dri_ttm_bo_reference;
bufmgr_ttm->bufmgr.bo_unreference = dri_ttm_bo_unreference;
bufmgr_ttm->bufmgr.bo_map = dri_ttm_bo_map;
bufmgr_ttm->bufmgr.bo_unmap = dri_ttm_bo_unmap;
bufmgr_ttm->bufmgr.fence_reference = dri_ttm_fence_reference;
bufmgr_ttm->bufmgr.fence_unreference = dri_ttm_fence_unreference;
bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait;
bufmgr_ttm->bufmgr.destroy = dri_bufmgr_ttm_destroy;
bufmgr_ttm->bufmgr.emit_reloc = dri_ttm_emit_reloc;
bufmgr_ttm->bufmgr.process_relocs = dri_ttm_process_reloc;
bufmgr_ttm->bufmgr.post_submit = dri_ttm_post_submit;
return &bufmgr_ttm->bufmgr;
}

View file

@ -0,0 +1,17 @@
#ifndef INTEL_BUFMGR_TTM_H
#define INTEL_BUFMGR_TTM_H
#include "dri_bufmgr.h"
extern dri_bo *intel_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
unsigned int handle);
dri_fence *intel_ttm_fence_create_from_arg(dri_bufmgr *bufmgr, const char *name,
drm_fence_arg_t *arg);
dri_bufmgr *intel_bufmgr_ttm_init(int fd, unsigned int fence_type,
unsigned int fence_type_flush, int batch_size);
#endif

View file

@ -613,21 +613,20 @@ 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)
driDrawPriv->vblFlags = (intel->intelScreen->irq_active != 0)
? driGetDefaultVBlankFlags(&intel->optionCache)
: VBLANK_FLAG_NO_IRQ;
(*dri_interface->getUST) (&intel_fb->swap_ust);
driDrawableInitVBlank(driDrawPriv, intel_fb->vblank_flags,
&intel_fb->vbl_seq);
intel_fb->vbl_waited = intel_fb->vbl_seq;
driDrawableInitVBlank(driDrawPriv);
intel_fb->vbl_waited = driDrawPriv->vblSeq;
for (i = 0; i < (intel->intelScreen->third.handle ? 3 : 2); i++) {
if (intel_fb->color_rb[i])
intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_seq;
intel_fb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
}
}
intel->driDrawable = driDrawPriv;
@ -731,6 +730,7 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
*/
void LOCK_HARDWARE( struct intel_context *intel )
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
char __ret=0;
struct intel_framebuffer *intel_fb = NULL;
struct intel_renderbuffer *intel_rb = NULL;
@ -748,14 +748,14 @@ void LOCK_HARDWARE( struct intel_context *intel )
BUFFER_BACK_LEFT);
}
if (intel_rb && intel_fb->vblank_flags &&
!(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) &&
if (intel_rb && dPriv->vblFlags &&
!(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) &&
(intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) {
drmVBlank vbl;
vbl.request.type = DRM_VBLANK_ABSOLUTE;
if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
vbl.request.type |= DRM_VBLANK_SECONDARY;
}

View file

@ -292,6 +292,8 @@ extern char *__progname;
#define SUBPIXEL_X 0.125
#define SUBPIXEL_Y 0.125
#define ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1))
#define INTEL_FIREVERTICES(intel) \
do { \
if ((intel)->prim.flush) \
@ -460,9 +462,6 @@ extern void intelInitStateFuncs(struct dd_function_table *functions);
#define BLENDFACT_INV_CONST_ALPHA 0x0f
#define BLENDFACT_MASK 0x0f
#define MI_BATCH_BUFFER_END (0xA<<23)
extern int intel_translate_compare_func(GLenum func);
extern int intel_translate_stencil_op(GLenum op);
extern int intel_translate_blend_factor(GLenum factor);

View file

@ -50,8 +50,6 @@ struct intel_framebuffer
/* VBI
*/
GLuint vbl_seq;
GLuint vblank_flags;
GLuint vbl_waited;
int64_t swap_ust;

View file

@ -42,6 +42,8 @@
#include "intel_regions.h"
#include "drm.h"
#include "intel_bufmgr_ttm.h"
#define FILE_DEBUG_FLAG DEBUG_IOCTL
int
@ -105,9 +107,6 @@ intel_batch_ioctl(struct intel_context *intel,
* hardware contexts which would preserve statechanges beyond a
* single buffer.
*/
batch.start = start_offset;
batch.used = used;
batch.cliprects = intel->pClipRects;
@ -133,3 +132,56 @@ intel_batch_ioctl(struct intel_context *intel,
*/
intel->vtbl.lost_hardware(intel);
}
void
intel_exec_ioctl(struct intel_context *intel,
GLuint used,
GLboolean ignore_cliprects, GLboolean allow_unlock,
void *start, GLuint count, dri_fence **fence)
{
struct drm_i915_execbuffer execbuf;
dri_fence *fo;
assert(intel->locked);
assert(used);
if (*fence) {
dri_fence_unreference(*fence);
}
memset(&execbuf, 0, sizeof(execbuf));
execbuf.num_buffers = count;
execbuf.batch.used = used;
execbuf.batch.cliprects = intel->pClipRects;
execbuf.batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
execbuf.batch.DR1 = 0;
execbuf.batch.DR4 = ((((GLuint) intel->drawX) & 0xffff) |
(((GLuint) intel->drawY) << 16));
execbuf.ops_list = (unsigned)start; // TODO
execbuf.fence_arg.flags = DRM_FENCE_FLAG_SHAREABLE | DRM_I915_FENCE_FLAG_FLUSHED;
if (drmCommandWriteRead(intel->driFd, DRM_I915_EXECBUFFER, &execbuf,
sizeof(execbuf))) {
fprintf(stderr, "DRM_I830_EXECBUFFER: %d\n", -errno);
UNLOCK_HARDWARE(intel);
exit(1);
}
fo = intel_ttm_fence_create_from_arg(intel->intelScreen->bufmgr, "fence buffers",
&execbuf.fence_arg);
if (!fo) {
fprintf(stderr, "failed to fence handle: %08x\n", execbuf.fence_arg.handle);
UNLOCK_HARDWARE(intel);
exit(1);
}
*fence = fo;
/* FIXME: use hardware contexts to avoid 'losing' hardware after
* each buffer flush.
*/
intel->vtbl.lost_hardware(intel);
}

View file

@ -37,4 +37,8 @@ void intel_batch_ioctl(struct intel_context *intel,
GLuint start_offset,
GLuint used,
GLboolean ignore_cliprects, GLboolean allow_unlock);
void intel_exec_ioctl(struct intel_context *intel,
GLuint used,
GLboolean ignore_cliprects, GLboolean allow_unlock,
void *start, GLuint count, dri_fence **fence);
#endif

View file

@ -99,12 +99,29 @@ intel_miptree_create(struct intel_context *intel,
if (ok) {
if (!mt->compressed) {
/* XXX: Align pitch to multiple of 64 bytes for now to allow
* render-to-texture to work in all cases. This should probably be
* replaced at some point by some scheme to only do this when really
* necessary.
int align;
if (intel->intelScreen->ttm) {
/* XXX: Align pitch to multiple of 64 bytes for now to allow
* render-to-texture to work in all cases. This should probably be
* replaced at some point by some scheme to only do this when really
* necessary.
*/
align = 63;
} else {
align = 3;
}
mt->pitch = (mt->pitch * cpp + align) & ~align;
/* XXX: At least the i915 seems very upset when the pitch is a multiple
* of 1024 and sometimes 512 bytes - performance can drop by several
* times. Go to the next multiple of the required alignment for now.
*/
mt->pitch = ((mt->pitch * cpp + 63) & ~63) / cpp;
if (!(mt->pitch & 511))
mt->pitch += align + 1;
mt->pitch /= cpp;
}
mt->region = intel_region_alloc(intel->intelScreen,

View file

@ -44,6 +44,7 @@
#include "intel_blit.h"
#include "intel_buffer_objects.h"
#include "dri_bufmgr.h"
#include "intel_bufmgr_ttm.h"
#include "intel_batchbuffer.h"
#define FILE_DEBUG_FLAG DEBUG_REGION
@ -162,7 +163,7 @@ intel_region_create_static(intelScreenPrivate *intelScreen,
if (intelScreen->ttm) {
assert(bo_handle != -1);
region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr,
region->buffer = intel_ttm_bo_create_from_handle(intelScreen->bufmgr,
"static region",
bo_handle);
} else {
@ -201,7 +202,7 @@ intel_region_update_static(intelScreenPrivate *intelScreen,
dri_bo_unreference(region->buffer);
if (intelScreen->ttm) {
assert(bo_handle != -1);
region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr,
region->buffer = intel_ttm_bo_create_from_handle(intelScreen->bufmgr,
"static region",
bo_handle);
} else {

Some files were not shown because too many files have changed in this diff Show more