mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
Merge branch 'master' of git+ssh://joukj@git.freedesktop.org/git/mesa/mesa
This commit is contained in:
commit
d1414da8f9
239 changed files with 10518 additions and 6111 deletions
4
Makefile
4
Makefile
|
|
@ -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
|
||||
|
||||
|
|
|
|||
32
configs/catamount-osmesa-pgi
Normal file
32
configs/catamount-osmesa-pgi
Normal 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
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
3
progs/beos/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
demo
|
||||
GLInfo
|
||||
sample
|
||||
|
|
@ -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 $@
|
||||
|
|
|
|||
3
progs/demos/.gitignore
vendored
3
progs/demos/.gitignore
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
4
progs/directfb/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
df_gears
|
||||
df_morph3d
|
||||
df_reflect
|
||||
multi_window
|
||||
|
|
@ -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
5
progs/egl/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
demo1
|
||||
demo2
|
||||
demo3
|
||||
eglgears
|
||||
eglinfo
|
||||
1
progs/fbdev/.gitignore
vendored
Normal file
1
progs/fbdev/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
glfbdevtest
|
||||
|
|
@ -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
42
progs/fp/.gitignore
vendored
Normal 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
|
||||
|
|
@ -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
13
progs/glsl/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
bitmap
|
||||
brick
|
||||
bump
|
||||
deriv
|
||||
extfuncs.h
|
||||
mandelbrot
|
||||
noise
|
||||
points
|
||||
readtex.c
|
||||
readtex.h
|
||||
texdemo1
|
||||
trirast
|
||||
toyball
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
6
progs/miniglx/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
manytex
|
||||
miniglxsample
|
||||
miniglxtest
|
||||
sample_server
|
||||
sample_server2
|
||||
texline
|
||||
|
|
@ -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
8
progs/osdemos/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
osdemo
|
||||
osdemo16
|
||||
osdemo32
|
||||
ostest1
|
||||
readtex.c
|
||||
readtex.h
|
||||
showbuffer.c
|
||||
showbuffer.h
|
||||
|
|
@ -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 #####
|
||||
|
|
|
|||
|
|
@ -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 $@
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
32
progs/samples/.gitignore
vendored
32
progs/samples/.gitignore
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
3
progs/slang/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
cltest
|
||||
sotest
|
||||
vstest
|
||||
|
|
@ -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
|
||||
|
|
|
|||
6
progs/tests/.gitignore
vendored
6
progs/tests/.gitignore
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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
1
progs/tools/trace/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
gltrace.cc
|
||||
65
progs/trivial/.gitignore
vendored
Normal file
65
progs/trivial/.gitignore
vendored
Normal 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
|
||||
|
|
@ -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
1
progs/vp/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
vp-tris
|
||||
|
|
@ -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
|
||||
|
|
|
|||
6
progs/xdemos/.gitignore
vendored
6
progs/xdemos/.gitignore
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
396
progs/xdemos/corender.c
Normal 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;
|
||||
}
|
||||
|
|
@ -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
377
progs/xdemos/glxsnoop.c
Normal 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
264
progs/xdemos/ipc.c
Normal 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
16
progs/xdemos/ipc.h
Normal 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 */
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@
|
|||
#endif
|
||||
|
||||
|
||||
extern int
|
||||
QueryFBConfig(Display *dpy, int screen);
|
||||
|
||||
extern int
|
||||
QueryPbuffers(Display *dpy, int screen);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
411
src/glx/x11/glxhash.c
Normal 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
16
src/glx/x11/glxhash.h
Normal 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_ */
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ COMMON_SOURCES = \
|
|||
|
||||
COMMON_BM_SOURCES = \
|
||||
../common/dri_bufmgr.c \
|
||||
../common/dri_bufmgr_ttm.c \
|
||||
../common/dri_bufmgr_fake.c
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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() */
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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++]);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
833
src/mesa/drivers/dri/i915/intel_bufmgr_ttm.c
Normal file
833
src/mesa/drivers/dri/i915/intel_bufmgr_ttm.c
Normal 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;
|
||||
}
|
||||
|
||||
17
src/mesa/drivers/dri/i915/intel_bufmgr_ttm.h
Normal file
17
src/mesa/drivers/dri/i915/intel_bufmgr_ttm.h
Normal 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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -50,8 +50,6 @@ struct intel_framebuffer
|
|||
|
||||
/* VBI
|
||||
*/
|
||||
GLuint vbl_seq;
|
||||
GLuint vblank_flags;
|
||||
GLuint vbl_waited;
|
||||
|
||||
int64_t swap_ust;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Reference in a new issue