diff options
113 files changed, 3204 insertions, 2104 deletions
@@ -74,9 +74,10 @@ bluegene-xlc-osmesa \  beos \  catamount-osmesa-pgi \  darwin \ +darwin-fat-32bit \ +darwin-fat-all \  darwin-static \  darwin-static-x86ppc \ -darwin-x86ppc \  freebsd \  freebsd-dri \  freebsd-dri-amd64 \ diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000000..19e5b55fcf --- /dev/null +++ b/autogen.sh @@ -0,0 +1,16 @@ +#! /bin/sh + +srcdir=`dirname "$0"` +test -z "$srcdir" && srcdir=. + +SRCDIR=`(cd "$srcdir" && pwd)` +ORIGDIR=`pwd` + +if test "x$SRCDIR" != "x$ORIGDIR"; then +	echo "Mesa cannot be built when srcdir != builddir" 1>&2 +	exit 1 +fi + +autoreconf -v --install || exit 1 + +"$srcdir"/configure "$@" diff --git a/configs/darwin b/configs/darwin index 438abd94c1..c7f94d2bad 100644 --- a/configs/darwin +++ b/configs/darwin @@ -4,10 +4,9 @@ include $(TOP)/configs/default  CONFIG_NAME = darwin -DEFINES = -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE \ -	  -D_BSD_SOURCE -D_GNU_SOURCE \ -	  -DGLX_INDIRECT_RENDERING \ -	  -DPTHREADS -DGLX_ALIAS_UNSUPPORTED -DHAVE_POSIX_MEMALIGN +DEFINES = -D_DARWIN_C_SOURCE -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L \ +	  -D_SVID_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE \ +	  -DPTHREADS -DGLX_ALIAS_UNSUPPORTED -DGLX_INDIRECT_RENDERING  # Compiler and flags  CC = gcc @@ -37,4 +36,5 @@ GLW_LIB_DEPS = -L/usr/X11R6/lib -lX11 -lXt $(TOP)/lib/GL.dylib  APP_LIB_DEPS = -L$(TOP)/lib -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) -L/usr/X11/lib -lX11 -lXmu -lXt -lXi -lm  # omit glw lib for now: -SRC_DIRS = glx/x11 glu glut/glx +SRC_DIRS = glx/x11 glu glut/glx mesa +DRIVER_DIRS = osmesa diff --git a/configs/darwin-fat-32bit b/configs/darwin-fat-32bit new file mode 100644 index 0000000000..56bc6a37a4 --- /dev/null +++ b/configs/darwin-fat-32bit @@ -0,0 +1,7 @@ +# Configuration for Darwin / MacOS X, making 32bit fat dynamic libs + +RC_CFLAGS=-arch ppc -arch i386 + +include $(TOP)/configs/darwin + +CONFIG_NAME = darwin-fat-32bit diff --git a/configs/darwin-fat-all b/configs/darwin-fat-all new file mode 100644 index 0000000000..b8668dc5ae --- /dev/null +++ b/configs/darwin-fat-all @@ -0,0 +1,7 @@ +# Configuration for Darwin / MacOS X, making 32bit and 64bit fat dynamic libs + +RC_CFLAGS=-arch ppc -arch i386 -arch ppc64 -arch x86_64 + +include $(TOP)/configs/darwin + +CONFIG_NAME = darwin-fat-all diff --git a/configs/darwin-x86ppc b/configs/darwin-x86ppc deleted file mode 100644 index c87b206f92..0000000000 --- a/configs/darwin-x86ppc +++ /dev/null @@ -1,37 +0,0 @@ -# Configuration for Darwin / MacOS X, making dynamic libs - -include $(TOP)/configs/default - -CONFIG_NAME = darwin - -# Compiler and flags -CC = cc -CXX = cc -CFLAGS = -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk \ -         -I/usr/X11R6/include -O3 -fPIC -fno-common -ffast-math -funroll-loops -fexpensive-optimizations -no-cpp-precomp -dynamic -Ddarwin -CXXFLAGS = -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk \ -         -I/usr/X11R6/include -O3 -fPIC -fno-common -ffast-math -funroll-loops -fexpensive-optimizations -no-cpp-precomp -dynamic -Ddarwin - -MKLIB_OPTIONS = -archopt "-isysroot /Developer/SDKs/MacOSX10.4u.sdk" - -# Work around aliasing bugs - developers should comment this out -CFLAGS += -fno-strict-aliasing -CXXFLAGS += -fno-strict-aliasing - -# Library names (actual file names) -GL_LIB_NAME = libGL.dylib -GLU_LIB_NAME = libGLU.dylib -GLUT_LIB_NAME = libglut.dylib -GLW_LIB_NAME = libGLw.dylib -OSMESA_LIB_NAME = libOSMesa.dylib - -GL_LIB_DEPS = -L/usr/X11R6/lib -lX11 -lXext -lm -lpthread -OSMESA_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -lGL -GLU_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -lGL -GLUT_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -lGL -lGLU -L/usr/X11R6/lib -lX11 -lXmu -lXi -lXext -GLW_LIB_DEPS = -L/usr/X11R6/lib -lX11 -lXt $(TOP)/lib/GL.dylib -APP_LIB_DEPS = -L$(TOP)/lib -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) -L/usr/X11R6/lib -lX11 -lXmu -lXt -lXi -lm - -# omit glw lib for now: -SRC_DIRS = mesa glu glut/glx - diff --git a/configure.ac b/configure.ac index ec1bb8288e..8b79342e45 100644 --- a/configure.ac +++ b/configure.ac @@ -26,19 +26,29 @@ dnl Check for progs  AC_PROG_CPP  AC_PROG_CC  AC_PROG_CXX +AC_PATH_PROG(GMAKE, gmake, [not_found])  AC_PATH_PROG(MAKE, make) +if test "x$GMAKE" != "xnot_found"; then +	MAKE="$GMAKE" +fi  AC_PATH_PROG(MKDEP, makedepend)  AC_PATH_PROG(SED, sed) +MKDEP_OPTIONS=-fdepend  dnl Ask gcc where it's keeping its secret headers  if test "x$GCC" = xyes; then -    GCC_PATH=$(gcc -print-search-dirs | sed -ne 's/install: //p') -    MKDEP_OPTIONS="-fdepend -I${GCC_PATH}include" -else -    MKDEP_OPTIONS=-fdepend +    GCC_INCLUDES=`$CC -print-file-name=include` +    if test "x$GCC_INCLUDES" != x; then +        MKDEP_OPTIONS="$MKDEP_OPTIONS -I$GCC_INCLUDES" +    fi  fi  AC_SUBST(MKDEP_OPTIONS) +dnl Check to see if dlopen is in default libraries (like Solaris, which +dnl has it in libc), or if libdl is needed to get it. +AC_CHECK_FUNC([dlopen], [], +	AC_CHECK_LIB([dl], [dlopen], DLOPEN_LIBS="-ldl")) +  dnl Make sure the pkg-config macros are defined  m4_ifdef([PKG_PROG_PKG_CONFIG],,[      AC_MSG_ERROR([The pkg-config autoconf macros are not defined. @@ -63,11 +73,11 @@ AC_SUBST(X11_INCLUDES)  dnl Compiler macros  DEFINES=""  AC_SUBST(DEFINES) -if test "x$GCC" = xyes; then -    DEFINES="-D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_BSD_SOURCE" -fi  case "$host_os" in  linux*) +if test "x$GCC" = xyes; then +    DEFINES="$DEFINES -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_BSD_SOURCE" +fi      DEFINES="$DEFINES -D_SVID_SOURCE -D_GNU_SOURCE -DPTHREADS -DHAVE_POSIX_MEMALIGN"      ;;  esac @@ -290,7 +300,13 @@ fi  dnl If $with_demos is yes, directories will be added as libs available  PROGRAM_DIRS=""  case "$with_demos" in -no|yes) ;; +no) ;; +yes) +    # If the driver isn't osmesa, we have libGL and can build xdemos +    if test "$mesa_driver" != osmesa; then +        PROGRAM_DIRS="xdemos" +    fi +    ;;  *)      # verify the requested demos directories exist      demos=`IFS=,; echo $with_demos` @@ -389,7 +405,7 @@ dri)      fi      # need DRM libs, -lpthread, etc. -    GL_LIB_DEPS="$GL_LIB_DEPS $LIBDRM_LIBS -lm -lpthread -ldl" +    GL_LIB_DEPS="$GL_LIB_DEPS $LIBDRM_LIBS -lm -lpthread $DLOPEN_LIBS"      ;;  osmesa)      # No libGL for osmesa @@ -540,7 +556,7 @@ if test "$mesa_driver" = dri; then          AC_MSG_ERROR([Expat required for DRI.]))      # put all the necessary libs together -    DRI_LIB_DEPS="$SELINUX_LIBS $LIBDRM_LIBS $EXPAT_LIB -lm -lpthread -ldl" +    DRI_LIB_DEPS="$SELINUX_LIBS $LIBDRM_LIBS $EXPAT_LIB -lm -lpthread $DLOPEN_LIBS"  fi  AC_SUBST(DRI_DIRS)  AC_SUBST(EXPAT_INCLUDES) @@ -643,11 +659,6 @@ if test "x$enable_glu" = xyes; then          fi          ;;      *) -        # If GLU is available, we can build the xdemos -        if test "$with_demos" = yes; then -            PROGRAM_DIRS="$PROGRAM_DIRS xdemos" -        fi -          # If static, empty GLU_LIB_DEPS and add libs for programs to link          if test "$enable_static" = no; then              GLU_LIB_DEPS="-lm" diff --git a/docs/autoconf.html b/docs/autoconf.html index 518f5d2d41..d0f91558b7 100644 --- a/docs/autoconf.html +++ b/docs/autoconf.html @@ -43,9 +43,12 @@ configure script, type:  <p>  To see a short description of all the options, type <code>./configure  --help</code>. If you are using a development snapshot and the configure -script does not exist, type <code>make configure</code> to generate it -first. Once you have run <code>./configure</code> and set the options to -your preference, type: +script does not exist, type <code>./autogen.sh</code> to generate it +first. If you know the options you want to pass to +<code>configure</code>, you can pass them to <code>autogen.sh</code>. It +will run <code>configure</code> with these options after it is +generated. Once you have run <code>configure</code> and set the options +to your preference, type:  </p>  <pre> diff --git a/docs/cell.html b/docs/cell.html index 407f712312..f9915d67e5 100644 --- a/docs/cell.html +++ b/docs/cell.html @@ -31,6 +31,12 @@ Second, to implement a full-featured OpenGL driver with support for GLSL, etc.  <p>  The Cell driver source code is on the <code>gallium-0.1</code> branch of the  git repository. +After you've cloned the repository, check out the branch with: +</p> +<pre> +   git-checkout -b gallium-0.1 origin/gallium-0.1 +</pre> +<p>  To build the driver you'll need the IBM Cell SDK (version 2.1 or 3.0).  To use the driver you'll need a Cell system, such as a PS3 running Linux,  or the Cell Simulator (untested, though). diff --git a/include/GL/glext.h b/include/GL/glext.h index 2519a6cc5e..2b22714c30 100644 --- a/include/GL/glext.h +++ b/include/GL/glext.h @@ -46,9 +46,9 @@ extern "C" {  /*************************************************************/  /* Header file version number, required by OpenGL ABI for Linux */ -/* glext.h last updated 2007/02/12 */ +/* glext.h last updated 2008/03/24 */  /* Current version at http://www.opengl.org/registry/ */ -#define GL_GLEXT_VERSION 39 +#define GL_GLEXT_VERSION 40  #ifndef GL_VERSION_1_2  #define GL_UNSIGNED_BYTE_3_3_2            0x8032 @@ -3091,8 +3091,8 @@ extern "C" {  #ifndef GL_EXT_framebuffer_blit  #define GL_READ_FRAMEBUFFER_EXT           0x8CA8  #define GL_DRAW_FRAMEBUFFER_EXT           0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING_EXT   GL_FRAMEBUFFER_BINDING_EXT -#define GL_DRAW_FRAMEBUFFER_BINDING_EXT   0x8CAA +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT   GL_FRAMEBUFFER_BINDING_EXT +#define GL_READ_FRAMEBUFFER_BINDING_EXT   0x8CAA  #endif  #ifndef GL_EXT_framebuffer_multisample @@ -3379,6 +3379,9 @@ extern "C" {  #define GL_RGBA_INTEGER_MODE_EXT          0x8D9E  #endif +#ifndef GL_GREMEDY_frame_terminator +#endif +  /*************************************************************/ @@ -7252,6 +7255,14 @@ typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint  typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha);  #endif +#ifndef GL_GREMEDY_frame_terminator +#define GL_GREMEDY_frame_terminator 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFrameTerminatorGREMEDY (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void); +#endif +  #ifdef __cplusplus  } diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 175ff2d3af..fb68fd6ee7 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -216,16 +216,14 @@ struct __DRItexBufferExtensionRec {      __DRIextension base;      /** -     * Method to override base texture image with a DRM memory manager -     * buffer object.  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. +     * Method to override base texture image with the contents of a +     * __DRIdrawable.        *       * For GLX_EXT_texture_from_pixmap with AIGLX.       */      void (*setTexBuffer)(__DRIcontext *pDRICtx, -			 GLint target, unsigned long handle, -			 GLint cpp, GLuint pitch, GLuint height); +			 GLint target, +			 __DRIdrawable *pDraw);  }; @@ -243,7 +241,7 @@ struct __DRItexBufferExtensionRec {   */  /*@{*/ -#define __DRI_INTERFACE_VERSION 20080226 +#define __DRI_INTERFACE_VERSION 20080310  typedef void *(CREATENEWSCREENFUNC)(int scr, __DRIscreen *psc,      const __DRIversion * ddx_version, const __DRIversion * dri_version, @@ -424,8 +422,9 @@ struct __DRIcoreDRI2ExtensionRec {       * specified drawable in the DRI2 event buffer.       *       * \param draw the drawable for which to request info +     * \param tail the new event buffer tail pointer       */ -    void (*reemitDrawableInfo)(__DRIdrawable *draw); +    void (*reemitDrawableInfo)(__DRIdrawable *draw, unsigned int *tail);  }; @@ -481,6 +480,7 @@ struct __DRIscreenRec {  			       const __GLcontextModes *modes,  			       __DRIdrawable *pdraw,  			       drm_drawable_t hwDrawable, +			       unsigned int head,  			       int renderType, const int *attrs);      /** diff --git a/progs/demos/.gitignore b/progs/demos/.gitignore index ad20499f1e..ab836eb834 100644 --- a/progs/demos/.gitignore +++ b/progs/demos/.gitignore @@ -32,6 +32,7 @@ osdemo  paltex  pixeltex  pointblast +rain  ray  readpix  readtex.c diff --git a/progs/demos/Makefile b/progs/demos/Makefile index dcddee17d4..456bd4a2c7 100644 --- a/progs/demos/Makefile +++ b/progs/demos/Makefile @@ -159,10 +159,10 @@ rain: particles.o rain.o readtex.o  	$(CXX) $(LDFLAGS) $^ $(LIBS) -o $@  rain.o: rain.cxx readtex.h -	$(CXX) -c -I../ $(CXXFLAGS) $< +	$(CXX) -c -I$(INCDIR) $(CXXFLAGS) $<  particles.o: particles.cxx -	$(CXX) -c -I../ $(CXXFLAGS) $< +	$(CXX) -c -I$(INCDIR) $(CXXFLAGS) $<  viewdds: viewdds.c diff --git a/progs/glsl/.gitignore b/progs/glsl/.gitignore index b63693bbb5..7865753ea9 100644 --- a/progs/glsl/.gitignore +++ b/progs/glsl/.gitignore @@ -9,5 +9,6 @@ points  readtex.c  readtex.h  texdemo1 -trirast  toyball +trirast +twoside diff --git a/progs/tests/.gitignore b/progs/tests/.gitignore index d789b3098e..6505c315a6 100644 --- a/progs/tests/.gitignore +++ b/progs/tests/.gitignore @@ -38,6 +38,7 @@ getproclist.h  interleave  invert  jkrahntest +lineclip  manytex  mipmap_limits  multipal @@ -66,6 +67,7 @@ texline  texobjshare  texrect  texwrap +unfilledclip  vao-01  vao-02  vparray diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 7bf64e19e4..116a19b1f5 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -48,6 +48,7 @@ SOURCES = \  	interleave.c \  	invert.c \  	jkrahntest.c \ +	lineclip.c \  	manytex.c \  	minmag.c \  	mipmap_limits.c \ @@ -73,6 +74,7 @@ SOURCES = \  	texobjshare.c \  	texrect.c \  	texwrap.c \ +	unfilledclip.c \  	vao-01.c \  	vao-02.c \  	vparray.c \ diff --git a/progs/tests/lineclip.c b/progs/tests/lineclip.c new file mode 100644 index 0000000000..098f5e92eb --- /dev/null +++ b/progs/tests/lineclip.c @@ -0,0 +1,175 @@ +/* + * Copyright © 2008 Intel Corporation + * + * 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 + * 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. + * + * Authors: + *    Eric Anholt <eric@anholt.net> + * + */ + +#include <stdlib.h> +#include <GL/glut.h> + +static int win_width, win_height; + +static void +line(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) +{ +	glBegin(GL_LINES); +	glVertex2f(x1, y1); +	glVertex2f(x2, y2); +	glEnd(); +} + +static void +line3(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2) +{ +	glBegin(GL_LINES); +	glVertex3f(x1, y1, z1); +	glVertex3f(x2, y2, z2); +	glEnd(); +} + +static void +display(void) +{ +	glClearColor(0.0, 0.0, 0.0, 0.0); +	glClear(GL_COLOR_BUFFER_BIT); + +	glColor3f(1.0, 0.0, 0.0); +	/* 2 lines clipped along xmin */ +	line(-20, win_height / 2 - 20, +	      20, win_height / 2 - 20); +	line( 20, win_height / 2 + 20, +	     -20, win_height / 2 + 20); + +	glColor3f(0.0, 1.0, 0.0); +	/* 2 lines clipped along ymax */ +	line(win_width / 2 - 20, win_height + 20, +	     win_width / 2 - 20, win_height - 20); +	line(win_width / 2 + 20, win_height - 20, +	     win_width / 2 + 20, win_height + 20); + +	glColor3f(0.0, 0.0, 1.0); +	/* 2 lines clipped along xmax */ +	line(win_width - 20, win_height / 2 - 20, +	     win_width + 20, win_height / 2 - 20); +	line(win_width + 20, win_height / 2 + 20, +	     win_width - 20, win_height / 2 + 20); + +	glColor3f(1.0, 1.0, 1.0); +	/* 2 lines clipped along ymin */ +	line(win_width / 2 - 20,  20, +	     win_width / 2 - 20, -20); +	line(win_width / 2 + 20, -20, +	     win_width / 2 + 20,  20); + +	/* 2 lines clipped along near */ +	glColor3f(1.0, 0.0, 1.0); +	line3(win_width / 2 - 20 - 20, win_height / 2,       0.5, +	      win_width / 2 - 20 + 20, win_height / 2,      -0.5); +	line3(win_width / 2 - 20,      win_height / 2 - 20, -0.5, +	      win_width / 2 - 20,      win_height / 2 + 20,  0.5); + +	/* 2 lines clipped along far */ +	glColor3f(0.0, 1.0, 1.0); +	line3(win_width / 2 + 20 - 20, win_height / 2,      1.5, +	      win_width / 2 + 20 + 20, win_height / 2,      0.5); +	line3(win_width / 2 + 20,      win_height / 2 - 20, 0.5, +	      win_width / 2 + 20,      win_height / 2 + 20, 1.5); + +	/* entirely clipped along near/far */ +	glColor3f(.5, .5, .5); +	line3(win_width / 2, win_height / 2 - 20, -0.5, +	      win_width / 2, win_height / 2 + 20, -0.5); +	glColor3f(.5, .5, .5); +	line3(win_width / 2, win_height / 2 - 20, 1.5, +	      win_width / 2, win_height / 2 + 20, 1.5); + +	glColor3f(1.0, 1.0, 0.0); +	/* lines clipped along both x and y limits */ +	line(-5, 20, +	     20, -5); /* xmin, ymin */ +	line(-5, win_height - 20, +	     20, win_height + 5); /* xmin, ymax */ +	line(win_width - 20, -5, +	     win_width + 5,  20); /* xmax, ymin */ +	line(win_width - 20, win_height + 5, +	     win_width + 5,  win_height - 20); /* xmax, ymax */ + +	glutSwapBuffers(); +} + +static void +reshape(int width, int height) +{ +	win_width = width; +	win_height = height; +	glViewport(0, 0, width, height); + +	glMatrixMode(GL_PROJECTION); +	glLoadIdentity(); +	glOrtho(0, win_width, 0, win_height, 0.0, -1.0); + +	glMatrixMode(GL_MODELVIEW); +	glLoadIdentity(); +	glTranslatef(.25, .25, 0); +} + +static void key( unsigned char key, int x, int y ) +{ +	(void) x; +	(void) y; + +	switch (key) { +	case 27: /* esc */ +		exit(0); +		break; +	} + +	glutPostRedisplay(); +} + +static void +init(void) +{ +} + +int +main(int argc, char *argv[]) +{ +	win_width = 200; +	win_height = 200; + +	glutInit(&argc, argv); +	glutInitWindowPosition(0, 0); +	glutInitWindowSize(win_width, win_height); +	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); +	glutCreateWindow(argv[0]); +	glutReshapeFunc(reshape); +	glutKeyboardFunc(key); +	glutDisplayFunc(display); + +	init(); + +	glutMainLoop(); +	return 0; +} diff --git a/progs/tests/unfilledclip.c b/progs/tests/unfilledclip.c new file mode 100644 index 0000000000..f25e52616a --- /dev/null +++ b/progs/tests/unfilledclip.c @@ -0,0 +1,205 @@ +/* + * Copyright © 2008 Intel Corporation + * + * 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 + * 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. + * + * Authors: + *    Eric Anholt <eric@anholt.net> + * + */ + +#include <stdlib.h> +#include <GL/glut.h> + +static int win_width, win_height; + +static void +line(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) +{ +	glBegin(GL_LINES); +	glVertex2f(x1, y1); +	glVertex2f(x2, y2); +	glEnd(); +} + +static void +line3(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2) +{ +	glBegin(GL_LINES); +	glVertex3f(x1, y1, z1); +	glVertex3f(x2, y2, z2); +	glEnd(); +} + +static void +display(void) +{ +	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + +	glClearColor(0.0, 0.0, 0.0, 0.0); +	glClear(GL_COLOR_BUFFER_BIT); + +	glColor3f(1.0, 0.0, 0.0); +	/* clipped along xmin */ +	glBegin(GL_TRIANGLES); +	glVertex2f(-20, win_height / 2 - 20); +	glVertex2f(20, win_height / 2); +	glVertex2f(-20, win_height / 2 + 20); +	glEnd(); + +	glColor3f(0.0, 1.0, 0.0); +	/* clipped along ymax */ +	glBegin(GL_TRIANGLES); +	glVertex2f(win_height / 2 - 20, win_height + 20); +	glVertex2f(win_height / 2,      win_height - 20); +	glVertex2f(win_height / 2 + 20, win_height + 20); +	glEnd(); + +	glColor3f(0.0, 0.0, 1.0); +	/* clipped along xmax */ +	glBegin(GL_TRIANGLES); +	glVertex2f(win_height + 20, win_height / 2 - 20); +	glVertex2f(win_height - 20, win_height / 2); +	glVertex2f(win_height + 20, win_height / 2 + 20); +	glEnd(); + +	glColor3f(1.0, 1.0, 1.0); +	/* clipped along ymin */ +	glBegin(GL_TRIANGLES); +	glVertex2f(win_height / 2 - 20, -20); +	glVertex2f(win_height / 2,       20); +	glVertex2f(win_height / 2 + 20, -20); +	glEnd(); + +	/* clipped along near */ +	glColor3f(1.0, 0.0, 1.0); +	glBegin(GL_TRIANGLES); +	glVertex3f(win_width / 2 - 20, win_height / 2 - 20,  0.5); +	glVertex3f(win_width / 2 - 40, win_height / 2,      -0.5); +	glVertex3f(win_width / 2 - 20, win_height / 2 + 20,  0.5); +	glEnd(); + +	/* clipped along far */ +	glColor3f(0.0, 1.0, 1.0); +	glBegin(GL_TRIANGLES); +	glVertex3f(win_width / 2 + 20, win_height / 2 - 20, 0.5); +	glVertex3f(win_width / 2 + 40, win_height / 2,      1.5); +	glVertex3f(win_width / 2 + 20, win_height / 2 + 20, 0.5); +	glEnd(); + +	/* entirely clipped along near/far */ +	glColor3f(.5, .5, .5); +	glBegin(GL_TRIANGLES); +	glVertex3f(win_width / 2 - 20, win_height / 2 + 20, -0.5); +	glVertex3f(win_width / 2,      win_height / 2 + 40, -0.5); +	glVertex3f(win_width / 2 + 20, win_height / 2 + 20, -0.5); +	glEnd(); + +	glBegin(GL_TRIANGLES); +	glVertex3f(win_width / 2 - 20, win_height / 2 - 20, 1.5); +	glVertex3f(win_width / 2,      win_height / 2 - 40, 1.5); +	glVertex3f(win_width / 2 + 20, win_height / 2 - 20, 1.5); +	glEnd(); + +	glColor3f(.5, .5, .5); +	line3(win_width / 2, win_height / 2 - 20, 1.5, +	      win_width / 2, win_height / 2 + 20, 1.5); + +	glColor3f(1.0, 1.0, 0.0); +	/* clipped along both x and y limits */ +	glBegin(GL_TRIANGLES); /* xmin, ymin */ +	glVertex2f(-5, 20); +	glVertex2f(20, 20); +	glVertex2f(20, -5); +	glEnd(); +	glBegin(GL_TRIANGLES); /* xmin, ymax */ +	glVertex2f(-5, win_height - 20); +	glVertex2f(20, win_height - 20); +	glVertex2f(20, win_height + 5); +	glEnd(); +	glBegin(GL_TRIANGLES); /* xmax, ymax */ +	glVertex2f(win_width - 20, win_height + 5); +	glVertex2f(win_width - 20, win_height - 20); +	glVertex2f(win_width + 5,  win_height - 20); +	glEnd(); +	glBegin(GL_TRIANGLES); /* xmax, ymin */ +	glVertex2f(win_width + 5, 20); +	glVertex2f(win_width - 20, 20); +	glVertex2f(win_width - 20, -5); +	glEnd(); + +	glutSwapBuffers(); +} + +static void +reshape(int width, int height) +{ +	win_width = width; +	win_height = height; +	glViewport(0, 0, width, height); + +	glMatrixMode(GL_PROJECTION); +	glLoadIdentity(); +	glOrtho(0, win_width, 0, win_height, 0.0, -1.0); + +	glMatrixMode(GL_MODELVIEW); +	glLoadIdentity(); +	glTranslatef(.25, .25, 0); +} + +static void key( unsigned char key, int x, int y ) +{ +	(void) x; +	(void) y; + +	switch (key) { +	case 27: /* esc */ +		exit(0); +		break; +	} + +	glutPostRedisplay(); +} + +static void +init(void) +{ +} + +int +main(int argc, char *argv[]) +{ +	win_width = 200; +	win_height = 200; + +	glutInit(&argc, argv); +	glutInitWindowPosition(0, 0); +	glutInitWindowSize(win_width, win_height); +	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); +	glutCreateWindow(argv[0]); +	glutReshapeFunc(reshape); +	glutKeyboardFunc(key); +	glutDisplayFunc(display); + +	init(); + +	glutMainLoop(); +	return 0; +} diff --git a/progs/xdemos/glthreads.c b/progs/xdemos/glthreads.c index 989697fbca..6c7029b6ec 100644 --- a/progs/xdemos/glthreads.c +++ b/progs/xdemos/glthreads.c @@ -505,7 +505,7 @@ main(int argc, char *argv[])     for (i = 0; i < numThreads; i++) {        pthread_create(&WinThreads[i].Thread, NULL, thread_function,                       (void*) &WinThreads[i]); -      printf("glthreads: Created thread %u\n", (unsigned int) WinThreads[i].Thread); +      printf("glthreads: Created thread %p\n", WinThreads[i].Thread);     }     if (MultiDisplays) diff --git a/progs/xdemos/ipc.c b/progs/xdemos/ipc.c index fa52b09076..c872d1641a 100644 --- a/progs/xdemos/ipc.c +++ b/progs/xdemos/ipc.c @@ -27,12 +27,12 @@  #include <assert.h>  #include <stdio.h>  #include <string.h> +#include <sys/types.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" diff --git a/src/glx/x11/Makefile b/src/glx/x11/Makefile index 3366f005eb..8fa3700a04 100644 --- a/src/glx/x11/Makefile +++ b/src/glx/x11/Makefile @@ -80,8 +80,8 @@ depend: $(SOURCES) $(MESA_GLAPI_SOURCES) $(MESA_ASM_API) Makefile  tags:  	etags `find . -name \*.[ch]` `find $(TOP)/include` -# Dummy install target -install: +install: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) +	make -C $(TOP)/src/mesa install-libgl  # Remove .o and backup files  clean: diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index dab454e8e3..514c082f6c 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -24,7 +24,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  **************************************************************************/ -/* $XFree86: xc/lib/GL/dri/dri_glx.c,v 1.14 2003/07/16 00:54:00 dawes Exp $ */  /*   * Authors: @@ -39,15 +38,20 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #include <X11/Xlibint.h>  #include <X11/extensions/Xext.h>  #include <X11/extensions/extutil.h> +#include <X11/extensions/Xfixes.h> +#include <X11/extensions/Xdamage.h>  #include "glheader.h"  #include "glxclient.h"  #include "xf86dri.h"  #include "sarea.h"  #include <stdio.h>  #include <dlfcn.h> -#include "dri_glx.h"  #include <sys/types.h>  #include <stdarg.h> +#include "glcontextmodes.h" +#include <sys/mman.h> +#include "xf86drm.h" +  #ifndef RTLD_NOW  #define RTLD_NOW 0 @@ -56,19 +60,31 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #define RTLD_GLOBAL 0  #endif +typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate; +typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate; + +struct __GLXDRIdisplayPrivateRec { +    __GLXDRIdisplay base; + +    /* +    ** XFree86-DRI version information +    */ +    int driMajor; +    int driMinor; +    int driPatch; +}; + +struct __GLXDRIcontextPrivateRec { +    __GLXDRIcontext base; +    __DRIcontext driContext; +    XID hwContextID; +};  #ifndef DEFAULT_DRIVER_DIR  /* this is normally defined in Mesa/configs/default with DRI_DRIVER_SEARCH_PATH */  #define DEFAULT_DRIVER_DIR "/usr/X11R6/lib/modules/dri"  #endif -static __DRIdriver *Drivers = NULL; - - -/* - * printf wrappers - */ -  static void InfoMessageF(const char *f, ...)  {      va_list args; @@ -100,68 +116,6 @@ static void ErrorMessageF(const char *f, ...)  /** - * Extract the ith directory path out of a colon-separated list of paths.  No - * more than \c dirLen characters, including the terminating \c NUL, will be - * written to \c dir. - * - * \param index  Index of path to extract (starting at zero) - * \param paths  The colon-separated list of paths - * \param dirLen Maximum length of result to store in \c dir - * \param dir    Buffer to hold the extracted directory path - * - * \returns - * The number of characters that would have been written to \c dir had there - * been enough room.  This does not include the terminating \c NUL.  When - * extraction fails, zero will be returned. - *  - * \todo - * It seems like this function could be rewritten to use \c strchr. - */ -static size_t -ExtractDir(int index, const char *paths, int dirLen, char *dir) -{ -   int i, len; -   const char *start, *end; - -   /* find ith colon */ -   start = paths; -   i = 0; -   while (i < index) { -      if (*start == ':') { -         i++; -         start++; -      } -      else if (*start == 0) { -         /* end of string and couldn't find ith colon */ -         dir[0] = 0; -         return 0; -      } -      else { -         start++; -      } -   } - -   while (*start == ':') -      start++; - -   /* find next colon, or end of string */ -   end = start + 1; -   while (*end != ':' && *end != 0) { -      end++; -   } - -   /* copy string between <start> and <end> into result string */ -   len = end - start; -   if (len > dirLen - 1) -      len = dirLen - 1; -   strncpy(dir, start, len); -   dir[len] = 0; - -   return( end - start ); -} - - -/**   * Versioned name of the expected \c __driCreateNewScreen function.   *    * The version of the last incompatible loader/driver inteface change is @@ -183,106 +137,64 @@ static const char createNewScreenName[] = __DRI_CREATE_NEW_SCREEN_STRING;   * \returns   * A handle from \c dlopen, or \c NULL if driver file not found.   */ -static __DRIdriver *OpenDriver(const char *driverName) +static void *OpenDriver(const char *driverName)  { -   void *glhandle = NULL; -   char *libPaths = NULL; -   char libDir[1000]; -   int i; -   __DRIdriver *driver; - -   /* First, search Drivers list to see if we've already opened this driver */ -   for (driver = Drivers; driver; driver = driver->next) { -      if (strcmp(driver->name, driverName) == 0) { -         /* found it, increment library refcount & return */ -         dlopen(driver->libpath, RTLD_NOW | RTLD_GLOBAL); -         return driver; -      } -   } +   void *glhandle, *handle; +   const char *libPaths, *p, *next; +   char realDriverName[200]; +   int len;     /* Attempt to make sure libGL symbols will be visible to the driver */     glhandle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL); +   libPaths = NULL;     if (geteuid() == getuid()) {        /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */        libPaths = getenv("LIBGL_DRIVERS_PATH");        if (!libPaths)           libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */     } -   if (!libPaths) -      libPaths = DEFAULT_DRIVER_DIR; +   if (libPaths == NULL) +       libPaths = DEFAULT_DRIVER_DIR; -   for ( i = 0 ; ExtractDir(i, libPaths, 1000, libDir) != 0 ; i++ ) { -      char realDriverName[200]; -      void *handle = NULL; +   handle = NULL; +   for (p = libPaths; *p; p = next) { +       next = strchr(p, ':'); +       if (next == NULL) { +	   len = strlen(p); +	   next = p + len; +       } else { +	   len = next - p; +	   next++; +       } -       -      /* If TLS support is enabled, try to open the TLS version of the driver -       * binary first.  If that fails, try the non-TLS version. -       */  #ifdef GLX_USE_TLS -      snprintf(realDriverName, 200, "%s/tls/%s_dri.so", libDir, driverName); +      snprintf(realDriverName, sizeof realDriverName, +	       "%.*s/tls/%s_dri.so", len, p, driverName);        InfoMessageF("OpenDriver: trying %s\n", realDriverName);        handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);  #endif        if ( handle == NULL ) { -	 snprintf(realDriverName, 200, "%s/%s_dri.so", libDir, driverName); +	 snprintf(realDriverName, sizeof realDriverName, +		  "%.*s/%s_dri.so", len, p, driverName);  	 InfoMessageF("OpenDriver: trying %s\n", realDriverName);  	 handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);        } -      if ( handle != NULL ) { -         /* allocate __DRIdriver struct */ -         driver = (__DRIdriver *) Xmalloc(sizeof(__DRIdriver)); -         if (!driver) -            break; /* out of memory! */ -         /* init the struct */ -         driver->name = __glXstrdup(driverName); -         driver->libpath = __glXstrdup(realDriverName); -         if (!driver->name || !driver->libpath) { -            if (driver->name) -               Xfree(driver->name); -            if (driver->libpath) -               Xfree(driver->libpath); -            Xfree(driver); -            driver = NULL; -            break; /* out of memory! */ -         } - -         driver->createNewScreenFunc = (PFNCREATENEWSCREENFUNC) -            dlsym(handle, createNewScreenName); - -         if ( driver->createNewScreenFunc == NULL ) { -            /* If the driver doesn't have this symbol then something's -             * really, really wrong. -             */ -            ErrorMessageF("%s not defined in %s_dri.so!\n" -			  "Your driver may be too old for this libGL.\n", -			  createNewScreenName, driverName); -            Xfree(driver); -            driver = NULL; -            dlclose(handle); -            continue; -         } -         driver->handle = handle; -         /* put at head of linked list */ -         driver->next = Drivers; -         Drivers = driver; -         break; -      } -      else { +      if ( handle != NULL ) +	  break; +      else  	 ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror()); -      }     } -   if (!driver) +   if (!handle)        ErrorMessageF("unable to load driver: %s_dri.so\n", driverName);     if (glhandle)        dlclose(glhandle); -   return driver; +   return handle;  } @@ -326,11 +238,12 @@ static Bool GetDriverName(Display *dpy, int scrNum, char **driverName)   * Given a display pointer and screen number, return a __DRIdriver handle.   * Return NULL if anything goes wrong.   */ -__DRIdriver *driGetDriver(Display *dpy, int scrNum) +static void *driGetDriver(Display *dpy, int scrNum)  {     char *driverName; +   void *ret; +     if (GetDriverName(dpy, scrNum, &driverName)) { -      __DRIdriver *ret;        ret = OpenDriver(driverName);        if (driverName)       	 Xfree(driverName); @@ -339,7 +252,6 @@ __DRIdriver *driGetDriver(Display *dpy, int scrNum)     return NULL;  } -  /*   * Exported function for querying the DRI driver for a given screen.   * @@ -376,71 +288,569 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) {   * Note: The driver remains opened after this function returns.   */  PUBLIC const char *glXGetDriverConfig (const char *driverName) { -   __DRIdriver *driver = OpenDriver (driverName); -   if (driver) -      return dlsym (driver->handle, "__driConfigOptions"); +   void *handle = OpenDriver (driverName); +   if (handle) +      return dlsym (handle, "__driConfigOptions");     else        return NULL;  } +static void +filter_modes( __GLcontextModes ** server_modes, +	      const __GLcontextModes * driver_modes ) +{ +    __GLcontextModes * m; +    __GLcontextModes ** prev_next; +    const __GLcontextModes * check; -/* Called from __glXFreeDisplayPrivate. +    if (driver_modes == NULL) { +	fprintf(stderr, "libGL warning: 3D driver returned no fbconfigs.\n"); +	return; +    } + +    /* For each mode in server_modes, check to see if a matching mode exists +     * in driver_modes.  If not, then the mode is not available. +     */ + +    prev_next = server_modes; +    for ( m = *prev_next ; m != NULL ; m = *prev_next ) { +	GLboolean do_delete = GL_TRUE; + +	for ( check = driver_modes ; check != NULL ; check = check->next ) { +	    if ( _gl_context_modes_are_same( m, check ) ) { +		do_delete = GL_FALSE; +		break; +	    } +	} + +	/* The 3D has to support all the modes that match the GLX visuals +	 * sent from the X server. +	 */ +	if ( do_delete && (m->visualID != 0) ) { +	    do_delete = GL_FALSE; + +	    /* don't warn for this visual (Novell #247471 / X.Org #6689) */ +	    if (m->visualRating != GLX_NON_CONFORMANT_CONFIG) { +		fprintf(stderr, "libGL warning: 3D driver claims to not " +			"support visual 0x%02x\n", m->visualID); +	    } +	} + +	if ( do_delete ) { +	    *prev_next = m->next; + +	    m->next = NULL; +	    _gl_context_modes_destroy( m ); +	} +	else { +	    prev_next = & m->next; +	} +    } +} + +#ifdef XDAMAGE_1_1_INTERFACE +static GLboolean has_damage_post(Display *dpy) +{ +    static GLboolean inited = GL_FALSE; +    static GLboolean has_damage; + +    if (!inited) { +	int major, minor; + +	if (XDamageQueryVersion(dpy, &major, &minor) && +	    major == 1 && minor >= 1) +	{ +	    has_damage = GL_TRUE; +	} else { +	    has_damage = GL_FALSE; +	} +	inited = GL_TRUE; +    } + +    return has_damage; +} +#endif /* XDAMAGE_1_1_INTERFACE */ + +static void __glXReportDamage(__DRIdrawable *driDraw, +			      int x, int y, +			      drm_clip_rect_t *rects, int num_rects, +			      GLboolean front_buffer) +{ +#ifdef XDAMAGE_1_1_INTERFACE +    XRectangle *xrects; +    XserverRegion region; +    int i; +    int x_off, y_off; +    __GLXDRIdrawable *glxDraw = +	containerOf(driDraw, __GLXDRIdrawable, driDrawable); +    __GLXscreenConfigs *psc = glxDraw->psc; +    Display *dpy = psc->dpy; +    Drawable drawable; + +    if (!has_damage_post(dpy)) +	return; + +    if (front_buffer) { +	x_off = x; +	y_off = y; +	drawable = RootWindow(dpy, psc->scr); +    } else{ +	x_off = 0; +	y_off = 0; +	drawable = glxDraw->drawable; +    } + +    xrects = malloc(sizeof(XRectangle) * num_rects); +    if (xrects == NULL) +	return; + +    for (i = 0; i < num_rects; i++) { +	xrects[i].x = rects[i].x1 + x_off; +	xrects[i].y = rects[i].y1 + y_off; +	xrects[i].width = rects[i].x2 - rects[i].x1; +	xrects[i].height = rects[i].y2 - rects[i].y1; +    } +    region = XFixesCreateRegion(dpy, xrects, num_rects); +    free(xrects); +    XDamageAdd(dpy, drawable, region); +    XFixesDestroyRegion(dpy, region); +#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) +{ +    __GLXDRIdrawable *glxDraw = +	containerOf(drawable, __GLXDRIdrawable, 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 __DRIcontextModesExtension contextModesExtension = { +    { __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION }, +    _gl_context_modes_create, +    _gl_context_modes_destroy, +}; + +static const __DRIsystemTimeExtension systemTimeExtension = { +    { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION }, +    __glXGetUST, +    __driGetMscRateOML, +}; + +static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = { +    { __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION }, +    __glXDRIGetDrawableInfo +}; + +static const __DRIdamageExtension damageExtension = { +    { __DRI_DAMAGE, __DRI_DAMAGE_VERSION }, +    __glXReportDamage, +}; + +static const __DRIextension *loader_extensions[] = { +    &contextModesExtension.base, +    &systemTimeExtension.base, +    &getDrawableInfoExtension.base, +    &damageExtension.base, +    NULL +}; + + +/** + * Perform the required libGL-side initialization and call the client-side + * driver's \c __driCreateNewScreen function. + *  + * \param dpy    Display pointer. + * \param scrn   Screen number on the display. + * \param psc    DRI screen information. + * \param driDpy DRI display information. + * \param createNewScreen  Pointer to the client-side driver's + *               \c __driCreateNewScreen function. + * \returns A pointer to the \c __DRIscreenPrivate structure returned by + *          the client-side driver on success, or \c NULL on failure. + *  + * \todo This function needs to be modified to remove context-modes from the + *       list stored in the \c __GLXscreenConfigsRec to match the list + *       returned by the client-side driver.   */ -static void driDestroyDisplay(Display *dpy, void *private) +static void * +CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, +		    __GLXDRIdisplayPrivate * driDpy, +		    PFNCREATENEWSCREENFUNC createNewScreen)  { -    __DRIdisplayPrivate *pdpyp = (__DRIdisplayPrivate *)private; +    void *psp = NULL; +#ifndef GLX_USE_APPLEGL +    drm_handle_t hSAREA; +    drmAddress pSAREA = MAP_FAILED; +    char *BusID; +    __DRIversion   ddx_version; +    __DRIversion   dri_version; +    __DRIversion   drm_version; +    __DRIframebuffer  framebuffer; +    int   fd = -1; +    int   status; +    const char * err_msg; +    const char * err_extra; + +    dri_version.major = driDpy->driMajor; +    dri_version.minor = driDpy->driMinor; +    dri_version.patch = driDpy->driPatch; + + +    err_msg = "XF86DRIOpenConnection"; +    err_extra = NULL; + +    framebuffer.base = MAP_FAILED; +    framebuffer.dev_priv = NULL; + +    if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) { +        int newlyopened; +	fd = drmOpenOnce(NULL,BusID, &newlyopened); +	Xfree(BusID); /* No longer needed */ -    if (pdpyp) { -        const int numScreens = ScreenCount(dpy); -        int i; -        for (i = 0; i < numScreens; i++) { -	   if (pdpyp->libraryHandles[i]) { -	      __DRIdriver *driver, *prev; +	err_msg = "open DRM"; +	err_extra = strerror( -fd ); -	      /* Remove driver from Drivers list */ -	      for (prev = NULL, driver = Drivers; driver; -		   prev = driver, driver = driver->next) { -		 if (driver->handle == pdpyp->libraryHandles[i]) { -		    if (prev) -		       prev->next = driver->next; -		    else -		       Drivers = driver->next; +	if (fd >= 0) { +	    drm_magic_t magic; -		    Xfree(driver->name); -		    Xfree(driver->libpath); -		    Xfree(driver); -		    break; -		 } -	      } +	    err_msg = "drmGetMagic"; +	    err_extra = NULL; -	      dlclose(pdpyp->libraryHandles[i]); -	   } -        } -        Xfree(pdpyp->libraryHandles); -	Xfree(pdpyp); +	    if (!drmGetMagic(fd, &magic)) { +		drmVersionPtr version = drmGetVersion(fd); +		if (version) { +		    drm_version.major = version->version_major; +		    drm_version.minor = version->version_minor; +		    drm_version.patch = version->version_patchlevel; +		    drmFreeVersion(version); +		} +		else { +		    drm_version.major = -1; +		    drm_version.minor = -1; +		    drm_version.patch = -1; +		} + +		err_msg = "XF86DRIAuthConnection"; +		if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) { +		    char *driverName; + +		    /* +		     * Get device name (like "tdfx") and the ddx version +		     * numbers.  We'll check the version in each DRI driver's +		     * "createNewScreen" function. +		     */ +		    err_msg = "XF86DRIGetClientDriverName"; +		    if (XF86DRIGetClientDriverName(dpy, scrn, +						   &ddx_version.major, +						   &ddx_version.minor, +						   &ddx_version.patch, +						   &driverName)) { +			drm_handle_t  hFB; +			int        junk; + +			/* No longer needed. */ +			Xfree( driverName ); + + +			/* +			 * Get device-specific info.  pDevPriv will point to a struct +			 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) +			 * that has information about the screen size, depth, pitch, +			 * ancilliary buffers, DRM mmap handles, etc. +			 */ +			err_msg = "XF86DRIGetDeviceInfo"; +			if (XF86DRIGetDeviceInfo(dpy, scrn, +						 &hFB, +						 &junk, +						 &framebuffer.size, +						 &framebuffer.stride, +						 &framebuffer.dev_priv_size, +						 &framebuffer.dev_priv)) { +			    framebuffer.width = DisplayWidth(dpy, scrn); +			    framebuffer.height = DisplayHeight(dpy, scrn); + +			    /* +			     * Map the framebuffer region. +			     */ +			    status = drmMap(fd, hFB, framebuffer.size,  +					    (drmAddressPtr)&framebuffer.base); + +			    err_msg = "drmMap of framebuffer"; +			    err_extra = strerror( -status ); + +			    if ( status == 0 ) { +				/* +				 * Map the SAREA region.  Further mmap regions +				 * may be setup in each DRI driver's +				 * "createNewScreen" function. +				 */ +				status = drmMap(fd, hSAREA, SAREA_MAX,  +						&pSAREA); + +				err_msg = "drmMap of sarea"; +				err_extra = strerror( -status ); + +				if ( status == 0 ) { +				    __GLcontextModes * driver_modes = NULL; + +				    err_msg = "InitDriver"; +				    err_extra = NULL; +				    psp = (*createNewScreen)(scrn, +							     &psc->__driScreen, +							     & ddx_version, +							     & dri_version, +							     & drm_version, +							     & framebuffer, +							     pSAREA, +							     fd, +							     loader_extensions, +							     & driver_modes ); + +				    filter_modes(&psc->configs, driver_modes); +				    filter_modes(&psc->visuals, driver_modes); +				    _gl_context_modes_destroy(driver_modes); +				} +			    } +			} +		    } +		} +	    } +	}      } + +    if ( psp == NULL ) { +	if ( pSAREA != MAP_FAILED ) { +	    (void)drmUnmap(pSAREA, SAREA_MAX); +	} + +	if ( framebuffer.base != MAP_FAILED ) { +	    (void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size); +	} + +	if ( framebuffer.dev_priv != NULL ) { +	    Xfree(framebuffer.dev_priv); +	} + +	if ( fd >= 0 ) { +	    (void)drmCloseOnce(fd); +	} + +	(void)XF86DRICloseConnection(dpy, scrn); + +	if ( err_extra != NULL ) { +	    fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg, +		    err_extra); +	} +	else { +	    fprintf(stderr, "libGL error: %s failed\n", err_msg ); +	} + +        fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n"); +    } +#endif /* !GLX_USE_APPLEGL */ + +    return psp;  } +static void driDestroyContext(__GLXDRIcontext *context, +			      __GLXscreenConfigs *psc, Display *dpy) +{ +    __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; +			 +    (*pcp->driContext.destroyContext)(&pcp->driContext); + +    XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID); +} + +static Bool driBindContext(__GLXDRIcontext *context, +			   __GLXDRIdrawable *draw, __GLXDRIdrawable *read) +{ +    __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; + +    return (*pcp->driContext.bindContext)(&pcp->driContext, +					  &draw->driDrawable, +					  &read->driDrawable); +} + +static void driUnbindContext(__GLXDRIcontext *context) +{ +    __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; + +    (*pcp->driContext.unbindContext)(&pcp->driContext); +} + +static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc, +					 const __GLcontextModes *mode, +					 GLXContext gc, +					 GLXContext shareList, int renderType) +{ +    __GLXDRIcontextPrivate *pcp, *pcp_shared; +    drm_context_t hwContext; +    __DRIcontext *shared = NULL; + +    if (psc && psc->driScreen) { +	if (shareList) { +	    pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext; +	    shared = &pcp_shared->driContext; +	} + +	pcp = Xmalloc(sizeof *pcp); +	if (pcp == NULL) +	    return NULL; + +	if (!XF86DRICreateContextWithConfig(psc->dpy, psc->scr, +					    mode->visualID, +					    &pcp->hwContextID, &hwContext)) { +	    Xfree(pcp); +	    return NULL; +	} + +	pcp->driContext.private =  +	    (*psc->__driScreen.createNewContext)(&psc->__driScreen, +						 mode, renderType, +						 shared, +						 hwContext, +						 &pcp->driContext); +	if (pcp->driContext.private == NULL) { +	    XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID); +	    Xfree(pcp); +	    return NULL; +	} + +	pcp->base.destroyContext = driDestroyContext; +	pcp->base.bindContext = driBindContext; +	pcp->base.unbindContext = driUnbindContext; + +	return &pcp->base; +    } + +    return NULL; +} + +static void driDestroyDrawable(__GLXDRIdrawable *pdraw) +{ +    __GLXscreenConfigs *psc = pdraw->psc; + +    (*pdraw->driDrawable.destroyDrawable)(&pdraw->driDrawable); +    XF86DRIDestroyDrawable(psc->dpy, psc->scr, pdraw->drawable); +    Xfree(pdraw); +} + +static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc, +					   GLXDrawable drawable, +					   GLXContext gc) +{ +    __GLXDRIdrawable *pdraw; +    drm_drawable_t hwDrawable; +    void *empty_attribute_list = NULL; + +    pdraw = Xmalloc(sizeof(*pdraw)); +    if (!pdraw) +	return NULL; + +    pdraw->drawable = drawable; +    pdraw->psc = psc; + +    if (!XF86DRICreateDrawable(psc->dpy, psc->scr, drawable, &hwDrawable)) +	return NULL; + +    /* Create a new drawable */ +    pdraw->driDrawable.private = +	(*psc->__driScreen.createNewDrawable)(&psc->__driScreen, +					      gc->mode, +					      &pdraw->driDrawable, +					      hwDrawable, +					      GLX_WINDOW_BIT, +					      0, +					      empty_attribute_list); + +    if (!pdraw->driDrawable.private) { +	XF86DRIDestroyDrawable(psc->dpy, psc->scr, drawable); +	Xfree(pdraw); +	return NULL; +    } + +    pdraw->destroyDrawable = driDestroyDrawable; + +    return pdraw; +} + +static void driDestroyScreen(__GLXscreenConfigs *psc) +{ +    /* Free the direct rendering per screen data */ +    if (psc->__driScreen.private) +	(*psc->__driScreen.destroyScreen)(&psc->__driScreen); +    psc->__driScreen.private = NULL; +    if (psc->driver) +	dlclose(psc->driver); +} + +static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen, +				       __GLXdisplayPrivate *priv) +{ +    PFNCREATENEWSCREENFUNC createNewScreen; +    __GLXDRIdisplayPrivate *pdp; +    __GLXDRIscreen *psp; + +    psp = Xmalloc(sizeof *psp); +    if (psp == NULL) +	return NULL; + +    /* Initialize per screen dynamic client GLX extensions */ +    psc->ext_list_first_time = GL_TRUE; + +    psc->driver = driGetDriver(priv->dpy, screen); +    createNewScreen = dlsym(psc->driver, createNewScreenName); +    if (createNewScreen == NULL) +	return NULL; + +    pdp = (__GLXDRIdisplayPrivate *) priv->driDisplay; +    psc->__driScreen.private = +	CallCreateNewScreen(psc->dpy, screen, psc, pdp, createNewScreen); +    if (psc->__driScreen.private != NULL) +	__glXScrEnableDRIExtension(psc); + +    psp->destroyScreen = driDestroyScreen; +    psp->createContext = driCreateContext; +    psp->createDrawable = driCreateDrawable; + +    return psp; +} + +/* Called from __glXFreeDisplayPrivate. + */ +static void driDestroyDisplay(__GLXDRIdisplay *dpy) +{ +    Xfree(dpy); +}  /*   * Allocate, initialize and return a __DRIdisplayPrivate object.   * This is called from __glXInitialize() when we are given a new   * display pointer.   */ -void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp) +_X_HIDDEN __GLXDRIdisplay *driCreateDisplay(Display *dpy)  { -    const int numScreens = ScreenCount(dpy); -    __DRIdisplayPrivate *pdpyp; +    __GLXDRIdisplayPrivate *pdpyp;      int eventBase, errorBase;      int major, minor, patch; -    int scrn; - -    /* Initialize these fields to NULL in case we fail. -     * If we don't do this we may later get segfaults trying to free random -     * addresses when the display is closed. -     */ -    pdisp->private = NULL; -    pdisp->destroyDisplay = NULL;      if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) {  	return NULL; @@ -450,7 +860,7 @@ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp)  	return NULL;      } -    pdpyp = (__DRIdisplayPrivate *)Xmalloc(sizeof(__DRIdisplayPrivate)); +    pdpyp = Xmalloc(sizeof *pdpyp);      if (!pdpyp) {  	return NULL;      } @@ -459,41 +869,10 @@ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp)      pdpyp->driMinor = minor;      pdpyp->driPatch = patch; -    pdisp->destroyDisplay = driDestroyDisplay; - -    /* allocate array of pointers to createNewScreen funcs */ -    pdisp->createNewScreen = (PFNCREATENEWSCREENFUNC *) -      Xmalloc(numScreens * sizeof(void *)); -    if (!pdisp->createNewScreen) { -       Xfree(pdpyp); -       return NULL; -    } - -    /* allocate array of library handles */ -    pdpyp->libraryHandles = (void **) Xmalloc(numScreens * sizeof(void*)); -    if (!pdpyp->libraryHandles) { -       Xfree(pdisp->createNewScreen); -       Xfree(pdpyp); -       return NULL; -    } - -    /* dynamically discover DRI drivers for all screens, saving each -     * driver's "__driCreateScreen" function pointer.  That's the bootstrap -     * entrypoint for all DRI drivers. -     */ -    for (scrn = 0; scrn < numScreens; scrn++) { -        __DRIdriver *driver = driGetDriver(dpy, scrn); -        if (driver) { -           pdisp->createNewScreen[scrn] = driver->createNewScreenFunc; -           pdpyp->libraryHandles[scrn] = driver->handle; -        } -        else { -           pdisp->createNewScreen[scrn] = NULL; -           pdpyp->libraryHandles[scrn] = NULL; -        } -    } +    pdpyp->base.destroyDisplay = driDestroyDisplay; +    pdpyp->base.createScreen = driCreateScreen; -    return (void *)pdpyp; +    return &pdpyp->base;  }  #endif /* GLX_DIRECT_RENDERING */ diff --git a/src/glx/x11/dri_glx.h b/src/glx/x11/dri_glx.h deleted file mode 100644 index 75561685c8..0000000000 --- a/src/glx/x11/dri_glx.h +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************************************** - -Copyright 1998-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, sub license, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -IN NO EVENT SHALL 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: - *   Kevin E. Martin <kevin@precisioninsight.com> - *   Brian Paul <brian@precisioninsight.com> - * - */ - -#ifndef _DRI_GLX_H_ -#define _DRI_GLX_H_ - -#ifdef GLX_DIRECT_RENDERING - -struct __DRIdisplayPrivateRec { -    /* -    ** XFree86-DRI version information -    */ -    int driMajor; -    int driMinor; -    int driPatch; - -    /* -    ** Array of library handles [indexed by screen number] -    */ -    void **libraryHandles; -}; - -typedef struct __DRIdisplayPrivateRec  __DRIdisplayPrivate; -typedef struct __DRIscreenPrivateRec   __DRIscreenPrivate; -typedef struct __DRIvisualPrivateRec   __DRIvisualPrivate; -typedef struct __DRIcontextPrivateRec  __DRIcontextPrivate; -typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate; - -#endif -#endif /* _DRI_GLX_H_ */ diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index 002f7693a0..ea90282b08 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -92,44 +92,58 @@ typedef struct _glapi_table __GLapi;   * Display dependent methods.  This structure is initialized during the   * \c driCreateDisplay call.   */ -struct __DRIdisplayRec { +typedef struct __GLXDRIdisplayRec __GLXDRIdisplay; +typedef struct __GLXDRIscreenRec __GLXDRIscreen; +typedef struct __GLXDRIdrawableRec __GLXDRIdrawable; +typedef struct __GLXDRIcontextRec __GLXDRIcontext; + +struct __GLXDRIdisplayRec {      /**       * Method to destroy the private DRI display data.       */ -    void (*destroyDisplay)(Display *dpy, void *displayPrivate); +    void (*destroyDisplay)(__GLXDRIdisplay *display); -    /** -     * Opaque pointer to private per display direct rendering data. -     * \c NULL if direct rendering is not supported on this display. -     */ -    struct __DRIdisplayPrivateRec *private; +    __GLXDRIscreen *(*createScreen)(__GLXscreenConfigs *psc, int screen, +				    __GLXdisplayPrivate *priv); +}; -    /** -     * Array of pointers to methods to create and initialize the private DRI -     * screen data. -     */ -    PFNCREATENEWSCREENFUNC * createNewScreen; +struct __GLXDRIscreenRec { + +    void (*destroyScreen)(__GLXscreenConfigs *psc); + +    __GLXDRIcontext *(*createContext)(__GLXscreenConfigs *psc, +				      const __GLcontextModes *mode, +				      GLXContext gc, +				      GLXContext shareList, int renderType); +	 +    __GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc, +					GLXDrawable drawable, +					GLXContext gc);  }; +struct __GLXDRIcontextRec { +    void (*destroyContext)(__GLXDRIcontext *context, __GLXscreenConfigs *psc, +			   Display *dpy); +    Bool (*bindContext)(__GLXDRIcontext *context, +			__GLXDRIdrawable *pdraw, +			__GLXDRIdrawable *pread); +     +    void (*unbindContext)(__GLXDRIcontext *context); +}; -/* -** We keep a linked list of these structures, one per DRI device driver. -*/ -struct __DRIdriverRec { -   const char *name; -   const char *libpath; -   void *handle; -   PFNCREATENEWSCREENFUNC createNewScreenFunc; -   struct __DRIdriverRec *next; +struct __GLXDRIdrawableRec { +    void (*destroyDrawable)(__GLXDRIdrawable *drawable); + +    XID drawable; +    __GLXscreenConfigs *psc; +    __DRIdrawable driDrawable;  };  /*  ** Function to create and DRI display data and initialize the display  ** dependent methods.  */ -extern void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp); - -extern  __DRIdriver *driGetDriver(Display *dpy, int scrNum); +extern __GLXDRIdisplay *driCreateDisplay(Display *dpy);  extern void DRI_glXUseXFont( Font font, int first, int count, int listbase ); @@ -349,15 +363,7 @@ struct __GLXcontextRec {      const __GLcontextModes * mode;  #ifdef GLX_DIRECT_RENDERING -    /** -     * Per context direct rendering interface functions and data. -     */ -    __DRIcontext driContext; - -    /** -     * XID for the server side drm_context_t -     */ -    XID hwContextID; +    __GLXDRIcontext *driContext;  #endif      /** @@ -452,10 +458,13 @@ struct __GLXscreenConfigsRec {      /**       * Per screen direct rendering interface functions and data.       */ -    __DRIscreen driScreen; +    __DRIscreen __driScreen;      __glxHashTable *drawHash;      Display *dpy;      int scr; +    void *driver; + +    __GLXDRIscreen *driScreen;  #ifdef __DRI_COPY_SUB_BUFFER      __DRIcopySubBufferExtension *copySubBuffer; @@ -545,21 +554,10 @@ struct __GLXdisplayPrivateRec {      /**       * Per display direct rendering interface functions and data.       */ -    __DRIdisplay driDisplay; +    __GLXDRIdisplay *driDisplay;  #endif  }; -#ifdef GLX_DIRECT_RENDERING - -struct __GLXdrawableRec { -    XID drawable; -    __GLXscreenConfigs *psc; -    __DRIdrawable driDrawable; -}; - -#endif - -  void __glXFreeContext(__GLXcontext*); diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index 1bcfb94030..8d0f07fd0a 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -83,7 +83,7 @@ static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr)  static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc)  {      XID draw; -    __GLXdrawable *pdraw; +    __GLXDRIdrawable *pdraw;      XWindowAttributes xwa;      int (*oldXErrorHandler)(Display *, XErrorEvent *); @@ -99,10 +99,8 @@ static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc)  	    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); +		(*pdraw->destroyDrawable)(pdraw);                  __glxHashDelete(sc->drawHash, draw); -		Xfree(pdraw);  	    }  	} while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1);      } @@ -124,12 +122,12 @@ static __DRIdrawable *  GetDRIDrawable( Display *dpy, GLXDrawable drawable, int * const scrn_num )  {      __GLXdisplayPrivate * const priv = __glXInitialize(dpy); -    __GLXdrawable * const pdraw; +    __GLXDRIdrawable * const pdraw;      const unsigned  screen_count = ScreenCount(dpy);      unsigned   i;      __GLXscreenConfigs *sc; -    if (priv == NULL || priv->driDisplay.private == NULL) +    if (priv == NULL || priv->driDisplay == NULL)  	return NULL;      for (i = 0; i < screen_count; i++) { @@ -313,9 +311,9 @@ GLXContext AllocateGLXContext( Display *dpy )      */      gc->fastImageUnpack = GL_FALSE;      gc->fillImage = __glFillImage; -    gc->isDirect = GL_FALSE;      gc->pc = gc->buf;      gc->bufEnd = gc->buf + bufSize; +    gc->isDirect = GL_FALSE;      if (__glXDebug) {  	/*  	** Set limit register so that there will be one command per packet @@ -361,6 +359,10 @@ CreateContext(Display *dpy, XVisualInfo *vis,  	      Bool use_glx_1_3, int renderType)  {      GLXContext gc; +#ifdef GLX_DIRECT_RENDERING +    int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen; +    __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); +#endif      if ( dpy == NULL )         return NULL; @@ -374,12 +376,8 @@ CreateContext(Display *dpy, XVisualInfo *vis,  	    return NULL;  #ifdef GLX_DIRECT_RENDERING -	if (allowDirect) { -	    int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen; -	    __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); +	if (allowDirect && psc->driScreen) {  	    const __GLcontextModes * mode; -	    drm_context_t hwContext; -  	    if (fbconfig == NULL) {  		mode = _gl_context_modes_find_visual(psc->visuals, vis->visualid); @@ -400,32 +398,14 @@ CreateContext(Display *dpy, XVisualInfo *vis,  		mode = fbconfig;  	    } -	    if (psc && psc->driScreen.private) { -		__DRIcontext *shared = (shareList != NULL) -		    ? &shareList->driContext : NULL; - - -		if (!XF86DRICreateContextWithConfig(dpy, psc->scr, -						    mode->visualID, -						    &gc->hwContextID, &hwContext)) -		    /* gah, handle this better */ -		    return NULL; - -		gc->driContext.private =  -		  (*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->mode = mode; -		} -		else { -		    XF86DRIDestroyContext(dpy, psc->scr, gc->hwContextID); -		} +	    gc->driContext = psc->driScreen->createContext(psc, mode, gc, +							   shareList, +							   renderType); +	    if (gc->driContext != NULL) { +		gc->screen = mode->screen; +		gc->psc = psc; +		gc->mode = mode; +		gc->isDirect = GL_TRUE;  	    }  	}  #endif @@ -442,7 +422,7 @@ CreateContext(Display *dpy, XVisualInfo *vis,  	    req->visual = vis->visualid;  	    req->screen = vis->screen;  	    req->shareList = shareList ? shareList->xid : None; -	    req->isDirect = gc->isDirect; +	    req->isDirect = gc->driContext != NULL;  	}  	else if ( use_glx_1_3 ) {  	    xGLXCreateNewContextReq *req; @@ -456,7 +436,7 @@ CreateContext(Display *dpy, XVisualInfo *vis,  	    req->screen = fbconfig->screen;  	    req->renderType = renderType;  	    req->shareList = shareList ? shareList->xid : None; -	    req->isDirect = gc->isDirect; +	    req->isDirect = gc->driContext != NULL;  	}  	else {  	    xGLXVendorPrivateWithReplyReq *vpreq; @@ -474,7 +454,7 @@ CreateContext(Display *dpy, XVisualInfo *vis,  	    req->screen = fbconfig->screen;  	    req->renderType = renderType;  	    req->shareList = shareList ? shareList->xid : None; -	    req->isDirect = gc->isDirect; +	    req->isDirect = gc->driContext != NULL;  	}  	UnlockDisplay(dpy); @@ -496,7 +476,7 @@ PUBLIC GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis,  			False, 0);  } -void __glXFreeContext(__GLXcontext *gc) +_X_HIDDEN void __glXFreeContext(__GLXcontext *gc)  {      if (gc->vendor) XFree((char *) gc->vendor);      if (gc->renderer) XFree((char *) gc->renderer); @@ -532,12 +512,9 @@ DestroyContext(Display *dpy, GLXContext gc)  #ifdef GLX_DIRECT_RENDERING      /* Destroy the direct rendering context */ -    if (gc->isDirect) { -	if (gc->driContext.private) { -	    (*gc->driContext.destroyContext)(&gc->driContext); -	    XF86DRIDestroyContext(dpy, gc->psc->scr, gc->hwContextID); -	    gc->driContext.private = NULL; -	} +    if (gc->driContext) { +	(*gc->driContext->destroyContext)(gc->driContext, gc->psc, dpy); +	gc->driContext = NULL;  	GarbageCollectDRIDrawables(dpy, gc->psc);      }  #endif @@ -619,7 +596,7 @@ PUBLIC void glXWaitGL(void)      __glXFlushRenderBuffer(gc, gc->pc);  #ifdef GLX_DIRECT_RENDERING -    if (gc->isDirect) { +    if (gc->driContext) {  /* This bit of ugliness unwraps the glFinish function */  #ifdef glFinish  #undef glFinish @@ -655,7 +632,7 @@ PUBLIC void glXWaitX(void)      __glXFlushRenderBuffer(gc, gc->pc);  #ifdef GLX_DIRECT_RENDERING -    if (gc->isDirect) { +    if (gc->driContext) {  	XSync(dpy, False);  	return;      } @@ -685,7 +662,7 @@ PUBLIC void glXUseXFont(Font font, int first, int count, int listBase)      (void) __glXFlushRenderBuffer(gc, gc->pc);  #ifdef GLX_DIRECT_RENDERING -    if (gc->isDirect) { +    if (gc->driContext) {        DRI_glXUseXFont(font, first, count, listBase);        return;      } @@ -725,7 +702,7 @@ PUBLIC void glXCopyContext(Display *dpy, GLXContext source,      }  #ifdef GLX_DIRECT_RENDERING -    if (gc->isDirect) { +    if (gc->driContext) {  	/* NOT_DONE: This does not work yet */      }  #endif @@ -797,7 +774,7 @@ PUBLIC Bool glXIsDirect(Display *dpy, GLXContext gc)      if (!gc) {  	return GL_FALSE;  #ifdef GLX_DIRECT_RENDERING -    } else if (gc->isDirect) { +    } else if (gc->driContext) {  	return GL_TRUE;  #endif      } @@ -1335,7 +1312,7 @@ PUBLIC const char *glXQueryExtensionsString( Display *dpy, int screen )  	__glXCalculateUsableExtensions(psc,  #ifdef GLX_DIRECT_RENDERING -				       (psc->driScreen.private != NULL), +				       (psc->driScreen != NULL),  #else  				       GL_FALSE,  #endif @@ -1547,7 +1524,7 @@ glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)      int retVal;      /* get the information from the server if we don't have it already */ -    if (!ctx->isDirect && (ctx->mode == NULL)) { +    if (!ctx->driContext && (ctx->mode == NULL)) {  	retVal = __glXQueryContextInfo(dpy, ctx);  	if (Success != retVal) return retVal;      } @@ -1741,7 +1718,7 @@ static int __glXSwapIntervalSGI(int interval)     }  #ifdef __DRI_SWAP_CONTROL -   if ( gc->isDirect ) { +   if (gc->driContext) {         __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,  							     gc->screen );         __DRIdrawable * const pdraw = GetDRIDrawable( gc->currentDpy, @@ -1793,11 +1770,11 @@ static int __glXSwapIntervalMESA(unsigned int interval)        return GLX_BAD_VALUE;     } -   if ( (gc != NULL) && gc->isDirect ) { +   if (gc != NULL && gc->driContext) {        __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,  							    gc->screen ); -      if ( (psc != NULL) && (psc->driScreen.private != NULL) ) { +      if ( (psc != NULL) && (psc->driScreen != NULL) ) {  	 __DRIdrawable * const pdraw =   	     GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);  	 if (psc->swapControl != NULL && pdraw != NULL) { @@ -1819,11 +1796,11 @@ static int __glXGetSwapIntervalMESA(void)  #ifdef __DRI_SWAP_CONTROL     GLXContext gc = __glXGetCurrentContext(); -   if ( (gc != NULL) && gc->isDirect ) { +   if (gc != NULL && gc->driContext) {        __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,  							    gc->screen ); -      if ( (psc != NULL) && (psc->driScreen.private != NULL) ) { +      if ( (psc != NULL) && (psc->driScreen != NULL) ) {  	 __DRIdrawable * const pdraw =   	     GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);  	 if (psc->swapControl != NULL && pdraw != NULL) { @@ -1944,16 +1921,16 @@ static int __glXGetVideoSyncSGI(unsigned int *count)     GLXContext gc = __glXGetCurrentContext(); -   if ( (gc != NULL) && gc->isDirect ) { +   if (gc != NULL && gc->driContext) {        __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,  							    gc->screen ); -      if ( psc->msc && psc->driScreen.private ) { +      if ( psc->msc && psc->driScreen ) {            __DRIdrawable * const pdraw =                 GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);  	  int64_t temp;   	  int ret; -	  ret = (*psc->msc->getDrawableMSC)(&psc->driScreen, pdraw, &temp); +	  ret = (*psc->msc->getDrawableMSC)(&psc->__driScreen, pdraw, &temp);  	  *count = (unsigned) temp;  	  return (ret == 0) ? 0 : GLX_BAD_CONTEXT; @@ -1973,10 +1950,10 @@ static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count     if ( divisor <= 0 || remainder < 0 )       return GLX_BAD_VALUE; -   if ( (gc != NULL) && gc->isDirect ) { +   if (gc != NULL && gc->driContext) {        __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,  							    gc->screen ); -      if (psc->msc != NULL && psc->driScreen.private ) { +      if (psc->msc != NULL && psc->driScreen ) {  	 __DRIdrawable * const pdraw =   	     GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);  	 int       ret; @@ -2163,7 +2140,7 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable,  }  #ifdef GLX_DIRECT_RENDERING -GLboolean +_X_HIDDEN GLboolean  __driGetMscRateOML(__DRIdrawable *draw, int32_t *numerator, int32_t *denominator)  {  #ifdef XF86VIDMODE @@ -2171,9 +2148,9 @@ __driGetMscRateOML(__DRIdrawable *draw, int32_t *numerator, int32_t *denominator      XF86VidModeModeLine   mode_line;      int   dot_clock;      int   i; -    __GLXdrawable *glxDraw; +    __GLXDRIdrawable *glxDraw; -    glxDraw = containerOf(draw, __GLXdrawable, driDrawable); +    glxDraw = containerOf(draw, __GLXDRIdrawable, driDrawable);      psc = glxDraw->psc;      if (XF86VidModeQueryVersion(psc->dpy, &i, &i) &&  	XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line) ) { @@ -2241,8 +2218,9 @@ __driGetMscRateOML(__DRIdrawable *draw, int32_t *numerator, int32_t *denominator   *       when GLX_OML_sync_control appears in the client extension string.   */ -GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, -			     int32_t * numerator, int32_t * denominator) +_X_HIDDEN GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, +				       int32_t * numerator, +				       int32_t * denominator)  {  #if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )      __DRIdrawable *driDraw = GetDRIDrawable(dpy, drawable, NULL); @@ -2386,7 +2364,7 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn,     __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );     if (psc && psc->allocate) -       return (*psc->allocate->allocateMemory)( &psc->driScreen, size, +       return (*psc->allocate->allocateMemory)( &psc->__driScreen, size,  						readFreq, writeFreq,  						priority ); @@ -2409,7 +2387,7 @@ PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer)     __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );     if (psc && psc->allocate) -	 (*psc->allocate->freeMemory)( &psc->driScreen, pointer ); +	 (*psc->allocate->freeMemory)( &psc->__driScreen, pointer );  #else     (void) dpy; @@ -2426,7 +2404,7 @@ PUBLIC GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn,     __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );     if (psc && psc->allocate) -       return (*psc->allocate->memoryOffset)( &psc->driScreen, pointer ); +       return (*psc->allocate->memoryOffset)( &psc->__driScreen, pointer );  #else     (void) dpy; @@ -2582,7 +2560,7 @@ static void __glXBindTexImageEXT(Display *dpy,      }  #ifdef GLX_DIRECT_RENDERING -    if (gc->isDirect) +    if (gc->driContext)  	return;  #endif @@ -2634,7 +2612,7 @@ static void __glXReleaseTexImageEXT(Display *dpy,  	return;  #ifdef GLX_DIRECT_RENDERING -    if (gc->isDirect) +    if (gc->driContext)  	return;  #endif @@ -2666,7 +2644,7 @@ static void __glXReleaseTexImageEXT(Display *dpy,   *    * \sa strdup   */ -char * +_X_HIDDEN char *  __glXstrdup(const char *str)  {     char *copy; @@ -2907,7 +2885,7 @@ PUBLIC void (*glXGetProcAddress(const GLubyte *procName))( void )   *   * \since Internal API version 20030317.   */ -int __glXGetUST( int64_t * ust ) +_X_HIDDEN int __glXGetUST( int64_t * ust )  {      struct timeval  tv; diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index 7eef38446b..525faab10e 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -63,7 +63,6 @@  #include "xf86dri.h"  #include "xf86drm.h"  #include "sarea.h" -#include "dri_glx.h"  #endif  #ifdef USE_XCB @@ -72,7 +71,6 @@  #include <xcb/glx.h>  #endif -#include <assert.h>  #ifdef DEBUG  void __glXDumpDrawBuffer(__GLXcontext *ctx); @@ -150,7 +148,7 @@ static __GLapi *IndirectAPI = NULL;  static GLboolean TSDinitialized = GL_FALSE;  static xthread_key_t ContextTSD; -__GLXcontext *__glXGetCurrentContext(void) +_X_HIDDEN __GLXcontext *__glXGetCurrentContext(void)  {     if (!TSDinitialized) {        xthread_key_create(&ContextTSD, NULL); @@ -167,7 +165,7 @@ __GLXcontext *__glXGetCurrentContext(void)     }  } -void __glXSetCurrentContext(__GLXcontext *c) +_X_HIDDEN void __glXSetCurrentContext(__GLXcontext *c)  {     if (!TSDinitialized) {        xthread_key_create(&ContextTSD, NULL); @@ -178,11 +176,11 @@ void __glXSetCurrentContext(__GLXcontext *c)  /* Used by the __glXLock() and __glXUnlock() macros */ -xmutex_rec __glXmutex; +_X_HIDDEN xmutex_rec __glXmutex;  #elif defined( PTHREADS ) -pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER; +_X_HIDDEN pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER;  # if defined( GLX_USE_TLS ) @@ -196,7 +194,7 @@ pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER;  __thread void * __glX_tls_Context __attribute__((tls_model("initial-exec")))      = &dummyContext; -void __glXSetCurrentContext( __GLXcontext * c ) +_X_HIDDEN void __glXSetCurrentContext( __GLXcontext * c )  {      __glX_tls_Context = (c != NULL) ? c : &dummyContext;  } @@ -229,13 +227,13 @@ static void init_thread_data( void )      }  } -void __glXSetCurrentContext( __GLXcontext * c ) +_X_HIDDEN void __glXSetCurrentContext( __GLXcontext * c )  {      pthread_once( & once_control, init_thread_data );      pthread_setspecific( ContextTSD, c );  } -__GLXcontext * __glXGetCurrentContext( void ) +_X_HIDDEN __GLXcontext * __glXGetCurrentContext( void )  {      void * v; @@ -254,7 +252,7 @@ __GLXcontext * __glXGetCurrentContext( void )  #else  /* not thread safe */ -__GLXcontext *__glXcurrentContext = &dummyContext; +_X_HIDDEN __GLXcontext *__glXcurrentContext = &dummyContext;  #endif @@ -263,15 +261,7 @@ __GLXcontext *__glXcurrentContext = &dummyContext;  ** You can set this cell to 1 to force the gl drawing stuff to be  ** one command per packet  */ -int __glXDebug = 0; - -/* -** forward prototype declarations -*/ -int __glXCloseDisplay(Display *dpy, XExtCodes *codes); - - -/************************************************************************/ +_X_HIDDEN int __glXDebug = 0;  /* Extension required boiler plate */ @@ -294,7 +284,7 @@ static /* const */ char *error_list[] = {      "GLXBadWindow",  }; -int __glXCloseDisplay(Display *dpy, XExtCodes *codes) +static int __glXCloseDisplay(Display *dpy, XExtCodes *codes)  {    GLXContext gc; @@ -358,10 +348,8 @@ static void FreeScreenConfigs(__GLXdisplayPrivate *priv)  	Xfree((char*) psc->serverGLXexts);  #ifdef GLX_DIRECT_RENDERING -	/* Free the direct rendering per screen data */ -	if (psc->driScreen.private) -	    (*psc->driScreen.destroyScreen)(&psc->driScreen); -	psc->driScreen.private = NULL; +	if (psc->driScreen) +	    psc->driScreen->destroyScreen(psc);  	if (psc->drawHash)  	    __glxHashDestroy(psc->drawHash);  #endif @@ -390,14 +378,9 @@ static int __glXFreeDisplayPrivate(XExtData *extension)  #ifdef GLX_DIRECT_RENDERING      /* Free the direct rendering per display data */ -    if (priv->driDisplay.private) -	(*priv->driDisplay.destroyDisplay)(priv->dpy, -					   priv->driDisplay.private); -    priv->driDisplay.private = NULL; -    if (priv->driDisplay.createNewScreen) { -        Xfree(priv->driDisplay.createNewScreen); /* free array of ptrs */ -        priv->driDisplay.createNewScreen = NULL; -    } +    if (priv->driDisplay) +	(*priv->driDisplay->destroyDisplay)(priv->driDisplay); +    priv->driDisplay = NULL;  #endif      Xfree((char*) priv); @@ -439,7 +422,7 @@ static Bool QueryVersion(Display *dpy, int opcode, int *major, int *minor)  } -void  +_X_HIDDEN void   __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count,   				     const INT32 *bp, Bool tagged_only,  				     Bool fbconfig_style_tags ) @@ -633,385 +616,6 @@ __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count,      config->haveStencilBuffer = (config->stencilBits > 0);  } - -#ifdef GLX_DIRECT_RENDERING -static void -filter_modes( __GLcontextModes ** server_modes, -	      const __GLcontextModes * driver_modes ) -{ -    __GLcontextModes * m; -    __GLcontextModes ** prev_next; -    const __GLcontextModes * check; - -    if (driver_modes == NULL) { -	fprintf(stderr, "libGL warning: 3D driver returned no fbconfigs.\n"); -	return; -    } - -    /* For each mode in server_modes, check to see if a matching mode exists -     * in driver_modes.  If not, then the mode is not available. -     */ - -    prev_next = server_modes; -    for ( m = *prev_next ; m != NULL ; m = *prev_next ) { -	GLboolean do_delete = GL_TRUE; - -	for ( check = driver_modes ; check != NULL ; check = check->next ) { -	    if ( _gl_context_modes_are_same( m, check ) ) { -		do_delete = GL_FALSE; -		break; -	    } -	} - -	/* The 3D has to support all the modes that match the GLX visuals -	 * sent from the X server. -	 */ -	if ( do_delete && (m->visualID != 0) ) { -	    do_delete = GL_FALSE; - -	    /* don't warn for this visual (Novell #247471 / X.Org #6689) */ -	    if (m->visualRating != GLX_NON_CONFORMANT_CONFIG) { -		fprintf(stderr, "libGL warning: 3D driver claims to not " -			"support visual 0x%02x\n", m->visualID); -	    } -	} - -	if ( do_delete ) { -	    *prev_next = m->next; - -	    m->next = NULL; -	    _gl_context_modes_destroy( m ); -	} -	else { -	    prev_next = & m->next; -	} -    } -} - -#ifdef XDAMAGE_1_1_INTERFACE -static GLboolean has_damage_post(Display *dpy) -{ -    static GLboolean inited = GL_FALSE; -    static GLboolean has_damage; - -    if (!inited) { -	int major, minor; - -	if (XDamageQueryVersion(dpy, &major, &minor) && -	    major == 1 && minor >= 1) -	{ -	    has_damage = GL_TRUE; -	} else { -	    has_damage = GL_FALSE; -	} -	inited = GL_TRUE; -    } - -    return has_damage; -} -#endif /* XDAMAGE_1_1_INTERFACE */ - -static void __glXReportDamage(__DRIdrawable *driDraw, -			      int x, int y, -			      drm_clip_rect_t *rects, int num_rects, -			      GLboolean front_buffer) -{ -#ifdef XDAMAGE_1_1_INTERFACE -    XRectangle *xrects; -    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; - -    if (front_buffer) { -	x_off = x; -	y_off = y; -	drawable = RootWindow(dpy, psc->scr); -    } else{ -	x_off = 0; -	y_off = 0; -	drawable = glxDraw->drawable; -    } - -    xrects = malloc(sizeof(XRectangle) * num_rects); -    if (xrects == NULL) -	return; - -    for (i = 0; i < num_rects; i++) { -	xrects[i].x = rects[i].x1 + x_off; -	xrects[i].y = rects[i].y1 + y_off; -	xrects[i].width = rects[i].x2 - rects[i].x1; -	xrects[i].height = rects[i].y2 - rects[i].y1; -    } -    region = XFixesCreateRegion(dpy, xrects, num_rects); -    free(xrects); -    XDamageAdd(dpy, drawable, region); -    XFixesDestroyRegion(dpy, region); -#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 __DRIcontextModesExtension contextModesExtension = { -    { __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION }, -    _gl_context_modes_create, -    _gl_context_modes_destroy, -}; - -static const __DRIsystemTimeExtension systemTimeExtension = { -    { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION }, -    __glXGetUST, -    __driGetMscRateOML, -}; - -static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = { -    { __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION }, -    __glXDRIGetDrawableInfo -}; - -static const __DRIdamageExtension damageExtension = { -    { __DRI_DAMAGE, __DRI_DAMAGE_VERSION }, -    __glXReportDamage, -}; - -static const __DRIextension *loader_extensions[] = { -    &contextModesExtension.base, -    &systemTimeExtension.base, -    &getDrawableInfoExtension.base, -    &damageExtension.base, -    NULL -}; - - - -/** - * Perform the required libGL-side initialization and call the client-side - * driver's \c __driCreateNewScreen function. - *  - * \param dpy    Display pointer. - * \param scrn   Screen number on the display. - * \param psc    DRI screen information. - * \param driDpy DRI display information. - * \param createNewScreen  Pointer to the client-side driver's - *               \c __driCreateNewScreen function. - * \returns A pointer to the \c __DRIscreenPrivate structure returned by - *          the client-side driver on success, or \c NULL on failure. - *  - * \todo This function needs to be modified to remove context-modes from the - *       list stored in the \c __GLXscreenConfigsRec to match the list - *       returned by the client-side driver. - */ -static void * -CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, -		    __DRIdisplay * driDpy, -		    PFNCREATENEWSCREENFUNC createNewScreen) -{ -    __DRIscreenPrivate *psp = NULL; -#ifndef GLX_USE_APPLEGL -    drm_handle_t hSAREA; -    drmAddress pSAREA = MAP_FAILED; -    char *BusID; -    __DRIversion   ddx_version; -    __DRIversion   dri_version; -    __DRIversion   drm_version; -    __DRIframebuffer  framebuffer; -    int   fd = -1; -    int   status; -    const char * err_msg; -    const char * err_extra; - -    dri_version.major = driDpy->private->driMajor; -    dri_version.minor = driDpy->private->driMinor; -    dri_version.patch = driDpy->private->driPatch; - - -    err_msg = "XF86DRIOpenConnection"; -    err_extra = NULL; - -    framebuffer.base = MAP_FAILED; -    framebuffer.dev_priv = NULL; - -    if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) { -        int newlyopened; -	fd = drmOpenOnce(NULL,BusID, &newlyopened); -	Xfree(BusID); /* No longer needed */ - -	err_msg = "open DRM"; -	err_extra = strerror( -fd ); - -	if (fd >= 0) { -	    drm_magic_t magic; - -	    err_msg = "drmGetMagic"; -	    err_extra = NULL; - -	    if (!drmGetMagic(fd, &magic)) { -		drmVersionPtr version = drmGetVersion(fd); -		if (version) { -		    drm_version.major = version->version_major; -		    drm_version.minor = version->version_minor; -		    drm_version.patch = version->version_patchlevel; -		    drmFreeVersion(version); -		} -		else { -		    drm_version.major = -1; -		    drm_version.minor = -1; -		    drm_version.patch = -1; -		} - -		err_msg = "XF86DRIAuthConnection"; -		if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) { -		    char *driverName; - -		    /* -		     * Get device name (like "tdfx") and the ddx version -		     * numbers.  We'll check the version in each DRI driver's -		     * "createNewScreen" function. -		     */ -		    err_msg = "XF86DRIGetClientDriverName"; -		    if (XF86DRIGetClientDriverName(dpy, scrn, -						   &ddx_version.major, -						   &ddx_version.minor, -						   &ddx_version.patch, -						   &driverName)) { -			drm_handle_t  hFB; -			int        junk; - -			/* No longer needed. */ -			Xfree( driverName ); - - -			/* -			 * Get device-specific info.  pDevPriv will point to a struct -			 * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) -			 * that has information about the screen size, depth, pitch, -			 * ancilliary buffers, DRM mmap handles, etc. -			 */ -			err_msg = "XF86DRIGetDeviceInfo"; -			if (XF86DRIGetDeviceInfo(dpy, scrn, -						 &hFB, -						 &junk, -						 &framebuffer.size, -						 &framebuffer.stride, -						 &framebuffer.dev_priv_size, -						 &framebuffer.dev_priv)) { -			    framebuffer.width = DisplayWidth(dpy, scrn); -			    framebuffer.height = DisplayHeight(dpy, scrn); - -			    /* -			     * Map the framebuffer region. -			     */ -			    status = drmMap(fd, hFB, framebuffer.size,  -					    (drmAddressPtr)&framebuffer.base); - -			    err_msg = "drmMap of framebuffer"; -			    err_extra = strerror( -status ); - -			    if ( status == 0 ) { -				/* -				 * Map the SAREA region.  Further mmap regions -				 * may be setup in each DRI driver's -				 * "createNewScreen" function. -				 */ -				status = drmMap(fd, hSAREA, SAREA_MAX,  -						&pSAREA); - -				err_msg = "drmMap of sarea"; -				err_extra = strerror( -status ); - -				if ( status == 0 ) { -				    __GLcontextModes * driver_modes = NULL; - -				    err_msg = "InitDriver"; -				    err_extra = NULL; -				    psp = (*createNewScreen)(scrn, -							     &psc->driScreen, -							     & ddx_version, -							     & dri_version, -							     & drm_version, -							     & framebuffer, -							     pSAREA, -							     fd, -							     loader_extensions, -							     & driver_modes ); - -				    filter_modes(&psc->configs, driver_modes); -				    filter_modes(&psc->visuals, driver_modes); -				    _gl_context_modes_destroy(driver_modes); -				} -			    } -			} -		    } -		} -	    } -	} -    } - -    if ( psp == NULL ) { -	if ( pSAREA != MAP_FAILED ) { -	    (void)drmUnmap(pSAREA, SAREA_MAX); -	} - -	if ( framebuffer.base != MAP_FAILED ) { -	    (void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size); -	} - -	if ( framebuffer.dev_priv != NULL ) { -	    Xfree(framebuffer.dev_priv); -	} - -	if ( fd >= 0 ) { -	    (void)drmCloseOnce(fd); -	} - -	(void)XF86DRICloseConnection(dpy, scrn); - -	if ( err_extra != NULL ) { -	    fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg, -		    err_extra); -	} -	else { -	    fprintf(stderr, "libGL error: %s failed\n", err_msg ); -	} - -        fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n"); -    } -#endif /* !GLX_USE_APPLEGL */ - -    return psp; -} - -#endif /* GLX_DIRECT_RENDERING */ -  static __GLcontextModes *  createConfigsFromProperties(Display *dpy, int nvisuals, int nprops,  			    int screen, GLboolean tagged_only) @@ -1167,34 +771,17 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)  	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 */ -	if (priv->driDisplay.private != NULL) { -	    /* FIXME: Should it be some sort of an error if createNewScreen[i] -	     * FIXME: is NULL? -	     */ -	    if (priv->driDisplay.createNewScreen && -		priv->driDisplay.createNewScreen[i]) { - -		psc->driScreen.private = -		    CallCreateNewScreen(dpy, i, psc, -					& priv->driDisplay, -					priv->driDisplay.createNewScreen[i] ); -		if (psc->driScreen.private != NULL) -		    __glXScrEnableDRIExtension(psc); -	    } +#ifdef GLX_DIRECT_RENDERING +	if (priv->driDisplay) { +	    /* Create drawable hash */ +	    psc->drawHash = __glxHashCreate(); +	    if (psc->drawHash == NULL) +		continue; +	    psc->driScreen = (*priv->driDisplay->createScreen)(psc, i, priv); +	    if (psc->driScreen == NULL) +		__glxHashDestroy(psc->drawHash);  	}  #endif      } @@ -1205,7 +792,7 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)  /*  ** Initialize the client side extension code.  */ -__GLXdisplayPrivate *__glXInitialize(Display* dpy) +_X_HIDDEN __GLXdisplayPrivate *__glXInitialize(Display* dpy)  {      XExtDisplayInfo *info = __glXFindDisplay(dpy);      XExtData **privList, *private, *found; @@ -1285,8 +872,7 @@ __GLXdisplayPrivate *__glXInitialize(Display* dpy)      ** (e.g., those called in AllocAndFetchScreenConfigs).      */      if (getenv("LIBGL_ALWAYS_INDIRECT") == NULL) { -        dpyPriv->driDisplay.private = -            driCreateDisplay(dpy, &dpyPriv->driDisplay); +        dpyPriv->driDisplay = driCreateDisplay(dpy);      }  #endif @@ -1320,7 +906,7 @@ __GLXdisplayPrivate *__glXInitialize(Display* dpy)  ** Setup for sending a GLX command on dpy.  Make sure the extension is  ** initialized.  Try to avoid calling __glXInitialize as its kinda slow.  */ -CARD8 __glXSetupForCommand(Display *dpy) +_X_HIDDEN CARD8 __glXSetupForCommand(Display *dpy)  {      GLXContext gc;      __GLXdisplayPrivate *priv; @@ -1361,7 +947,7 @@ CARD8 __glXSetupForCommand(Display *dpy)   * Modify this function to use \c ctx->pc instead of the explicit   * \c pc parameter.   */ -GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc) +_X_HIDDEN GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)  {      Display * const dpy = ctx->currentDpy;  #ifdef USE_XCB @@ -1411,9 +997,9 @@ GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)   * \param data           Command data.   * \param dataLen        Size, in bytes, of the command data.   */ -void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber,  -			 GLint totalRequests, -			 const GLvoid * data, GLint dataLen) +_X_HIDDEN void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber,  +				   GLint totalRequests, +				   const GLvoid * data, GLint dataLen)  {      Display *dpy = gc->currentDpy;  #ifdef USE_XCB @@ -1459,9 +1045,9 @@ void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber,   * \param data       Command data.   * \param dataLen    Size, in bytes, of the command data.   */ -void __glXSendLargeCommand(__GLXcontext *ctx, -			   const GLvoid *header, GLint headerLen, -			   const GLvoid *data, GLint dataLen) +_X_HIDDEN void __glXSendLargeCommand(__GLXcontext *ctx, +				     const GLvoid *header, GLint headerLen, +				     const GLvoid *data, GLint dataLen)  {      GLint maxSize;      GLint totalRequests, requestNumber; @@ -1601,71 +1187,27 @@ static Bool SendMakeCurrentRequest(Display *dpy, CARD8 opcode,  #ifdef GLX_DIRECT_RENDERING -static __DRIdrawable * -FetchDRIDrawable( Display *dpy, GLXDrawable drawable, GLXContext gc) +static __GLXDRIdrawable * +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; +    __GLXDRIdrawable *pdraw; +    __GLXscreenConfigs *psc; -    if (priv == NULL || priv->driDisplay.private == NULL) +    if (priv == NULL || priv->driDisplay == 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; -    } +    psc = &priv->screenConfigs[gc->screen]; +    if (__glxHashLookup(psc->drawHash, drawable, (void *) &pdraw) == 0) +	return pdraw; -    if (__glxHashInsert(sc->drawHash, drawable, pdraw)) { -	(*pdraw->driDrawable.destroyDrawable)(&pdraw->driDrawable); -	XF86DRIDestroyDrawable(dpy, sc->scr, drawable); -	Xfree(pdraw); +    pdraw = psc->driScreen->createDrawable(psc, drawable, gc); +    if (__glxHashInsert(psc->drawHash, drawable, pdraw)) { +	(*pdraw->destroyDrawable)(pdraw);  	return NULL;      } -    return &pdraw->driDrawable; -} - -static Bool BindContextWrapper( Display *dpy, GLXContext gc, -				GLXDrawable draw, GLXDrawable read ) -{ -    __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->driContext); +    return pdraw;  }  #endif /* GLX_DIRECT_RENDERING */ @@ -1675,8 +1217,8 @@ static Bool UnbindContextWrapper( GLXContext gc )   *    * \note This is in this file so that it can access dummyContext.   */ -USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, -                                    GLXDrawable read, GLXContext gc) +static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, +			       GLXDrawable read, GLXContext gc)  {      xGLXMakeCurrentReply reply;      const GLXContext oldGC = __glXGetCurrentContext(); @@ -1698,20 +1240,16 @@ USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,  	return GL_FALSE;      } -#ifndef GLX_DIRECT_RENDERING -    if (gc && gc->isDirect) { -	return GL_FALSE; -    } -#endif -      _glapi_check_multithread();  #ifdef GLX_DIRECT_RENDERING      /* Bind the direct rendering context to the drawable */ -    if (gc && gc->isDirect) { -	bindReturnValue = (gc->driContext.private)  -	  ? BindContextWrapper(dpy, gc, draw, read) -	  : False; +    if (gc && gc->driContext) { +	__GLXDRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc); +	__GLXDRIdrawable *pread = FetchDRIDrawable(dpy, read, gc); + +	bindReturnValue = +	    (gc->driContext->bindContext) (gc->driContext, pdraw, pread);      } else  #endif      { @@ -1728,7 +1266,7 @@ USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,  	return False;      } -    if ((dpy != oldGC->currentDpy || (gc && gc->isDirect)) && +    if ((dpy != oldGC->currentDpy || (gc && gc->driContext)) &&  	!oldGC->isDirect && oldGC != &dummyContext) {  	xGLXMakeCurrentReply dummy_reply; @@ -1743,8 +1281,8 @@ USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,  				      & dummy_reply);      }  #ifdef GLX_DIRECT_RENDERING -    else if (oldGC->isDirect && oldGC->driContext.private) { -	(void) UnbindContextWrapper(oldGC); +    else if (oldGC->driContext) { +	oldGC->driContext->unbindContext(oldGC->driContext);      }  #endif @@ -1774,15 +1312,11 @@ USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,  		 */  #ifdef GLX_DIRECT_RENDERING  		/* Destroy the old direct rendering context */ -		if (oldGC->isDirect) { -		    if (oldGC->driContext.private) { -			(*oldGC->driContext.destroyContext) -			    (&oldGC->driContext); -			XF86DRIDestroyContext(oldGC->createDpy, -					      oldGC->psc->scr, -					      gc->hwContextID); -			oldGC->driContext.private = NULL; -		    } +		if (oldGC->driContext) { +		    oldGC->driContext->destroyContext(oldGC->driContext, +						      oldGC->psc, +						      oldGC->createDpy); +		    oldGC->driContext = NULL;  		}  #endif  		__glXFreeContext(oldGC); @@ -1795,7 +1329,7 @@ USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,  	    gc->currentDrawable = draw;  	    gc->currentReadable = read; -            if (!gc->isDirect) { +            if (!gc->driContext) {                 if (!IndirectAPI)                    IndirectAPI = __glXNewIndirectAPI();                 _glapi_set_dispatch(IndirectAPI); @@ -1847,7 +1381,7 @@ PUBLIC GLX_ALIAS(Bool, glXMakeContextCurrent,  #ifdef DEBUG -void __glXDumpDrawBuffer(__GLXcontext *ctx) +_X_HIDDEN void __glXDumpDrawBuffer(__GLXcontext *ctx)  {      GLubyte *p = ctx->buf;      GLubyte *end = ctx->pc; diff --git a/src/glx/x11/glxextensions.c b/src/glx/x11/glxextensions.c index 84f556e0cc..6d78c7067d 100644 --- a/src/glx/x11/glxextensions.c +++ b/src/glx/x11/glxextensions.c @@ -367,7 +367,7 @@ __glXScrEnableDRIExtension(__GLXscreenConfigs *psc)      __glXExtensionsCtr();      __glXExtensionsCtrScreen(psc); -    extensions = psc->driScreen.getExtensions(&psc->driScreen); +    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) { diff --git a/src/glx/x11/glxhash.c b/src/glx/x11/glxhash.c index 1b284c5f45..9ed0429032 100644 --- a/src/glx/x11/glxhash.c +++ b/src/glx/x11/glxhash.c @@ -71,6 +71,7 @@   */  #include "glxhash.h" +#include <X11/Xfuncproto.h>  #define HASH_MAIN 0 @@ -137,7 +138,7 @@ static unsigned long HashHash(unsigned long key)      return hash;  } -__glxHashTable *__glxHashCreate(void) +_X_HIDDEN __glxHashTable *__glxHashCreate(void)  {      __glxHashTablePtr table;      int          i; @@ -154,7 +155,7 @@ __glxHashTable *__glxHashCreate(void)      return table;  } -int __glxHashDestroy(__glxHashTable *t) +_X_HIDDEN int __glxHashDestroy(__glxHashTable *t)  {      __glxHashTablePtr  table = (__glxHashTablePtr)t;      __glxHashBucketPtr bucket; @@ -205,7 +206,8 @@ static __glxHashBucketPtr HashFind(__glxHashTablePtr table,      return NULL;  } -int __glxHashLookup(__glxHashTable *t, unsigned long key, void **value) +_X_HIDDEN int __glxHashLookup(__glxHashTable *t, +			      unsigned long key, void **value)  {      __glxHashTablePtr  table = (__glxHashTablePtr)t;      __glxHashBucketPtr bucket; @@ -218,7 +220,8 @@ int __glxHashLookup(__glxHashTable *t, unsigned long key, void **value)      return 0;			/* Found */  } -int __glxHashInsert(__glxHashTable *t, unsigned long key, void *value) +_X_HIDDEN int __glxHashInsert(__glxHashTable *t, +			      unsigned long key, void *value)  {      __glxHashTablePtr  table = (__glxHashTablePtr)t;      __glxHashBucketPtr bucket; @@ -240,7 +243,7 @@ int __glxHashInsert(__glxHashTable *t, unsigned long key, void *value)      return 0;			/* Added to table */  } -int __glxHashDelete(__glxHashTable *t, unsigned long key) +_X_HIDDEN int __glxHashDelete(__glxHashTable *t, unsigned long key)  {      __glxHashTablePtr  table = (__glxHashTablePtr)t;      unsigned long hash; @@ -257,7 +260,8 @@ int __glxHashDelete(__glxHashTable *t, unsigned long key)      return 0;  } -int __glxHashNext(__glxHashTable *t, unsigned long *key, void **value) +_X_HIDDEN int __glxHashNext(__glxHashTable *t, +			    unsigned long *key, void **value)  {      __glxHashTablePtr  table = (__glxHashTablePtr)t; @@ -274,7 +278,8 @@ int __glxHashNext(__glxHashTable *t, unsigned long *key, void **value)      return 0;  } -int __glxHashFirst(__glxHashTable *t, unsigned long *key, void **value) +_X_HIDDEN int __glxHashFirst(__glxHashTable *t, +			     unsigned long *key, void **value)  {      __glxHashTablePtr  table = (__glxHashTablePtr)t; diff --git a/src/glx/x11/indirect.c b/src/glx/x11/indirect.c index a8a649c5e3..871adddb95 100644 --- a/src/glx/x11/indirect.c +++ b/src/glx/x11/indirect.c @@ -5124,7 +5124,7 @@ glAreTexturesResidentEXT(GLsizei n, const GLuint * textures,  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          return CALL_AreTexturesResident(GET_DISPATCH(),                                          (n, textures, residences));      } else { @@ -5274,7 +5274,7 @@ glDeleteTexturesEXT(GLsizei n, const GLuint * textures)  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_DeleteTextures(GET_DISPATCH(), (n, textures));      } else {          __GLXcontext *const gc = __glXGetCurrentContext(); @@ -5342,7 +5342,7 @@ glGenTexturesEXT(GLsizei n, GLuint * textures)  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_GenTextures(GET_DISPATCH(), (n, textures));      } else {          __GLXcontext *const gc = __glXGetCurrentContext(); @@ -5404,7 +5404,7 @@ glIsTextureEXT(GLuint texture)  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          return CALL_IsTexture(GET_DISPATCH(), (texture));      } else {          __GLXcontext *const gc = __glXGetCurrentContext(); @@ -5718,7 +5718,7 @@ glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid * table)  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_GetColorTable(GET_DISPATCH(), (target, format, type, table));      } else {          __GLXcontext *const gc = __glXGetCurrentContext(); @@ -5791,7 +5791,7 @@ glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat * params)  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_GetColorTableParameterfv(GET_DISPATCH(),                                        (target, pname, params));      } else { @@ -5861,7 +5861,7 @@ glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint * params)  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_GetColorTableParameteriv(GET_DISPATCH(),                                        (target, pname, params));      } else { @@ -6184,7 +6184,7 @@ gl_dispatch_stub_356(GLenum target, GLenum format, GLenum type,  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_GetConvolutionFilter(GET_DISPATCH(),                                    (target, format, type, image));      } else { @@ -6259,7 +6259,7 @@ gl_dispatch_stub_357(GLenum target, GLenum pname, GLfloat * params)  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_GetConvolutionParameterfv(GET_DISPATCH(),                                         (target, pname, params));      } else { @@ -6329,7 +6329,7 @@ gl_dispatch_stub_358(GLenum target, GLenum pname, GLint * params)  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_GetConvolutionParameteriv(GET_DISPATCH(),                                         (target, pname, params));      } else { @@ -6406,7 +6406,7 @@ gl_dispatch_stub_361(GLenum target, GLboolean reset, GLenum format,  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_GetHistogram(GET_DISPATCH(),                            (target, reset, format, type, values));      } else { @@ -6480,7 +6480,7 @@ gl_dispatch_stub_362(GLenum target, GLenum pname, GLfloat * params)  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_GetHistogramParameterfv(GET_DISPATCH(), (target, pname, params));      } else {          __GLXcontext *const gc = __glXGetCurrentContext(); @@ -6548,7 +6548,7 @@ gl_dispatch_stub_363(GLenum target, GLenum pname, GLint * params)  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_GetHistogramParameteriv(GET_DISPATCH(), (target, pname, params));      } else {          __GLXcontext *const gc = __glXGetCurrentContext(); @@ -6620,7 +6620,7 @@ gl_dispatch_stub_364(GLenum target, GLboolean reset, GLenum format,  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_GetMinmax(GET_DISPATCH(), (target, reset, format, type, values));      } else {          __GLXcontext *const gc = __glXGetCurrentContext(); @@ -6691,7 +6691,7 @@ gl_dispatch_stub_365(GLenum target, GLenum pname, GLfloat * params)  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_GetMinmaxParameterfv(GET_DISPATCH(), (target, pname, params));      } else {          __GLXcontext *const gc = __glXGetCurrentContext(); @@ -6756,7 +6756,7 @@ gl_dispatch_stub_366(GLenum target, GLenum pname, GLint * params)  {      __GLXcontext *const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {          CALL_GetMinmaxParameteriv(GET_DISPATCH(), (target, pname, params));      } else {          __GLXcontext *const gc = __glXGetCurrentContext(); diff --git a/src/glx/x11/singlepix.c b/src/glx/x11/singlepix.c index a7b5b79870..bc5b162c67 100644 --- a/src/glx/x11/singlepix.c +++ b/src/glx/x11/singlepix.c @@ -118,7 +118,7 @@ void NAME(_gloffset_GetSeparableFilter)(GLenum target, GLenum format, GLenum typ  {      __GLXcontext * const gc = __glXGetCurrentContext(); -    if (gc->isDirect) { +    if (gc->driContext) {  	CALL_GetSeparableFilter(GET_DISPATCH(),  				(target, format, type, row, column, span));  	return; diff --git a/src/glx/x11/xfont.c b/src/glx/x11/xfont.c index 843a2298b2..b650c17c55 100644 --- a/src/glx/x11/xfont.c +++ b/src/glx/x11/xfont.c @@ -210,7 +210,7 @@ static XCharStruct *isvalid(XFontStruct *fs, int which)    return(NULL);  } -void DRI_glXUseXFont( Font font, int first, int count, int listbase ) +_X_HIDDEN void DRI_glXUseXFont( Font font, int first, int count, int listbase )  {    GLXContext CC;    Display *dpy; diff --git a/src/mesa/Makefile b/src/mesa/Makefile index d0c78b71ee..695a416094 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -132,15 +132,6 @@ $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME): $(OSMESA_DRIVER_OBJECTS) $(OSMESA16_OBJECT  ###################################################################### -# libGL pkg-config file -pcedit = sed \ -	-e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \ -	-e 's,@LIB_DIR@,$(LIB_DIR),' \ -	-e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),' -gl.pc: gl.pc.in -	$(pcedit) $< > $@ - -######################################################################  # Generic stuff  depend: $(ALL_SOURCES) @@ -159,25 +150,40 @@ subdirs:  		(cd x86-64 ; $(MAKE)) ; \  	fi +pcedit = sed \ +	-e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \ +	-e 's,@LIB_DIR@,$(LIB_DIR),' \ +	-e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),' + +gl.pc: gl.pc.in +	$(pcedit) $< > $@ -install: default gl.pc +install-libgl: gl.pc  	$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL  	$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)  	$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig  	$(INSTALL) -m 644 $(TOP)/include/GL/*.h $(DESTDIR)$(INSTALL_DIR)/include/GL  	@if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \ -		$(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \ +		$(INSTALL) $(TOP)/$(LIB_DIR)/libGL* \ +			$(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \  	fi  	$(INSTALL) -m 644 gl.pc $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig + +install-osmesa:  	@if [ -e $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME) ]; then \ -		$(INSTALL) $(TOP)/$(LIB_DIR)/libOSMesa* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \ +		$(INSTALL) $(TOP)/$(LIB_DIR)/libOSMesa* \ +			$(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \  	fi + +install-drivers:  	@for target in $(DRIVER_DIRS); do \  	  case "$$target" in \  	    dri) cd drivers/dri ; $(MAKE) install ;; \  	  esac; \  	done +install: default install-libgl install-osmesa install-drivers +  ## NOT INSTALLED YET:  ## $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES  ## $(INSTALL) -m 644 include/GLES/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 8f67798a08..9d94ca3b39 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -231,7 +231,7 @@ alloc_block(dri_bo *bo)     dri_bo_fake *bo_fake = (dri_bo_fake *)bo;     dri_bufmgr_fake *bufmgr_fake= (dri_bufmgr_fake *)bo->bufmgr;     struct block *block = (struct block *)calloc(sizeof *block, 1); -   unsigned int align_log2 = ffs(bo_fake->alignment); +   unsigned int align_log2 = _mesa_ffs(bo_fake->alignment);     GLuint sz;     if (!block) @@ -660,10 +660,12 @@ dri_fake_bo_unreference(dri_bo *bo)        for (i = 0; i < bo_fake->nr_relocs; i++)  	 dri_bo_unreference(bo_fake->relocs[i].target_buf); -      free(bo_fake->relocs); +      DBG("drm_bo_unreference: free buf %d %s\n", bo_fake->id, bo_fake->name); + +      free(bo_fake->relocs);        free(bo); -      DBG("drm_bo_unreference: free %s\n", bo_fake->name); +        return;     }  } @@ -924,6 +926,8 @@ dri_fake_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta,     dri_bo_fake *reloc_fake = (dri_bo_fake *)reloc_buf;     int i; +   assert(reloc_buf); +   assert(target_buf);     if (reloc_fake->relocs == NULL) {        reloc_fake->relocs = malloc(sizeof(struct fake_buffer_reloc) *  				  MAX_RELOCS); diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 89c1a099d9..1f5d65265c 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -49,6 +49,7 @@ static void *driCreateNewDrawable(__DRIscreen *screen,  				  const __GLcontextModes *modes,                                    __DRIdrawable *pdraw,  				  drm_drawable_t hwDrawable, +				  unsigned int head,                                    int renderType, const int *attrs);  static void driDestroyDrawable(__DRIdrawable *drawable); @@ -192,8 +193,8 @@ static GLboolean driBindContext(__DRIcontext * ctx,      */      if (psp->dri2.enabled) { -       __driParseEvents(psp, pdp); -       __driParseEvents(psp, prp); +       __driParseEvents(pcp, pdp); +       __driParseEvents(pcp, prp);      } else {  	if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) {  	    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); @@ -285,17 +286,14 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)  }  int -__driParseEvents(__DRIscreenPrivate *psp, __DRIdrawablePrivate *pdp) +__driParseEvents(__DRIcontextPrivate *pcp, __DRIdrawablePrivate *pdp)  { -    __DRIDrawableConfigEvent *dc; -    __DRIBufferAttachEvent *ba; +    __DRIscreenPrivate *psp = pcp->driScreenPriv; +    __DRIDrawableConfigEvent *dc, *last_dc; +    __DRIBufferAttachEvent *ba, *last_ba;      unsigned int tail, mask, *p, end, total, size, changed;      unsigned char *data;      size_t rect_size; -    __DRIcontextPrivate *pcp = pdp->driContextPriv; - -    if (pcp == NULL) -	return 0;      /* Check for wraparound. */      if (psp->dri2.buffer->prealloc - pdp->dri2.tail > psp->dri2.buffer->size) { @@ -303,18 +301,20 @@ __driParseEvents(__DRIscreenPrivate *psp, __DRIdrawablePrivate *pdp)  	* server overwrote it and we have to reset our tail  	* pointer. */  	DRM_UNLOCK(psp->fd, psp->lock, pcp->hHWContext); -	(*psp->dri2.core->reemitDrawableInfo)(pdp->pdraw); +	(*psp->dri2.core->reemitDrawableInfo)(pdp->pdraw, &pdp->dri2.tail);  	DRM_LIGHT_LOCK(psp->fd, psp->lock, pcp->hHWContext);      }      total = psp->dri2.buffer->head - pdp->dri2.tail;      mask = psp->dri2.buffer->size - 1; -    tail = pdp->dri2.tail;      end = psp->dri2.buffer->head;      data = psp->dri2.buffer->data; +      changed = 0; +    last_dc = NULL; +    last_ba = NULL; -    while (tail != end) { +    for (tail = pdp->dri2.tail; tail != end; tail += size) {         p = (unsigned int *) (data + (tail & mask));         size = DRI2_EVENT_SIZE(*p);         if (size > total || (tail & mask) + size > psp->dri2.buffer->size) { @@ -326,50 +326,92 @@ __driParseEvents(__DRIscreenPrivate *psp, __DRIdrawablePrivate *pdp)         switch (DRI2_EVENT_TYPE(*p)) {         case DRI2_EVENT_DRAWABLE_CONFIG:  	  dc = (__DRIDrawableConfigEvent *) p; +	  if (dc->drawable == pdp->hHWDrawable) +	     last_dc = dc; +	  break; -	  if (dc->drawable != pdp->hHWDrawable) -	     break; +       case DRI2_EVENT_BUFFER_ATTACH: +	  ba = (__DRIBufferAttachEvent *) p; +	  if (ba->drawable == pdp->hHWDrawable &&  +	      ba->buffer.attachment == DRI_DRAWABLE_BUFFER_FRONT_LEFT) +	     last_ba = ba; +	  break; +       } +    } +	   +    if (last_dc) { +       if (pdp->w != last_dc->width || pdp->h != last_dc->height) +	  changed = 1; -	  if (pdp->w != dc->width || pdp->h != dc->height) -	     changed = 1; +       pdp->x = last_dc->x; +       pdp->y = last_dc->y; +       pdp->w = last_dc->width; +       pdp->h = last_dc->height; -	  pdp->x = dc->x; -	  pdp->y = dc->y; -	  pdp->w = dc->width; -	  pdp->h = dc->height; +       pdp->backX = 0; +       pdp->backY = 0; +       pdp->numBackClipRects = 1; +       pdp->pBackClipRects[0].x1 = 0; +       pdp->pBackClipRects[0].y1 = 0; +       pdp->pBackClipRects[0].x2 = pdp->w; +       pdp->pBackClipRects[0].y2 = pdp->h; -	  pdp->backX = 0; -	  pdp->backY = 0; -	  pdp->numBackClipRects = 1; -	  pdp->pBackClipRects[0].x1 = 0; -	  pdp->pBackClipRects[0].y1 = 0; -	  pdp->pBackClipRects[0].x2 = pdp->w; -	  pdp->pBackClipRects[0].y2 = pdp->h; +       pdp->numClipRects = last_dc->num_rects; +       _mesa_free(pdp->pClipRects); +       rect_size = last_dc->num_rects * sizeof last_dc->rects[0]; +       pdp->pClipRects = _mesa_malloc(rect_size); +       memcpy(pdp->pClipRects, last_dc->rects, rect_size); -	  pdp->numClipRects = dc->num_rects; -	  _mesa_free(pdp->pClipRects); -	  rect_size = dc->num_rects * sizeof dc->rects[0]; -	  pdp->pClipRects = _mesa_malloc(rect_size); -	  memcpy(pdp->pClipRects, dc->rects, rect_size); +       if (changed) +	  (*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc); +    } -	  if (changed) -	      (*psp->DriverAPI.UpdateBuffer)(pdp, p); -	  break; +    /* Front buffer attachments are special, they typically mean that +     * we're rendering to a redirected window (or a child window of a +     * redirected window) and that it got resized.  Resizing the root +     * window on randr events is a special case of this.  Other causes +     * may be a window transitioning between redirected and +     * non-redirected, or a window getting reparented between parents +     * with different window pixmaps (eg two redirected windows). +     * These events are special in that the X server allocates the +     * buffer and that the buffer may be shared by other child +     * windows.  When our window share the window pixmap with its +     * parent, drawable config events doesn't affect the front buffer. +     * We only care about the last such event in the buffer; in fact, +     * older events will refer to invalid buffer objects.*/ +    if (last_ba) +       (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, last_ba); -       case DRI2_EVENT_BUFFER_ATTACH: -	  ba = (__DRIBufferAttachEvent *) p; +    /* Like for buffer attachments, we only care about the most recent +     * drawable config. */ +    if (last_dc) +       (*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc); -	  if (ba->drawable != pdp->hHWDrawable) -	     break; +    /* If there was a drawable config event in the buffer and it +     * changed the size of the window, all buffer auxillary buffer +     * attachments prior to that are invalid (as opposed to the front +     * buffer case discussed above).  In that case we can start +     * looking for buffer attachment after the last drawable config +     * event.  If there is no drawable config event in this batch of +     * events, we have to assume that the last batch might have had +     * one and process all buffer attach events.*/ +    if (last_dc && changed) +       tail = (unsigned char *) last_dc - data; +    else +       tail = pdp->dri2.tail; -	  (*psp->DriverAPI.UpdateBuffer)(pdp, p); -	  break; +    for ( ; tail != end; tail += size) { +       ba = (__DRIBufferAttachEvent *) (data + (tail & mask)); +       size = DRI2_EVENT_SIZE(ba->event_header); -       default: -	  break; -       } +       if (DRI2_EVENT_TYPE(ba->event_header) != DRI2_EVENT_BUFFER_ATTACH) +	  continue; +       if (ba->drawable != pdp->hHWDrawable) +	  continue; +       if (last_ba == ba) +	  continue; -       tail += size; +       (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, ba);      }      pdp->dri2.tail = tail; @@ -508,13 +550,13 @@ static void *driCreateNewDrawable(__DRIscreen *screen,  				  const __GLcontextModes *modes,  				  __DRIdrawable *pdraw,  				  drm_drawable_t hwDrawable, +				  unsigned int head,  				  int renderType,  				  const int *attrs)  {      __DRIscreenPrivate *psp;      __DRIdrawablePrivate *pdp; -      pdraw->private = NULL;      /* Since pbuffers are not yet supported, no drawable attributes are @@ -568,7 +610,7 @@ static void *driCreateNewDrawable(__DRIscreen *screen,      pdp->swapBuffers = psp->DriverAPI.SwapBuffers;      if (psp->dri2.enabled) { -	pdp->dri2.tail = 0; +        pdp->dri2.tail = head;  	pdp->pBackClipRects = _mesa_malloc(sizeof *pdp->pBackClipRects);      } diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index e6659811d7..59c64e4adf 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -209,8 +209,14 @@ struct __DriverAPIRec {  			    int64_t *count);      /* DRI2 Entry points */ -    void (*UpdateBuffer)(__DRIdrawablePrivate *dPriv, -			 unsigned int *event); +    void (*HandleDrawableConfig)(__DRIdrawablePrivate *dPriv, +				__DRIcontextPrivate *pcp, +				__DRIDrawableConfigEvent *event); + +    void (*HandleBufferAttach)(__DRIdrawablePrivate *dPriv, +			       __DRIcontextPrivate *pcp, +			       __DRIBufferAttachEvent *ba); +  }; @@ -559,7 +565,7 @@ extern void  __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp);  extern int -__driParseEvents(__DRIscreenPrivate *psp, __DRIdrawablePrivate *pdp); +__driParseEvents(__DRIcontextPrivate *psp, __DRIdrawablePrivate *pdp);  extern float  driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index 9bc868b043..d1b07c5a2f 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -609,11 +609,12 @@ i830_state_draw_region(struct intel_context *intel,  static void  i830_set_draw_region(struct intel_context *intel, -                     struct intel_region *color_region, -                     struct intel_region *depth_region) +                     struct intel_region *color_regions[], +                     struct intel_region *depth_region, +		     GLuint num_regions)  {     struct i830_context *i830 = i830_context(&intel->ctx); -   i830_state_draw_region(intel, &i830->state, color_region, depth_region); +   i830_state_draw_region(intel, &i830->state, color_regions[0], depth_region);  }  #if 0 @@ -665,6 +666,11 @@ i830_assert_not_dirty( struct intel_context *intel )     assert(!get_dirty(state));  } +static void +i830_note_unlock( struct intel_context *intel ) +{ +    /* nothing */ +}  void  i830InitVtbl(struct i830_context *i830) @@ -680,4 +686,5 @@ i830InitVtbl(struct i830_context *i830)     i830->intel.vtbl.render_start = i830_render_start;     i830->intel.vtbl.render_prevalidate = i830_render_prevalidate;     i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty; +   i830->intel.vtbl.note_unlock = i830_note_unlock;   } diff --git a/src/mesa/drivers/dri/i915/i915_tex_layout.c b/src/mesa/drivers/dri/i915/i915_tex_layout.c index dfd02112ba..b5085f49d4 100644 --- a/src/mesa/drivers/dri/i915/i915_tex_layout.c +++ b/src/mesa/drivers/dri/i915/i915_tex_layout.c @@ -25,8 +25,8 @@   *    **************************************************************************/ -/* Code to layout images in a mipmap tree for i915 and i945 - * respectively. +/** @file i915_tex_layout.c + * Code to layout images in a mipmap tree for i830M-GM915 and G945 and beyond.   */  #include "intel_mipmap_tree.h" @@ -36,141 +36,206 @@  #define FILE_DEBUG_FLAG DEBUG_TEXTURE -static GLint initial_offsets[6][2] = { {0, 0}, -{0, 2}, -{1, 0}, -{1, 2}, -{1, 1}, -{1, 3} +static GLint initial_offsets[6][2] = { +   [FACE_POS_X] = {0, 0}, +   [FACE_POS_Y] = {1, 0}, +   [FACE_POS_Z] = {1, 1}, +   [FACE_NEG_X] = {0, 2}, +   [FACE_NEG_Y] = {1, 2}, +   [FACE_NEG_Z] = {1, 3},  }; -static GLint step_offsets[6][2] = { {0, 2}, -{0, 2}, -{-1, 2}, -{-1, 2}, -{-1, 1}, -{-1, 1} +static GLint step_offsets[6][2] = { +   [FACE_POS_X] = {0, 2}, +   [FACE_POS_Y] = {-1, 2}, +   [FACE_POS_Z] = {-1, 1}, +   [FACE_NEG_X] = {0, 2}, +   [FACE_NEG_Y] = {-1, 2}, +   [FACE_NEG_Z] = {-1, 1},  }; -GLboolean -i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt) +/** + * Cube texture map layout for i830M-GM915. + * + * Hardware layout looks like: + * + * +-------+-------+ + * |       |       | + * |       |       | + * |       |       | + * |  +x   |  +y   | + * |       |       | + * |       |       | + * |       |       | + * |       |       | + * +---+---+-------+ + * |   |   |       | + * | +x| +y|       | + * |   |   |       | + * |   |   |       | + * +-+-+---+  +z   | + * | | |   |       | + * +-+-+ +z|       | + *   | |   |       | + * +-+-+---+-------+ + * |       |       | + * |       |       | + * |       |       | + * |  -x   |  -y   | + * |       |       | + * |       |       | + * |       |       | + * |       |       | + * +---+---+-------+ + * |   |   |       | + * | -x| -y|       | + * |   |   |       | + * |   |   |       | + * +-+-+---+  -z   | + * | | |   |       | + * +-+-+ -z|       | + *   | |   |       | + *   +-+---+-------+ + * + */ +static void +i915_miptree_layout_cube(struct intel_context *intel, +			 struct intel_mipmap_tree * mt)  { +   const GLuint dim = mt->width0; +   GLuint face; +   GLuint lvlWidth = mt->width0, lvlHeight = mt->height0;     GLint level; -   switch (mt->target) { -   case GL_TEXTURE_CUBE_MAP:{ -         const GLuint dim = mt->width0; -         GLuint face; -         GLuint lvlWidth = mt->width0, lvlHeight = mt->height0; +   assert(lvlWidth == lvlHeight); /* cubemap images are square */ -         assert(lvlWidth == lvlHeight); /* cubemap images are square */ +   /* double pitch for cube layouts */ +   mt->pitch = intel_miptree_pitch_align (intel, mt, dim * 2); +   mt->total_height = dim * 4; -         /* double pitch for cube layouts */ -         mt->pitch = intel_miptree_pitch_align (intel, mt, dim * 2); -         mt->total_height = dim * 4; - -         for (level = mt->first_level; level <= mt->last_level; level++) { -            intel_miptree_set_level_info(mt, level, 6, -                                         0, 0, -                                         /*OLD: mt->pitch, mt->total_height,*/ -                                         lvlWidth, lvlHeight, -                                         1); -            lvlWidth /= 2; -            lvlHeight /= 2; -         } +   for (level = mt->first_level; level <= mt->last_level; level++) { +      intel_miptree_set_level_info(mt, level, 6, +				   0, 0, +				   /*OLD: mt->pitch, mt->total_height,*/ +				   lvlWidth, lvlHeight, +				   1); +      lvlWidth /= 2; +      lvlHeight /= 2; +   } -         for (face = 0; face < 6; face++) { -            GLuint x = initial_offsets[face][0] * dim; -            GLuint y = initial_offsets[face][1] * dim; -            GLuint d = dim; +   for (face = 0; face < 6; face++) { +      GLuint x = initial_offsets[face][0] * dim; +      GLuint y = initial_offsets[face][1] * dim; +      GLuint d = dim; -            for (level = mt->first_level; level <= mt->last_level; level++) { -               intel_miptree_set_image_offset(mt, level, face, x, y); +      for (level = mt->first_level; level <= mt->last_level; level++) { +	 intel_miptree_set_image_offset(mt, level, face, x, y); -               if (d == 0) -                  _mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n", -                               face, level, mt->first_level, mt->last_level); +	 if (d == 0) +	    _mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n", +			 face, level, mt->first_level, mt->last_level); -               d >>= 1; -               x += step_offsets[face][0] * d; -               y += step_offsets[face][1] * d; -            } -         } -         break; +	 d >>= 1; +	 x += step_offsets[face][0] * d; +	 y += step_offsets[face][1] * d;        } -   case GL_TEXTURE_3D:{ -         GLuint width = mt->width0; -         GLuint height = mt->height0; -         GLuint depth = mt->depth0; -         GLuint stack_height = 0; +   } +} -         /* Calculate the size of a single slice.  -          */ -         mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); +static void +i915_miptree_layout_3d(struct intel_context *intel, +		       struct intel_mipmap_tree * mt) +{ +   GLuint width = mt->width0; +   GLuint height = mt->height0; +   GLuint depth = mt->depth0; +   GLuint stack_height = 0; +   GLint level; -         /* XXX: hardware expects/requires 9 levels at minimum. -          */ -         for (level = mt->first_level; level <= MAX2(8, mt->last_level); -              level++) { -            intel_miptree_set_level_info(mt, level, depth, 0, mt->total_height, -                                         width, height, depth); +   /* Calculate the size of a single slice. */ +   mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); +   /* XXX: hardware expects/requires 9 levels at minimum. */ +   for (level = mt->first_level; level <= MAX2(8, mt->last_level); level++) { +      intel_miptree_set_level_info(mt, level, depth, 0, mt->total_height, +				   width, height, depth); -            stack_height += MAX2(2, height); +      stack_height += MAX2(2, height); -            width = minify(width); -            height = minify(height); -            depth = minify(depth); -         } +      width = minify(width); +      height = minify(height); +      depth = minify(depth); +   } -         /* Fixup depth image_offsets:  -          */ -         depth = mt->depth0; -         for (level = mt->first_level; level <= mt->last_level; level++) { -            GLuint i; -            for (i = 0; i < depth; i++)  -               intel_miptree_set_image_offset(mt, level, i, -                                              0, i * stack_height); +   /* Fixup depth image_offsets: */ +   depth = mt->depth0; +   for (level = mt->first_level; level <= mt->last_level; level++) { +      GLuint i; +      for (i = 0; i < depth; i++) { +	 intel_miptree_set_image_offset(mt, level, i, +					0, i * stack_height); +      } -            depth = minify(depth); -         } +      depth = minify(depth); +   } +   /* Multiply slice size by texture depth for total size.  It's +    * remarkable how wasteful of memory the i915 texture layouts +    * are.  They are largely fixed in the i945. +    */ +   mt->total_height = stack_height * mt->depth0; +} -         /* Multiply slice size by texture depth for total size.  It's -          * remarkable how wasteful of memory the i915 texture layouts -          * are.  They are largely fixed in the i945. -          */ -         mt->total_height = stack_height * mt->depth0; -         break; -      } +static void +i915_miptree_layout_2d(struct intel_context *intel, +		       struct intel_mipmap_tree * mt) +{ +   GLuint width = mt->width0; +   GLuint height = mt->height0; +   GLuint img_height; +   GLint level; -   default:{ -         GLuint width = mt->width0; -         GLuint height = mt->height0; -	 GLuint img_height; +   mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); +   mt->total_height = 0; -         mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); -         mt->total_height = 0; +   for (level = mt->first_level; level <= mt->last_level; level++) { +      intel_miptree_set_level_info(mt, level, 1, +				   0, mt->total_height, +				   width, height, 1); -         for (level = mt->first_level; level <= mt->last_level; level++) { -            intel_miptree_set_level_info(mt, level, 1, -                                         0, mt->total_height, -                                         width, height, 1); +      if (mt->compressed) +	 img_height = MAX2(1, height / 4); +      else +	 img_height = (MAX2(2, height) + 1) & ~1; -            if (mt->compressed) -               img_height = MAX2(1, height / 4); -            else -               img_height = (MAX2(2, height) + 1) & ~1; +      mt->total_height += img_height; -	    mt->total_height += img_height; +      width = minify(width); +      height = minify(height); +   } +} -            width = minify(width); -            height = minify(height); -         } -         break; -      } +GLboolean +i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt) +{ +   switch (mt->target) { +   case GL_TEXTURE_CUBE_MAP: +      i915_miptree_layout_cube(intel, mt); +      break; +   case GL_TEXTURE_3D: +      i915_miptree_layout_3d(intel, mt); +      break; +   case GL_TEXTURE_1D: +   case GL_TEXTURE_2D: +   case GL_TEXTURE_RECTANGLE_ARB: +      i915_miptree_layout_2d(intel, mt); +      break; +   default: +      _mesa_problem(NULL, "Unexpected tex target in i915_miptree_layout()"); +      break;     } +     DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,         mt->pitch,         mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); @@ -179,160 +244,229 @@ i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt)  } -GLboolean -i945_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt) +/** + * Cube texture map layout for GM945 and later. + * + * The hardware layout looks like the 830-915 layout, except for the small + * sizes.  A zoomed in view of the layout for 945 is: + * + * +-------+-------+ + * |  8x8  |  8x8  | + * |       |       | + * |       |       | + * |  +x   |  +y   | + * |       |       | + * |       |       | + * |       |       | + * |       |       | + * +---+---+-------+ + * |4x4|   |  8x8  | + * | +x|   |       | + * |   |   |       | + * |   |   |       | + * +---+   |  +z   | + * |4x4|   |       | + * | +y|   |       | + * |   |   |       | + * +---+   +-------+ + * + * ... + * + * +-------+-------+ + * |  8x8  |  8x8  | + * |       |       | + * |       |       | + * |  -x   |  -y   | + * |       |       | + * |       |       | + * |       |       | + * |       |       | + * +---+---+-------+ + * |4x4|   |  8x8  | + * | -x|   |       | + * |   |   |       | + * |   |   |       | + * +---+   |  -z   | + * |4x4|   |       | + * | -y|   |       | + * |   |   |       | + * +---+   +---+---+---+---+---+---+---+---+---+ + * |4x4|   |4x4|   |2x2|   |2x2|   |2x2|   |2x2| + * | +z|   | -z|   | +x|   | +y|   | +z|   | -x| ... + * |   |   |   |   |   |   |   |   |   |   |   | + * +---+   +---+   +---+   +---+   +---+   +---+ + * + * The bottom row continues with the remaining 2x2 then the 1x1 mip contents + * in order, with each of them aligned to a 4x4 block boundary.  Thus, for + * 32x32 cube maps and smaller, the bottom row layout is going to dictate the + * pitch of the tree.  For a tree with 4x4 images, the pitch is at least + * 14 * 8 = 112 texels, for 2x2 it is at least 12 * 8 texels, and for 1x1 + * it is 6 * 8 texels. + */ + +static void +i945_miptree_layout_cube(struct intel_context *intel, +			 struct intel_mipmap_tree * mt)  { +   const GLuint dim = mt->width0; +   GLuint face; +   GLuint lvlWidth = mt->width0, lvlHeight = mt->height0;     GLint level; -   switch (mt->target) { -   case GL_TEXTURE_CUBE_MAP:{ -         const GLuint dim = mt->width0; -         GLuint face; -         GLuint lvlWidth = mt->width0, lvlHeight = mt->height0; - -         assert(lvlWidth == lvlHeight); /* cubemap images are square */ - -         /* Depending on the size of the largest images, pitch can be -          * determined either by the old-style packing of cubemap faces, -          * or the final row of 4x4, 2x2 and 1x1 faces below this.  -          */ -         if (dim > 32) -            mt->pitch = intel_miptree_pitch_align (intel, mt, dim); -         else -            mt->pitch = 14 * 8; +   assert(lvlWidth == lvlHeight); /* cubemap images are square */ -         mt->total_height = dim * 4 + 4; +   /* Depending on the size of the largest images, pitch can be +    * determined either by the old-style packing of cubemap faces, +    * or the final row of 4x4, 2x2 and 1x1 faces below this. +    */ +   if (dim > 32) +      mt->pitch = intel_miptree_pitch_align (intel, mt, dim * 2); +   else +      mt->pitch = intel_miptree_pitch_align (intel, mt, 14 * 8); -         /* Set all the levels to effectively occupy the whole rectangular region.  -          */ -         for (level = mt->first_level; level <= mt->last_level; level++) { -            intel_miptree_set_level_info(mt, level, 6, -                                         0, 0, -                                         lvlWidth, lvlHeight, 1); -	    lvlWidth /= 2; -	    lvlHeight /= 2; -	 } +   if (dim >= 4) +      mt->total_height = dim * 4 + 4; +   else +      mt->total_height = 4; +   /* Set all the levels to effectively occupy the whole rectangular region. */ +   for (level = mt->first_level; level <= mt->last_level; level++) { +      intel_miptree_set_level_info(mt, level, 6, +				   0, 0, +				   lvlWidth, lvlHeight, 1); +      lvlWidth /= 2; +      lvlHeight /= 2; +   } -         for (face = 0; face < 6; face++) { -            GLuint x = initial_offsets[face][0] * dim; -            GLuint y = initial_offsets[face][1] * dim; -            GLuint d = dim; +   for (face = 0; face < 6; face++) { +      GLuint x = initial_offsets[face][0] * dim; +      GLuint y = initial_offsets[face][1] * dim; +      GLuint d = dim; -            if (dim == 4 && face >= 4) { -               y = mt->total_height - 4; -               x = (face - 4) * 8; -            } -            else if (dim < 4 && (face > 0 || mt->first_level > 0)) { -               y = mt->total_height - 4; -               x = face * 8; -            } +      if (dim == 4 && face >= 4) { +	 y = mt->total_height - 4; +	 x = (face - 4) * 8; +      } else if (dim < 4 && (face > 0 || mt->first_level > 0)) { +	 y = mt->total_height - 4; +	 x = face * 8; +      } -            for (level = mt->first_level; level <= mt->last_level; level++) { -               intel_miptree_set_image_offset(mt, level, face, x, y); +      for (level = mt->first_level; level <= mt->last_level; level++) { +	 intel_miptree_set_image_offset(mt, level, face, x, y); -               d >>= 1; +	 d >>= 1; -               switch (d) { -               case 4: -                  switch (face) { -                  case FACE_POS_X: -                  case FACE_NEG_X: -                     x += step_offsets[face][0] * d; -                     y += step_offsets[face][1] * d; -                     break; -                  case FACE_POS_Y: -                  case FACE_NEG_Y: -                     y += 12; -                     x -= 8; -                     break; -                  case FACE_POS_Z: -                  case FACE_NEG_Z: -                     y = mt->total_height - 4; -                     x = (face - 4) * 8; -                     break; -                  } +	 switch (d) { +	 case 4: +	    switch (face) { +	    case FACE_POS_X: +	    case FACE_NEG_X: +	       x += step_offsets[face][0] * d; +	       y += step_offsets[face][1] * d; +	       break; +	    case FACE_POS_Y: +	    case FACE_NEG_Y: +	       y += 12; +	       x -= 8; +	       break; +	    case FACE_POS_Z: +	    case FACE_NEG_Z: +	       y = mt->total_height - 4; +	       x = (face - 4) * 8; +	       break; +	    } -               case 2: -                  y = mt->total_height - 4; -                  x = 16 + face * 8; -                  break; +	 case 2: +	    y = mt->total_height - 4; +	    x = 16 + face * 8; +	    break; -               case 1: -                  x += 48; -                  break; +	 case 1: +	    x += 48; +	    break; -               default: -                  x += step_offsets[face][0] * d; -                  y += step_offsets[face][1] * d; -                  break; -               } -            } -         } -         break; +	 default: +	    x += step_offsets[face][0] * d; +	    y += step_offsets[face][1] * d; +	    break; +	 }        } -   case GL_TEXTURE_3D:{ -         GLuint width = mt->width0; -         GLuint height = mt->height0; -         GLuint depth = mt->depth0; -         GLuint pack_x_pitch, pack_x_nr; -         GLuint pack_y_pitch; -         GLuint level; - -         mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); -         mt->total_height = 0; +   } +} -         pack_y_pitch = MAX2(mt->height0, 2); -         pack_x_pitch = mt->pitch; -         pack_x_nr = 1; +static void +i945_miptree_layout_3d(struct intel_context *intel, +		       struct intel_mipmap_tree * mt) +{ +   GLuint width = mt->width0; +   GLuint height = mt->height0; +   GLuint depth = mt->depth0; +   GLuint pack_x_pitch, pack_x_nr; +   GLuint pack_y_pitch; +   GLuint level; -         for (level = mt->first_level; level <= mt->last_level; level++) { -            GLuint nr_images = mt->target == GL_TEXTURE_3D ? depth : 6; -            GLint x = 0; -            GLint y = 0; -            GLint q, j; +   mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); +   mt->total_height = 0; -            intel_miptree_set_level_info(mt, level, nr_images, -                                         0, mt->total_height, -                                         width, height, depth); +   pack_y_pitch = MAX2(mt->height0, 2); +   pack_x_pitch = mt->pitch; +   pack_x_nr = 1; -            for (q = 0; q < nr_images;) { -               for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { -                  intel_miptree_set_image_offset(mt, level, q, x, y); -                  x += pack_x_pitch; -               } +   for (level = mt->first_level; level <= mt->last_level; level++) { +      GLint x = 0; +      GLint y = 0; +      GLint q, j; -               x = 0; -               y += pack_y_pitch; -            } +      intel_miptree_set_level_info(mt, level, depth, +				   0, mt->total_height, +				   width, height, depth); +      for (q = 0; q < depth;) { +	 for (j = 0; j < pack_x_nr && q < depth; j++, q++) { +	    intel_miptree_set_image_offset(mt, level, q, x, y); +	    x += pack_x_pitch; +	 } -            mt->total_height += y; +	 x = 0; +	 y += pack_y_pitch; +      } -            if (pack_x_pitch > 4) { -               pack_x_pitch >>= 1; -               pack_x_nr <<= 1; -               assert(pack_x_pitch * pack_x_nr <= mt->pitch); -            } +      mt->total_height += y; -            if (pack_y_pitch > 2) { -               pack_y_pitch >>= 1; -            } +      if (pack_x_pitch > 4) { +	 pack_x_pitch >>= 1; +	 pack_x_nr <<= 1; +	 assert(pack_x_pitch * pack_x_nr <= mt->pitch); +      } -            width = minify(width); -            height = minify(height); -            depth = minify(depth); -         } -         break; +      if (pack_y_pitch > 2) { +	 pack_y_pitch >>= 1;        } +      width = minify(width); +      height = minify(height); +      depth = minify(depth); +   } +} + +GLboolean +i945_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt) +{ +   switch (mt->target) { +   case GL_TEXTURE_CUBE_MAP: +      i945_miptree_layout_cube(intel, mt); +      break; +   case GL_TEXTURE_3D: +      i945_miptree_layout_3d(intel, mt); +      break;     case GL_TEXTURE_1D:     case GL_TEXTURE_2D:     case GL_TEXTURE_RECTANGLE_ARB: -         i945_miptree_layout_2d(intel, mt); -         break; +      i945_miptree_layout_2d(intel, mt); +      break;     default:        _mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()"); +      break;     }     DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index 1c45fd5dcd..e489d25ae8 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -38,7 +38,7 @@  static GLuint -translate_texture_format(GLuint mesa_format) +translate_texture_format(GLuint mesa_format, GLenum DepthMode)  {     switch (mesa_format) {     case MESA_FORMAT_L8: @@ -65,7 +65,7 @@ translate_texture_format(GLuint mesa_format)     case MESA_FORMAT_RGBA_FXT1:        return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1);     case MESA_FORMAT_Z16: -      return (MAPSURF_16BIT | MT_16BIT_L16); +      return (MAPSURF_16BIT | (DepthMode==GL_ALPHA?MT_16BIT_A16:MT_16BIT_L16));     case MESA_FORMAT_RGBA_DXT1:     case MESA_FORMAT_RGB_DXT1:        return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); @@ -74,7 +74,7 @@ translate_texture_format(GLuint mesa_format)     case MESA_FORMAT_RGBA_DXT5:        return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);     case MESA_FORMAT_Z24_S8: -      return (MAPSURF_32BIT | MT_32BIT_xL824); +      return (MAPSURF_32BIT | MT_32BIT_xI824);     default:        fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, mesa_format);        abort(); @@ -166,7 +166,8 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)  								 0, intelObj->  								 firstLevel); -      format = translate_texture_format(firstImage->TexFormat->MesaFormat); +      format = translate_texture_format(firstImage->TexFormat->MesaFormat,  +		tObj->DepthMode);        pitch = intelObj->mt->pitch * intelObj->mt->cpp;     } @@ -248,8 +249,13 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)              (SS2_SHADOW_ENABLE |               intel_translate_shadow_compare_func(tObj->CompareFunc)); -         minFilt = FILTER_4X4_FLAT; -         magFilt = FILTER_4X4_FLAT; +	 if (tObj->Target == GL_TEXTURE_1D) {  +		 minFilt = FILTER_NEAREST; +		 magFilt = FILTER_NEAREST; +	 } else { +         	minFilt = FILTER_4X4_FLAT; +         	magFilt = FILTER_4X4_FLAT; +	 }        }        state[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index c856a8627d..94d70be441 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -532,11 +532,12 @@ i915_state_draw_region(struct intel_context *intel,  static void  i915_set_draw_region(struct intel_context *intel, -                     struct intel_region *color_region, -                     struct intel_region *depth_region) +                     struct intel_region *color_regions[], +                     struct intel_region *depth_region, +		     GLuint num_regions)  {     struct i915_context *i915 = i915_context(&intel->ctx); -   i915_state_draw_region(intel, &i915->state, color_region, depth_region); +   i915_state_draw_region(intel, &i915->state, color_regions[0], depth_region);  } @@ -571,6 +572,12 @@ i915_assert_not_dirty( struct intel_context *intel )     assert(!dirty);  } +static void +i915_note_unlock( struct intel_context *intel ) +{ +    /* nothing */ +} +  void  i915InitVtbl(struct i915_context *i915) @@ -586,4 +593,5 @@ i915InitVtbl(struct i915_context *i915)     i915->intel.vtbl.update_texture_state = i915UpdateTextureState;     i915->intel.vtbl.flush_cmd = i915_flush_cmd;     i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty; +   i915->intel.vtbl.note_unlock = i915_note_unlock;   } diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index 29f0b51ba6..bbb4e0f3cd 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -311,10 +311,18 @@ intel_wpos_triangle(struct intel_context *intel,  {     GLuint offset = intel->wpos_offset;     GLuint size = intel->wpos_size; +   GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset); +   GLfloat *v1_wpos = (GLfloat *)((char *)v1 + offset); +   GLfloat *v2_wpos = (GLfloat *)((char *)v2 + offset); + +   __memcpy(v0_wpos, v0, size); +   __memcpy(v1_wpos, v1, size); +   __memcpy(v2_wpos, v2, size); + +   v0_wpos[1] = -v0_wpos[1] + intel->driDrawable->h; +   v1_wpos[1] = -v1_wpos[1] + intel->driDrawable->h; +   v2_wpos[1] = -v2_wpos[1] + intel->driDrawable->h; -   __memcpy(((char *) v0) + offset, v0, size); -   __memcpy(((char *) v1) + offset, v1, size); -   __memcpy(((char *) v2) + offset, v2, size);     intel_draw_triangle(intel, v0, v1, v2);  } @@ -326,9 +334,14 @@ intel_wpos_line(struct intel_context *intel,  {     GLuint offset = intel->wpos_offset;     GLuint size = intel->wpos_size; +   GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset); +   GLfloat *v1_wpos = (GLfloat *)((char *)v1 + offset); + +   __memcpy(v0_wpos, v0, size); +   __memcpy(v1_wpos, v1, size); -   __memcpy(((char *) v0) + offset, v0, size); -   __memcpy(((char *) v1) + offset, v1, size); +   v0_wpos[1] = -v0_wpos[1] + intel->driDrawable->h; +   v1_wpos[1] = -v1_wpos[1] + intel->driDrawable->h;     intel_draw_line(intel, v0, v1);  } @@ -339,8 +352,10 @@ intel_wpos_point(struct intel_context *intel, intelVertexPtr v0)  {     GLuint offset = intel->wpos_offset;     GLuint size = intel->wpos_size; +   GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset); -   __memcpy(((char *) v0) + offset, v0, size); +   __memcpy(v0_wpos, v0, size); +   v0_wpos[1] = -v0_wpos[1] + intel->driDrawable->h;     intel_draw_point(intel, v0);  } diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c index 24b0288f88..ce34da165c 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.c +++ b/src/mesa/drivers/dri/i965/brw_clip.c @@ -168,12 +168,10 @@ static void upload_clip_prog( struct brw_context *brw )  	       offset_front = 0;  	       break;  	    case GL_LINE: -	       key.do_unfilled = 1;  	       fill_front = CLIP_LINE;  	       offset_front = brw->attribs.Polygon->OffsetLine;  	       break;  	    case GL_POINT: -	       key.do_unfilled = 1;  	       fill_front = CLIP_POINT;  	       offset_front = brw->attribs.Polygon->OffsetPoint;  	       break; @@ -188,26 +186,23 @@ static void upload_clip_prog( struct brw_context *brw )  	       offset_back = 0;  	       break;  	    case GL_LINE: -	       key.do_unfilled = 1;  	       fill_back = CLIP_LINE;  	       offset_back = brw->attribs.Polygon->OffsetLine;  	       break;  	    case GL_POINT: -	       key.do_unfilled = 1;  	       fill_back = CLIP_POINT;  	       offset_back = brw->attribs.Polygon->OffsetPoint;  	       break;  	    }  	 } -    if (brw->attribs.Polygon->BackMode != GL_FILL || -        brw->attribs.Polygon->FrontMode != GL_FILL) -        key.do_unfilled = 1; +	 if (brw->attribs.Polygon->BackMode != GL_FILL || +	     brw->attribs.Polygon->FrontMode != GL_FILL) { +	    key.do_unfilled = 1; -	 /* Most cases the fixed function units will handle.  Cases where -	  * one or more polygon faces are unfilled will require help: -	  */ -	 if (key.do_unfilled) { +	    /* Most cases the fixed function units will handle.  Cases where +	     * one or more polygon faces are unfilled will require help: +	     */  	    key.clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED;  	    if (offset_back || offset_front) { diff --git a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c index 918e000187..57ebf388f5 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c +++ b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c @@ -220,8 +220,8 @@ static void apply_one_offset( struct brw_clip_compile *c,  			  struct brw_indirect vert )  {     struct brw_compile *p = &c->func; -   struct brw_reg pos = deref_4f(vert, c->offset[VERT_RESULT_HPOS]); -   struct brw_reg z = get_element(pos, 2); +   struct brw_reg z = deref_1f(vert, c->header_position_offset + +			       2 * type_sz(BRW_REGISTER_TYPE_F));     brw_ADD(p, z, z, vec1(c->reg.offset));  } diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 49e739b0ad..56021fa209 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -146,12 +146,12 @@ struct brw_context;  struct brw_state_flags {     /** State update flags signalled by mesa internals */     GLuint mesa; -   /** State update flags signalled by brw_state_cache.c searches */ -   GLuint cache;     /**      * State update flags signalled as the result of brw_tracked_state updates      */     GLuint brw; +   /** State update flags signalled by brw_state_cache.c searches */ +   GLuint cache;  };  struct brw_vertex_program { @@ -240,7 +240,7 @@ struct brw_vs_ouput_sizes {  #define BRW_MAX_TEX_UNIT 8 -#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1 +#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + MAX_DRAW_BUFFERS  enum brw_cache_id {     BRW_CC_VP, @@ -425,8 +425,8 @@ struct brw_context        struct brw_tracked_state **atoms;        GLuint nr_atoms; - -      struct intel_region *draw_region; +      GLuint nr_draw_regions; +      struct intel_region *draw_regions[MAX_DRAW_BUFFERS];        struct intel_region *depth_region;     } state; @@ -461,6 +461,7 @@ struct brw_context        struct gl_buffer_object *vbo;        struct intel_region *saved_draw_region; +      GLuint saved_nr_draw_regions;        struct intel_region *saved_depth_region;        GLuint restore_draw_buffers[MAX_DRAW_BUFFERS]; diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c index 58aeeb4228..ce0df0357b 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.c +++ b/src/mesa/drivers/dri/i965/brw_fallback.c @@ -57,16 +57,6 @@ static GLboolean do_check_fallback(struct brw_context *brw)        return GL_TRUE;     } -   /* _NEW_BUFFERS -    */ -   /* We can only handle a single draw buffer at the moment, and only as the -    * first color buffer. -    */ -   if (fb->_NumColorDrawBuffers > 1) { -      DBG("FALLBACK: multiple color draw buffers\n"); -      return GL_TRUE; -   } -     /* _NEW_RENDERMODE      *      * XXX: need to save/restore RenderMode in metaops state, or diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c index dd62be34f4..252a8996e2 100644 --- a/src/mesa/drivers/dri/i965/brw_metaops.c +++ b/src/mesa/drivers/dri/i965/brw_metaops.c @@ -362,17 +362,20 @@ static void meta_draw_region( struct intel_context *intel,     struct brw_context *brw = brw_context(&intel->ctx);     if (!brw->metaops.saved_draw_region) { -      brw->metaops.saved_draw_region = brw->state.draw_region; +      brw->metaops.saved_draw_region = brw->state.draw_regions[0]; +      brw->metaops.saved_nr_draw_regions = brw->state.nr_draw_regions;        brw->metaops.saved_depth_region = brw->state.depth_region;     } -   brw->state.draw_region = draw_region; +   brw->state.draw_regions[0] = draw_region; +   brw->state.nr_draw_regions = 1;     brw->state.depth_region = depth_region;     if (intel->frame_buffer_texobj != NULL)        brw_FrameBufferTexDestroy(brw); -   brw_FrameBufferTexInit(brw, draw_region); +   if (draw_region) +       brw_FrameBufferTexInit(brw, draw_region);     brw->state.dirty.mesa |= _NEW_BUFFERS;  } @@ -508,7 +511,8 @@ static void install_meta_state( struct intel_context *intel )     /* This works without adjusting refcounts.  Fix later?       */ -   brw->metaops.saved_draw_region = brw->state.draw_region; +   brw->metaops.saved_draw_region = brw->state.draw_regions[0]; +   brw->metaops.saved_nr_draw_regions = brw->state.nr_draw_regions;     brw->metaops.saved_depth_region = brw->state.depth_region;     brw->metaops.active = 1; @@ -531,7 +535,8 @@ static void leave_meta_state( struct intel_context *intel )     ctx->FragmentProgram.Current = brw->metaops.restore_fp; -   brw->state.draw_region = brw->metaops.saved_draw_region; +   brw->state.draw_regions[0] = brw->metaops.saved_draw_region; +   brw->state.nr_draw_regions = brw->metaops.saved_nr_draw_regions;     brw->state.depth_region = brw->metaops.saved_depth_region;     brw->metaops.saved_draw_region = NULL;     brw->metaops.saved_depth_region = NULL; diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index 8e8fea48e9..f717b6f6c3 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -124,6 +124,9 @@ static void brwProgramStringNotify( GLcontext *ctx,        struct brw_vertex_program *vp = (struct brw_vertex_program *)brw->vertex_program;        if (p == vp)  	 brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM; +      if (p->program.IsPositionInvariant) { +	 _mesa_insert_mvp_code(ctx, &p->program); +      }        p->id = brw->program_id++;              p->param_state = p->program.Base.Parameters->StateFlags; diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c index 2b6087d691..398048429b 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_state.c +++ b/src/mesa/drivers/dri/i965/brw_sf_state.c @@ -224,11 +224,11 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,         sf.sf6.line_width = 0;     /* _NEW_POINT */ -   sf.sf6.point_rast_rule = 1;	/* opengl conventions */ +   sf.sf6.point_rast_rule = BRW_RASTRULE_UPPER_RIGHT;	/* opengl conventions */     /* XXX clamp max depends on AA vs. non-AA */     sf.sf7.sprite_point = key->point_sprite; -   sf.sf7.point_size = CLAMP(key->point_size, 1.0, 255.0) * (1<<3); +   sf.sf7.point_size = CLAMP(nearbyint(key->point_size), 1, 255) * (1<<3);     sf.sf7.use_point_size_state = !key->point_attenuated;     sf.sf7.aa_line_distance_mode = 0; diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c index 7b5eff4f2d..d617650fad 100644 --- a/src/mesa/drivers/dri/i965/brw_state_cache.c +++ b/src/mesa/drivers/dri/i965/brw_state_cache.c @@ -85,7 +85,7 @@ static GLuint hash_key( const void *key, GLuint key_size,     }     /* Include the BO pointers as key data as well */ -   ikey = (void *)reloc_bufs; +   ikey = (GLuint *)reloc_bufs;     key_size = nr_reloc_bufs * sizeof(dri_bo *);     for (i = 0; i < key_size/4; i++) {        hash ^= ikey[i]; @@ -102,6 +102,9 @@ static void  update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id,  		  dri_bo *bo)  { +   if (bo == cache->last_bo[cache_id]) +      return; /* no change */ +     dri_bo_unreference(cache->last_bo[cache_id]);     cache->last_bo[cache_id] = bo;     dri_bo_reference(cache->last_bo[cache_id]); @@ -255,7 +258,7 @@ brw_upload_cache( struct brw_cache *cache,     if (INTEL_DEBUG & DEBUG_STATE)        _mesa_printf("upload %s: %d bytes to cache id %d\n",  		   cache->name[cache_id], -		   data_size); +		   data_size, cache_id);     /* Copy data to the buffer */     dri_bo_subdata(bo, 0, data_size, data); @@ -282,6 +285,7 @@ brw_cache_data_sz(struct brw_cache *cache,     item = search_cache(cache, cache_id, hash, data, data_size,  		       reloc_bufs, nr_reloc_bufs);     if (item) { +      update_cache_last(cache, cache_id, item->bo);        dri_bo_reference(item->bo);        return item->bo;     } diff --git a/src/mesa/drivers/dri/i965/brw_tex.c b/src/mesa/drivers/dri/i965/brw_tex.c index ef14b8e89f..258c6260fb 100644 --- a/src/mesa/drivers/dri/i965/brw_tex.c +++ b/src/mesa/drivers/dri/i965/brw_tex.c @@ -77,6 +77,7 @@ void brw_FrameBufferTexDestroy( struct brw_context *brw )     if (brw->intel.frame_buffer_texobj != NULL)        brw->intel.ctx.Driver.DeleteTexture( &brw->intel.ctx,  					   brw->intel.frame_buffer_texobj ); +   brw->intel.frame_buffer_texobj = NULL;  }  /** diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index cdbbe7b699..31e96a250a 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -70,18 +70,21 @@ static void brw_destroy_context( struct intel_context *intel )  /* called from intelDrawBuffer()   */  static void brw_set_draw_region( struct intel_context *intel,  -				  struct intel_region *draw_region, -				  struct intel_region *depth_region) +				  struct intel_region *draw_regions[], +				  struct intel_region *depth_region, +				GLuint num_regions)  {     struct brw_context *brw = brw_context(&intel->ctx); - +   int i;     if (brw->state.depth_region != depth_region)        brw->state.dirty.brw |= BRW_NEW_DEPTH_BUFFER; - -   intel_region_release(&brw->state.draw_region); +   for (i = 0; i < brw->state.nr_draw_regions; i++) +       intel_region_release(&brw->state.draw_regions[i]);     intel_region_release(&brw->state.depth_region); -   intel_region_reference(&brw->state.draw_region, draw_region); +   for (i = 0; i < num_regions; i++) +       intel_region_reference(&brw->state.draw_regions[i], draw_regions[i]);     intel_region_reference(&brw->state.depth_region, depth_region); +   brw->state.nr_draw_regions = num_regions;  } diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 342e7f8496..abdc92bf01 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -29,7 +29,7 @@    *   Keith Whitwell <keith@tungstengraphics.com>    */ - +#include "main/texformat.h"  #include "brw_context.h"  #include "brw_util.h"  #include "brw_wm.h" @@ -139,6 +139,7 @@ static void do_wm_prog( struct brw_context *brw,     c->fp = fp;     c->env_param = brw->intel.ctx.FragmentProgram.Parameters; +    brw_init_compile(brw, &c->func);     if (brw_wm_is_glsl(&c->fp->program)) {         brw_wm_glsl_emit(brw, c);     } else { @@ -160,10 +161,6 @@ static void do_wm_prog( struct brw_context *brw,  	*/         c->grf_limit = BRW_WM_MAX_GRF/2; -       /* This is where we start emitting gen4 code: -	*/ -       brw_init_compile(brw, &c->func); -         brw_wm_pass2(c);         c->prog_data.total_grf = c->max_wm_grf; @@ -288,8 +285,12 @@ static void brw_wm_populate_key( struct brw_context *brw,  	    key->shadowtex_mask |= 1<<i;  	 } -	 if (t->Image[0][t->BaseLevel]->InternalFormat == GL_YCBCR_MESA) +	 if (t->Image[0][t->BaseLevel]->InternalFormat == GL_YCBCR_MESA) {  	    key->yuvtex_mask |= 1<<i; +	    if (t->Image[0][t->BaseLevel]->TexFormat->MesaFormat ==  +		    MESA_FORMAT_YCBCR) +		key->yuvtex_swap_mask |= 1<< i; +	 }        }     } diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index 645286d470..297617ee2d 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -69,7 +69,8 @@ struct brw_wm_prog_key {     GLuint runtime_check_aads_emit:1;     GLuint yuvtex_mask:8; -   GLuint pad1:24; +   GLuint yuvtex_swap_mask:8;	/* UV swaped */ +   GLuint pad1:16;     GLuint program_string_id:32;     GLuint origin_x, origin_y; @@ -142,6 +143,8 @@ struct brw_wm_instruction {     GLuint writemask:4;     GLuint tex_unit:4;   /* texture unit for TEX, TXD, TXP instructions */     GLuint tex_idx:3;    /* TEXTURE_1D,2D,3D,CUBE,RECT_INDEX source target */ +   GLuint eot:1;    	/* End of thread indicator for FB_WRITE*/ +   GLuint target:10;    /* target binding table index for FB_WRITE*/  }; @@ -196,6 +199,7 @@ struct brw_wm_compile {     GLuint nr_fp_insns;     GLuint fp_temp;     GLuint fp_interp_emitted; +   GLuint fp_fragcolor_emitted;     GLuint fp_deriv_emitted;     struct prog_src_register pixel_xy; diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c index df51f73dd8..a02f70a50c 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_emit.c +++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c @@ -137,7 +137,7 @@ static void emit_wpos_xy(struct brw_wm_compile *c,        brw_ADD(p,  	      dst[0],  	      retype(arg0[0], BRW_REGISTER_TYPE_W), -	      brw_imm_d(- c->key.origin_x)); +	      brw_imm_d(0 - c->key.origin_x));     }     if (mask & WRITEMASK_Y) { @@ -145,7 +145,7 @@ static void emit_wpos_xy(struct brw_wm_compile *c,        brw_ADD(p,  	      dst[1],  	      negate(retype(arg0[1], BRW_REGISTER_TYPE_W)), -	      brw_imm_d(c->key.origin_y + c->key.drawable_height)); +	      brw_imm_d(c->key.origin_y + c->key.drawable_height - 1));     }  } @@ -223,6 +223,10 @@ static void emit_pinterp( struct brw_compile *p,        if (mask & (1<<i)) {  	 brw_LINE(p, brw_null_reg(), interp[i], deltas[0]);  	 brw_MAC(p, dst[i], suboffset(interp[i],1), deltas[1]); +      } +   } +   for(i = 0; i < 4; i++ ) { +      if (mask & (1<<i)) {  	 brw_MUL(p, dst[i], dst[i], w[3]);        }     } @@ -500,6 +504,9 @@ static void emit_dp3( struct brw_compile *p,  		      const struct brw_reg *arg0,  		      const struct brw_reg *arg1 )  { +   if (!(mask & WRITEMASK_XYZW)) +      return; /* Do not emit dead code*/ +     assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);     brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]); @@ -517,6 +524,9 @@ static void emit_dp4( struct brw_compile *p,  		      const struct brw_reg *arg0,  		      const struct brw_reg *arg1 )  { +   if (!(mask & WRITEMASK_XYZW)) +      return; /* Do not emit dead code*/ +     assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);     brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]); @@ -535,6 +545,9 @@ static void emit_dph( struct brw_compile *p,  		      const struct brw_reg *arg0,  		      const struct brw_reg *arg1 )  { +   if (!(mask & WRITEMASK_XYZW)) +      return; /* Do not emit dead code*/ +     assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);     brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]); @@ -578,6 +591,9 @@ static void emit_math1( struct brw_compile *p,  			GLuint mask,  			const struct brw_reg *arg0 )  { +   if (!(mask & WRITEMASK_XYZW)) +      return; /* Do not emit dead code*/ +     //assert((mask & WRITEMASK_XYZW) == WRITEMASK_X ||     //	  function == BRW_MATH_FUNCTION_SINCOS); @@ -602,6 +618,9 @@ static void emit_math2( struct brw_compile *p,  			const struct brw_reg *arg0,  			const struct brw_reg *arg1)  { +   if (!(mask & WRITEMASK_XYZW)) +      return; /* Do not emit dead code*/ +     assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);     brw_push_insn_state(p); @@ -696,7 +715,7 @@ static void emit_tex( struct brw_wm_compile *c,  	      retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),  	      1,  	      retype(c->payload.depth[0].hw_reg, BRW_REGISTER_TYPE_UW), -	      inst->tex_unit + 1, /* surface */ +	      inst->tex_unit + MAX_DRAW_BUFFERS, /* surface */  	      inst->tex_unit,	  /* sampler */  	      inst->writemask,  	      (shadow ?  @@ -749,7 +768,7 @@ static void emit_txb( struct brw_wm_compile *c,  	      retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),  	      1,  	      retype(c->payload.depth[0].hw_reg, BRW_REGISTER_TYPE_UW), -	      inst->tex_unit + 1, /* surface */ +	      inst->tex_unit + MAX_DRAW_BUFFERS, /* surface */  	      inst->tex_unit,	  /* sampler */  	      inst->writemask,  	      BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS, @@ -822,7 +841,9 @@ static void emit_kil( struct brw_wm_compile *c,  static void fire_fb_write( struct brw_wm_compile *c,  			   GLuint base_reg, -			   GLuint nr ) +			   GLuint nr, +			   GLuint target, +			   GLuint eot )  {     struct brw_compile *p = &c->func; @@ -845,10 +866,10 @@ static void fire_fb_write( struct brw_wm_compile *c,  		retype(vec16(brw_null_reg()), BRW_REGISTER_TYPE_UW),  		base_reg,  		retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW), -		0,		/* render surface always 0 */ +		target,		  		nr,  		0,  -		1); +		eot);  }  static void emit_aa( struct brw_wm_compile *c, @@ -873,7 +894,9 @@ static void emit_aa( struct brw_wm_compile *c,  static void emit_fb_write( struct brw_wm_compile *c,  			   struct brw_reg *arg0,  			   struct brw_reg *arg1, -			   struct brw_reg *arg2) +			   struct brw_reg *arg2, +			   GLuint target, +			   GLuint eot)  {     struct brw_compile *p = &c->func;     GLuint nr = 2; @@ -946,7 +969,7 @@ static void emit_fb_write( struct brw_wm_compile *c,        if (c->key.aa_dest_stencil_reg)  	 emit_aa(c, arg1, 2); -      fire_fb_write(c, 0, nr); +      fire_fb_write(c, 0, nr, target, eot);     }     else {        struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD)); @@ -963,14 +986,14 @@ static void emit_fb_write( struct brw_wm_compile *c,        jmp = brw_JMPI(p, ip, ip, brw_imm_w(0));        {  	 emit_aa(c, arg1, 2); -	 fire_fb_write(c, 0, nr); +	 fire_fb_write(c, 0, nr, target, eot);  	 /* note - thread killed in subroutine */        }        brw_land_fwd_jump(p, jmp);        /* ELSE: Shuffle up one register to fill in the hole left for AA:         */ -      fire_fb_write(c, 1, nr-1); +      fire_fb_write(c, 1, nr-1, target, eot);     }  } @@ -1138,7 +1161,7 @@ void brw_wm_emit( struct brw_wm_compile *c )  	 break;        case WM_FB_WRITE: -	 emit_fb_write(c, args[0], args[1], args[2]); +	 emit_fb_write(c, args[0], args[1], args[2], inst->target, inst->eot);  	 break;  	 /* Straightforward arithmetic: diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index 55527373bc..7e80724130 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -144,7 +144,7 @@ static struct prog_dst_register dst_undef( void )  static struct prog_dst_register get_temp( struct brw_wm_compile *c )  { -   int bit = ffs( ~c->fp_temp ); +   int bit = _mesa_ffs( ~c->fp_temp );     if (!bit) {        _mesa_printf("%s: out of temporaries\n", __FILE__); @@ -158,7 +158,7 @@ static struct prog_dst_register get_temp( struct brw_wm_compile *c )  static void release_temp( struct brw_wm_compile *c, struct prog_dst_register temp )  { -   c->fp_temp &= ~1<<(temp.Index + 1 - FIRST_INTERNAL_TEMP); +   c->fp_temp &= ~(1 << (temp.Index - FIRST_INTERNAL_TEMP));  } @@ -494,17 +494,20 @@ static void precalc_dst( struct brw_wm_compile *c,     if (dst.WriteMask & WRITEMASK_XZ) { +      struct prog_instruction *swz;        GLuint z = GET_SWZ(src0.Swizzle, Z);        /* dst.xz = swz src0.1zzz         */ -      emit_op(c, -	      OPCODE_SWZ, -	      dst_mask(dst, WRITEMASK_XZ), -	      inst->SaturateMode, 0, 0, -	      src_swizzle(src0, SWIZZLE_ONE, z, z, z), -	      src_undef(), -	      src_undef()); +      swz = emit_op(c, +		    OPCODE_SWZ, +		    dst_mask(dst, WRITEMASK_XZ), +		    inst->SaturateMode, 0, 0, +		    src_swizzle(src0, SWIZZLE_ONE, z, z, z), +		    src_undef(), +		    src_undef()); +      /* Avoid letting negation flag of src0 affect our 1 constant. */ +      swz->SrcReg[0].NegateBase &= ~NEGATE_X;     }     if (dst.WriteMask & WRITEMASK_W) {        /* dst.w = mov src1.w @@ -527,15 +530,19 @@ static void precalc_lit( struct brw_wm_compile *c,     struct prog_dst_register dst = inst->DstReg;     if (dst.WriteMask & WRITEMASK_XW) { +      struct prog_instruction *swz; +        /* dst.xw = swz src0.1111         */ -      emit_op(c, -	      OPCODE_SWZ, -	      dst_mask(dst, WRITEMASK_XW), -	      0, 0, 0, -	      src_swizzle1(src0, SWIZZLE_ONE), -	      src_undef(), -	      src_undef()); +      swz = emit_op(c, +		    OPCODE_SWZ, +		    dst_mask(dst, WRITEMASK_XW), +		    0, 0, 0, +		    src_swizzle1(src0, SWIZZLE_ONE), +		    src_undef(), +		    src_undef()); +      /* Avoid letting the negation flag of src0 affect our 1 constant. */ +      swz->SrcReg[0].NegateBase = 0;     } @@ -649,17 +656,21 @@ static void precalc_tex( struct brw_wm_compile *c,  	      src_undef());     }     else { +       GLboolean  swap_uv = c->key.yuvtex_swap_mask & (1<<inst->TexSrcUnit); +        /*   	 CONST C0 = { -.5, -.0625,  -.5, 1.164 }  	 CONST C1 = { 1.596, -0.813, 2.018, -.391 }  	 UYV     = TEX ...  	 UYV.xyz = ADD UYV,     C0  	 UYV.y   = MUL UYV.y,   C0.w -	 RGB.xyz = MAD UYV.xxz, C1,   UYV.y + 	 if (UV swaped) +	    RGB.xyz = MAD UYV.zzx, C1,   UYV.y +	 else +	    RGB.xyz = MAD UYV.xxz, C1,   UYV.y   	 RGB.y   = MAD UYV.z,   C1.w, RGB.y        */        struct prog_dst_register dst = inst->DstReg; -      struct prog_src_register src0 = inst->SrcReg[0];        struct prog_dst_register tmp = get_temp(c);        struct prog_src_register tmpsrc = src_reg_from_dst(tmp);        struct prog_src_register C0 = search_or_add_const4f( c,  -.5, -.0625, -.5, 1.164 ); @@ -673,7 +684,7 @@ static void precalc_tex( struct brw_wm_compile *c,  	      inst->SaturateMode,  	      inst->TexSrcUnit,  	      inst->TexSrcTarget, -	      src0, +	      coord,  	      src_undef(),  	      src_undef()); @@ -689,6 +700,7 @@ static void precalc_tex( struct brw_wm_compile *c,        /* YUV.y   = MUL YUV.y, C0.w         */ +        emit_op(c,  	      OPCODE_MUL,  	      dst_mask(tmp, WRITEMASK_Y), @@ -697,13 +709,18 @@ static void precalc_tex( struct brw_wm_compile *c,  	      src_swizzle1(C0, W),  	      src_undef()); -      /* RGB.xyz = MAD YUV.xxz, C1, YUV.y +      /*  +       * if (UV swaped) +       *     RGB.xyz = MAD YUV.zzx, C1, YUV.y +       * else +       *     RGB.xyz = MAD YUV.xxz, C1, YUV.y         */ +        emit_op(c,  	      OPCODE_MAD,  	      dst_mask(dst, WRITEMASK_XYZ),  	      0, 0, 0, -	      src_swizzle(tmpsrc, X,X,Z,Z), +	      swap_uv?src_swizzle(tmpsrc, Z,Z,X,X):src_swizzle(tmpsrc, X,X,Z,Z),  	      C1,  	      src_swizzle1(tmpsrc, Y)); @@ -851,14 +868,34 @@ static void emit_fb_write( struct brw_wm_compile *c )     struct prog_src_register outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);     struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);     struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPR); +   GLuint i; -   emit_op(c, -	   WM_FB_WRITE, -	   dst_mask(dst_undef(),0), -	   0, 0, 0, -	   outcolor, -	   payload_r0_depth, -	   outdepth); +   struct prog_instruction *inst, *last_inst; +   struct brw_context *brw = c->func.brw; + +   /* inst->Sampler is not used by backend,  +      use it for fb write target and eot */ + +   if (brw->state.nr_draw_regions > 1) { +       for (i = 0 ; i < brw->state.nr_draw_regions; i++) { +	   outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i); +	   last_inst = inst = emit_op(c, +		   WM_FB_WRITE, dst_mask(dst_undef(),0), 0, 0, 0, +		   outcolor, payload_r0_depth, outdepth); +	   inst->Sampler = (i<<1); +	   if (c->fp_fragcolor_emitted) { +	       outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR); +	       last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0), +		       0, 0, 0, outcolor, payload_r0_depth, outdepth); +	       inst->Sampler = (i<<1); +	   } +       } +       last_inst->Sampler |= 1; //eot +   }else { +       inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0), +	       0, 0, 0, outcolor, payload_r0_depth, outdepth); +       inst->Sampler = 1|(0<<1); +   }  } @@ -884,7 +921,15 @@ static void validate_src_regs( struct brw_wm_compile *c,     }  } - +static void validate_dst_regs( struct brw_wm_compile *c, +			       const struct prog_instruction *inst ) +{ +   if (inst->DstReg.File == PROGRAM_OUTPUT) { +       GLuint idx = inst->DstReg.Index; +       if (idx == FRAG_RESULT_COLR) +	   c->fp_fragcolor_emitted = 1; +   } +}  static void print_insns( const struct prog_instruction *insn,  			 GLuint nr ) @@ -929,12 +974,16 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )     for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {        const struct prog_instruction *inst = &fp->program.Base.Instructions[insn]; +      validate_src_regs(c, inst); +      validate_dst_regs(c, inst); +   } +   for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) { +      const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];        struct prog_instruction *out;        /* Check for INPUT values, emit INTERP instructions where         * necessary:         */ -      validate_src_regs(c, inst);        switch (inst->Opcode) { diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index fd237ee028..b2ffc82ed2 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -274,10 +274,11 @@ static void emit_delta_xy(struct brw_wm_compile *c,  static void fire_fb_write( struct brw_wm_compile *c,                             GLuint base_reg, -                           GLuint nr ) +                           GLuint nr, +                           GLuint target, +                           GLuint eot)  {      struct brw_compile *p = &c->func; -      /* Pass through control information:       */      /*  mov (8) m1.0<1>:ud   r1.0<8;8,1>:ud   { Align1 NoMask } */ @@ -294,10 +295,10 @@ static void fire_fb_write( struct brw_wm_compile *c,  	    retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW),  	    base_reg,  	    retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW), -	    0,              /* render surface always 0 */ +	    target,                	    nr,  	    0, -	    1); +	    eot);  }  static void emit_fb_write(struct brw_wm_compile *c, @@ -306,7 +307,8 @@ static void emit_fb_write(struct brw_wm_compile *c,      struct brw_compile *p = &c->func;      int nr = 2;      int channel; -    struct brw_reg src0;//, src1, src2, dst; +    GLuint target, eot; +    struct brw_reg src0;      /* Reserve a space for AA - may not be needed:       */ @@ -337,8 +339,9 @@ static void emit_fb_write(struct brw_wm_compile *c,        nr += 2;     } - -    fire_fb_write(c, 0, nr); +    target = inst->Sampler >> 1; +    eot = inst->Sampler & 1; +    fire_fb_write(c, 0, nr, target, eot);  }  static void emit_pixel_w( struct brw_wm_compile *c, @@ -983,7 +986,7 @@ static void emit_wpos_xy(struct brw_wm_compile *c,  	brw_ADD(p,  		dst[1],  		negate(retype(src0[1], BRW_REGISTER_TYPE_W)), -		brw_imm_d(c->key.origin_y + c->key.drawable_height)); +		brw_imm_d(c->key.origin_y + c->key.drawable_height - 1));      }  } @@ -1026,7 +1029,7 @@ static void emit_txb(struct brw_wm_compile *c,  	    retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),  	    1,  	    retype(payload_reg, BRW_REGISTER_TYPE_UW), -	    inst->TexSrcUnit + 1, /* surface */ +	    inst->TexSrcUnit + MAX_DRAW_BUFFERS, /* surface */  	    inst->TexSrcUnit,     /* sampler */  	    inst->DstReg.WriteMask,  	    BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS, @@ -1088,7 +1091,7 @@ static void emit_tex(struct brw_wm_compile *c,  	    retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),  	    1,  	    retype(payload_reg, BRW_REGISTER_TYPE_UW), -	    inst->TexSrcUnit + 1, /* surface */ +	    inst->TexSrcUnit + MAX_DRAW_BUFFERS, /* surface */  	    inst->TexSrcUnit,     /* sampler */  	    inst->DstReg.WriteMask,  	    BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE, @@ -1125,7 +1128,6 @@ static void post_wm_emit( struct brw_wm_compile *c )  }  static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) -  {  #define MAX_IFSN 32  #define MAX_LOOP_DEPTH 32 @@ -1135,7 +1137,6 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)      struct brw_compile *p = &c->func;      struct brw_indirect stack_index = brw_indirect(0, 0); -    brw_init_compile(brw, &c->func);      c->reg_index = 0;      prealloc_reg(c);      brw_set_compression_control(p, BRW_COMPRESSION_NONE); diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c index 1bfae5a069..205a7160d3 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c +++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c @@ -348,6 +348,8 @@ static struct brw_wm_instruction *translate_insn( struct brw_wm_compile *c,     out->saturate = (inst->SaturateMode != SATURATE_OFF);     out->tex_unit = inst->TexSrcUnit;     out->tex_idx = inst->TexSrcTarget; +   out->eot = inst->Sampler & 1; +   out->target = inst->Sampler>>1;     /* Args:      */ diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass1.c b/src/mesa/drivers/dri/i965/brw_wm_pass1.c index 26c044d400..f6f3a38e9e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_pass1.c +++ b/src/mesa/drivers/dri/i965/brw_wm_pass1.c @@ -150,6 +150,7 @@ void brw_wm_pass1( struct brw_wm_compile *c )        case OPCODE_FLR:        case OPCODE_FRC:        case OPCODE_MOV: +      case OPCODE_SWZ:  	 read0 = writemask;  	 break; @@ -257,7 +258,6 @@ void brw_wm_pass1( struct brw_wm_compile *c )  	 read0 = WRITEMASK_XYW;  	 break; -      case OPCODE_SWZ:        case OPCODE_DST:        case OPCODE_TXP:        default: diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index f2ae210c38..c5c944f781 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -133,6 +133,9 @@ static GLuint translate_tex_format( GLuint mesa_format )     case MESA_FORMAT_SRGB_DXT1:        return BRW_SURFACEFORMAT_BC1_UNORM_SRGB; +   case MESA_FORMAT_Z24_S8: +      return BRW_SURFACEFORMAT_I24X8_UNORM; +     default:        assert(0);        return 0; @@ -226,13 +229,13 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )     key.depth = firstImage->Depth;     key.tiled = intelObj->mt->region->tiled; -   dri_bo_unreference(brw->wm.surf_bo[unit + 1]); -   brw->wm.surf_bo[unit + 1] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, +   dri_bo_unreference(brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS]); +   brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] = brw_search_cache(&brw->cache, BRW_SS_SURFACE,  						&key, sizeof(key),  						&key.bo, 1,  						NULL); -   if (brw->wm.surf_bo[unit + 1] == NULL) -      brw->wm.surf_bo[unit + 1] = brw_create_texture_surface(brw, &key); +   if (brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] == NULL) +      brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] = brw_create_texture_surface(brw, &key);  }  /** @@ -242,7 +245,7 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )   */  static void  brw_update_region_surface(struct brw_context *brw, struct intel_region *region, -			  unsigned int unit) +			  unsigned int unit, GLboolean cached)  {     dri_bo *region_bo = NULL; @@ -276,17 +279,19 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region,        key.height = 1;        key.cpp = 4;     } -     memcpy(key.color_mask, brw->attribs.Color->ColorMask,  	  sizeof(key.color_mask));     key.color_blend = (!brw->attribs.Color->_LogicOpEnabled &&  		      brw->attribs.Color->BlendEnabled);     dri_bo_unreference(brw->wm.surf_bo[unit]); -   brw->wm.surf_bo[unit] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, -					    &key, sizeof(key), -					    ®ion_bo, 1, -					    NULL); +   brw->wm.surf_bo[unit] = NULL; +   if (cached)  +       brw->wm.surf_bo[unit] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, +	       &key, sizeof(key), +	       ®ion_bo, 1, +	       NULL); +     if (brw->wm.surf_bo[unit] == NULL) {        struct brw_surface_state surf; @@ -312,11 +317,10 @@ brw_update_region_surface(struct brw_context *brw, struct intel_region *region,        /* Key size will never match key size for textures, so we're safe. */        brw->wm.surf_bo[unit] = brw_upload_cache(&brw->cache, BRW_SS_SURFACE, -					       &key, sizeof(key), +					      &key, sizeof(key),  					       ®ion_bo, 1,  					       &surf, sizeof(surf),  					       NULL, NULL); -        if (region_bo != NULL) {  	 dri_emit_reloc(brw->wm.surf_bo[unit],  			DRM_BO_FLAG_MEM_TT | @@ -345,7 +349,7 @@ brw_wm_get_binding_table(struct brw_context *brw)  			      NULL);     if (bind_bo == NULL) { -      GLuint data_size = brw->wm.nr_surfaces * 4; +      GLuint data_size = brw->wm.nr_surfaces * sizeof(GLuint);        uint32_t *data = malloc(data_size);        int i; @@ -369,7 +373,7 @@ brw_wm_get_binding_table(struct brw_context *brw)  			   DRM_BO_FLAG_READ |  			   DRM_BO_FLAG_WRITE,  			   0, -			   i * 4, +			   i * sizeof(GLuint),  			   brw->wm.surf_bo[i]);  	 }        } @@ -385,9 +389,14 @@ static void upload_wm_surfaces(struct brw_context *brw )     GLcontext *ctx = &brw->intel.ctx;     struct intel_context *intel = &brw->intel;     GLuint i; +   if (brw->state.nr_draw_regions  > 1) { +       for (i = 0; i < brw->state.nr_draw_regions; i++)  +	   brw_update_region_surface(brw, brw->state.draw_regions[i], i,  +		GL_FALSE); +   }else +       brw_update_region_surface(brw, brw->state.draw_regions[0], 0, GL_TRUE); -   brw_update_region_surface(brw, brw->state.draw_region, 0); -   brw->wm.nr_surfaces = 1; +   brw->wm.nr_surfaces = MAX_DRAW_BUFFERS;     for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {        struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[i]; @@ -396,16 +405,16 @@ static void upload_wm_surfaces(struct brw_context *brw )        if(texUnit->_ReallyEnabled &&  	 texUnit->_Current == intel->frame_buffer_texobj)        { -	 dri_bo_unreference(brw->wm.surf_bo[i+1]); -	 brw->wm.surf_bo[i+1] = brw->wm.surf_bo[0]; -	 dri_bo_reference(brw->wm.surf_bo[i+1]); -	 brw->wm.nr_surfaces = i+2; +	 dri_bo_unreference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]); +	 brw->wm.surf_bo[i+MAX_DRAW_BUFFERS] = brw->wm.surf_bo[0]; +	 dri_bo_reference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]); +	 brw->wm.nr_surfaces = i + MAX_DRAW_BUFFERS + 1;        } else if (texUnit->_ReallyEnabled) {  	 brw_update_texture_surface(ctx, i); -	 brw->wm.nr_surfaces = i+2; +	 brw->wm.nr_surfaces = i + MAX_DRAW_BUFFERS + 1;        } else { -	 dri_bo_unreference(brw->wm.surf_bo[i+1]); -	 brw->wm.surf_bo[i+1] = NULL; +	 dri_bo_unreference(brw->wm.surf_bo[i+MAX_DRAW_BUFFERS]); +	 brw->wm.surf_bo[i+MAX_DRAW_BUFFERS] = NULL;        }     } diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index 5199f833e2..2a25f079e9 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -300,6 +300,7 @@ intelWindowMoved(struct intel_context *intel)        default:           intelSetFrontClipRects(intel);        } +	     }     if (!intel->intelScreen->driScrnPriv->dri2.enabled && @@ -894,7 +895,7 @@ void  intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)  {     struct intel_context *intel = intel_context(ctx); -   struct intel_region *colorRegion, *depthRegion = NULL; +   struct intel_region *colorRegions[MAX_DRAW_BUFFERS], *depthRegion = NULL;     struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL;     int front = 0;               /* drawing to front color buffer? */ @@ -933,14 +934,24 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)     /*      * How many color buffers are we drawing into?      */ -   if (fb->_NumColorDrawBuffers != 1) { -      /* writing to 0 or 2 or 4 color buffers */ -      /*_mesa_debug(ctx, "Software rendering\n");*/ +   if (fb->_NumColorDrawBuffers == 0) { +      /* writing to 0  */        FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); -      colorRegion = NULL; +      colorRegions[0] = NULL;        if (fb->Name != 0)  	 intelSetRenderbufferClipRects(intel); +   } else if (fb->_NumColorDrawBuffers > 1) { +       int i; +       struct intel_renderbuffer *irb; +       FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); + +       if (fb->Name != 0) +           intelSetRenderbufferClipRects(intel); +       for (i = 0; i < fb->_NumColorDrawBuffers; i++) { +           irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]); +           colorRegions[i] = (irb && irb->region) ? irb->region : NULL; +       }     }     else {        /* draw to exactly one color buffer */ @@ -958,11 +969,11 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)  	 /* drawing to window system buffer */  	 if (front) {  	    intelSetFrontClipRects(intel); -	    colorRegion = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); +	    colorRegions[0] = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);  	 }  	 else {  	    intelSetBackClipRects(intel); -	    colorRegion = intel_get_rb_region(fb, BUFFER_BACK_LEFT); +	    colorRegions[0]= intel_get_rb_region(fb, BUFFER_BACK_LEFT);  	 }        }        else { @@ -970,7 +981,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)  	 struct intel_renderbuffer *irb;  	 intelSetRenderbufferClipRects(intel);  	 irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]); -	 colorRegion = (irb && irb->region) ? irb->region : NULL; +	 colorRegions[0] = (irb && irb->region) ? irb->region : NULL;        }     } @@ -982,7 +993,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)     else        ctx->NewState |= _NEW_POLYGON; -   if (!colorRegion) { +   if (!colorRegions[0]) {        FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE);     }     else { @@ -1055,7 +1066,8 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)        ctx->NewState |= _NEW_DEPTH;     } -   intel->vtbl.set_draw_region(intel, colorRegion, depthRegion); +   intel->vtbl.set_draw_region(intel, colorRegions, depthRegion,  +	fb->_NumColorDrawBuffers);     /* update viewport since it depends on window size */     if (ctx->Driver.Viewport) { diff --git a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c index fb65e66555..f164b48963 100644 --- a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c @@ -72,6 +72,28 @@ struct intel_validate_entry {      struct drm_i915_op_arg bo_arg;  }; +struct dri_ttm_bo_bucket_entry { +   drmBO drm_bo; +   struct dri_ttm_bo_bucket_entry *next; +}; + +struct dri_ttm_bo_bucket { +   struct dri_ttm_bo_bucket_entry *head; +   struct dri_ttm_bo_bucket_entry **tail; +   /** +    * Limit on the number of entries in this bucket. +    * +    * 0 means that this caching at this bucket size is disabled. +    * -1 means that there is no limit to caching at this size. +    */ +   int max_entries; +   int num_entries; +}; + +/* Arbitrarily chosen, 16 means that the maximum size we'll cache for reuse + * is 1 << 16 pages, or 256MB. + */ +#define INTEL_TTM_BO_BUCKETS	16  typedef struct _dri_bufmgr_ttm {      dri_bufmgr bufmgr; @@ -84,6 +106,9 @@ typedef struct _dri_bufmgr_ttm {      struct intel_validate_entry *validate_array;      int validate_array_size;      int validate_count; + +    /** Array of lists of cached drmBOs of power-of-two sizes */ +    struct dri_ttm_bo_bucket cache_bucket[INTEL_TTM_BO_BUCKETS];  } dri_bufmgr_ttm;  /** @@ -137,6 +162,41 @@ typedef struct _dri_fence_ttm      drmFence drm_fence;  } dri_fence_ttm; +static int +logbase2(int n) +{ +   GLint i = 1; +   GLint log2 = 0; + +   while (n > i) { +      i *= 2; +      log2++; +   } + +   return log2; +} + +static struct dri_ttm_bo_bucket * +dri_ttm_bo_bucket_for_size(dri_bufmgr_ttm *bufmgr_ttm, unsigned long size) +{ +    int i; + +    /* We only do buckets in power of two increments */ +    if ((size & (size - 1)) != 0) +	return NULL; + +    /* We should only see sizes rounded to pages. */ +    assert((size % 4096) == 0); + +    /* We always allocate in units of pages */ +    i = ffs(size / 4096) - 1; +    if (i >= INTEL_TTM_BO_BUCKETS) +	return NULL; + +    return &bufmgr_ttm->cache_bucket[i]; +} + +  static void dri_ttm_dump_validation_list(dri_bufmgr_ttm *bufmgr_ttm)  {      int i, j; @@ -294,8 +354,8 @@ intel_setup_reloc_list(dri_bo *bo)      dri_bo_ttm *bo_ttm = (dri_bo_ttm *)bo;      dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bo->bufmgr; -    bo_ttm->relocs = malloc(sizeof(struct dri_ttm_reloc) * -			    bufmgr_ttm->max_relocs); +    bo_ttm->relocs = calloc(bufmgr_ttm->max_relocs, +			    sizeof(struct dri_ttm_reloc));      bo_ttm->reloc_buf_data = calloc(1, RELOC_BUF_SIZE(bufmgr_ttm->max_relocs));      /* Initialize the relocation list with the header: @@ -338,6 +398,9 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name,      int ret;      uint64_t flags;      unsigned int hint; +    unsigned long alloc_size; +    struct dri_ttm_bo_bucket *bucket; +    GLboolean alloc_from_cache = GL_FALSE;      ttm_buf = calloc(1, sizeof(*ttm_buf));      if (!ttm_buf) @@ -352,13 +415,48 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name,      /* No hints we want to use. */      hint = 0; -    ret = drmBOCreate(bufmgr_ttm->fd, size, alignment / pageSize, -		      NULL, flags, hint, &ttm_buf->drm_bo); -    if (ret != 0) { -	free(ttm_buf); -	return NULL; +    /* Round the allocated size up to a power of two number of pages. */ +    alloc_size = 1 << logbase2(size); +    if (alloc_size < pageSize) +	alloc_size = pageSize; +    bucket = dri_ttm_bo_bucket_for_size(bufmgr_ttm, alloc_size); + +    /* If we don't have caching at this size, don't actually round the +     * allocation up. +     */ +    if (bucket == NULL || bucket->max_entries == 0) +	alloc_size = size; + +    /* Get a buffer out of the cache if available */ +    if (bucket != NULL && bucket->num_entries > 0) { +	struct dri_ttm_bo_bucket_entry *entry = bucket->head; +	int busy; + +	/* Check if the buffer is still in flight.  If not, reuse it. */ +	ret = drmBOBusy(bufmgr_ttm->fd, &entry->drm_bo, &busy); +	alloc_from_cache = (ret == 0 && busy == 0); + +	if (alloc_from_cache) { +	    bucket->head = entry->next; +	    if (entry->next == NULL) +		bucket->tail = &bucket->head; +	    bucket->num_entries--; + +	    ttm_buf->drm_bo = entry->drm_bo; +	    free(entry); +	}      } -    ttm_buf->bo.size = ttm_buf->drm_bo.size; + +    if (!alloc_from_cache) { +	ret = drmBOCreate(bufmgr_ttm->fd, alloc_size, alignment / pageSize, +			  NULL, flags, hint, &ttm_buf->drm_bo); +	if (ret != 0) { +	    free(ttm_buf); +	    return NULL; +	} +    } + +    ttm_buf->bo.size = size;      ttm_buf->bo.offset = ttm_buf->drm_bo.offset;      ttm_buf->bo.virtual = NULL;      ttm_buf->bo.bufmgr = bufmgr; @@ -450,6 +548,7 @@ dri_ttm_bo_unreference(dri_bo *buf)  	return;      if (--ttm_buf->refcount == 0) { +	struct dri_ttm_bo_bucket *bucket;  	int ret;  	assert(ttm_buf->map_count == 0); @@ -476,11 +575,32 @@ dri_ttm_bo_unreference(dri_bo *buf)  	   }  	} -	ret = drmBOUnreference(bufmgr_ttm->fd, &ttm_buf->drm_bo); -	if (ret != 0) { -	    fprintf(stderr, "drmBOUnreference failed (%s): %s\n", -		    ttm_buf->name, strerror(-ret)); +	bucket = dri_ttm_bo_bucket_for_size(bufmgr_ttm, ttm_buf->drm_bo.size); +	/* Put the buffer into our internal cache for reuse if we can. */ +	if (!ttm_buf->shared && +	    bucket != NULL && +	    (bucket->max_entries == -1 || +	     (bucket->max_entries > 0 && +	      bucket->num_entries < bucket->max_entries))) +	{ +	    struct dri_ttm_bo_bucket_entry *entry; + +	    entry = calloc(1, sizeof(*entry)); +	    entry->drm_bo = ttm_buf->drm_bo; + +	    entry->next = NULL; +	    *bucket->tail = entry; +	    bucket->tail = &entry->next; +	    bucket->num_entries++; +	} else { +	    /* Decrement the kernel refcount for the buffer. */ +	    ret = drmBOUnreference(bufmgr_ttm->fd, &ttm_buf->drm_bo); +	    if (ret != 0) { +	       fprintf(stderr, "drmBOUnreference failed (%s): %s\n", +		       ttm_buf->name, strerror(-ret)); +	    }  	} +  	DBG("bo_unreference final: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);  	free(buf); @@ -657,9 +777,34 @@ static void  dri_bufmgr_ttm_destroy(dri_bufmgr *bufmgr)  {      dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr; +    int i;      free(bufmgr_ttm->validate_array); +    /* Free any cached buffer objects we were going to reuse */ +    for (i = 0; i < INTEL_TTM_BO_BUCKETS; i++) { +	struct dri_ttm_bo_bucket *bucket = &bufmgr_ttm->cache_bucket[i]; +	struct dri_ttm_bo_bucket_entry *entry; + +	while ((entry = bucket->head) != NULL) { +	    int ret; + +	    bucket->head = entry->next; +	    if (entry->next == NULL) +		bucket->tail = &bucket->head; +	    bucket->num_entries--; + +	    /* Decrement the kernel refcount for the buffer. */ +	    ret = drmBOUnreference(bufmgr_ttm->fd, &entry->drm_bo); +	    if (ret != 0) { +	       fprintf(stderr, "drmBOUnreference failed: %s\n", +		       strerror(-ret)); +	    } + +	    free(entry); +	} +    } +      free(bufmgr);  } @@ -877,6 +1022,24 @@ dri_ttm_post_submit(dri_bo *batch_buf, dri_fence **last_fence)  }  /** + * Enables unlimited caching of buffer objects for reuse. + * + * This is potentially very memory expensive, as the cache at each bucket + * size is only bounded by how many buffers of that size we've managed to have + * in flight at once. + */ +void +intel_ttm_enable_bo_reuse(dri_bufmgr *bufmgr) +{ +    dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr; +    int i; + +    for (i = 0; i < INTEL_TTM_BO_BUCKETS; i++) { +	bufmgr_ttm->cache_bucket[i].max_entries = -1; +    } +} + +/**   * Initializes the TTM buffer manager, which uses the kernel to allocate, map,   * and manage map buffer objections.   * @@ -890,6 +1053,7 @@ intel_bufmgr_ttm_init(int fd, unsigned int fence_type,  		      unsigned int fence_type_flush, int batch_size)  {      dri_bufmgr_ttm *bufmgr_ttm; +    int i;      bufmgr_ttm = calloc(1, sizeof(*bufmgr_ttm));      bufmgr_ttm->fd = fd; @@ -919,6 +1083,10 @@ intel_bufmgr_ttm_init(int fd, unsigned int fence_type,      bufmgr_ttm->bufmgr.post_submit = dri_ttm_post_submit;      bufmgr_ttm->bufmgr.debug = GL_FALSE; +    /* Initialize the linked lists for BO reuse cache. */ +    for (i = 0; i < INTEL_TTM_BO_BUCKETS; i++) +	bufmgr_ttm->cache_bucket[i].tail = &bufmgr_ttm->cache_bucket[i].head; +      return &bufmgr_ttm->bufmgr;  } diff --git a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.h b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.h index 0738839cef..d267a168cd 100644 --- a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.h +++ b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.h @@ -14,4 +14,7 @@ dri_fence *intel_ttm_fence_create_from_arg(dri_bufmgr *bufmgr, const char *name,  dri_bufmgr *intel_bufmgr_ttm_init(int fd, unsigned int fence_type,  				  unsigned int fence_type_flush, int batch_size); +void +intel_ttm_enable_bo_reuse(dri_bufmgr *bufmgr); +  #endif diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index d3f0681807..e2388dbb09 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -205,7 +205,6 @@ static const struct dri_extension card_extensions[] = {     {"GL_ARB_texture_rectangle", NULL},     {"GL_NV_texture_rectangle", NULL},     {"GL_EXT_texture_rectangle", NULL}, -   {"GL_ARB_point_sprite", NULL},     {"GL_ARB_point_parameters", NULL},      {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},     {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, @@ -231,7 +230,6 @@ static const struct dri_extension card_extensions[] = {     {"GL_EXT_texture_env_dot3", NULL},     {"GL_EXT_texture_filter_anisotropic", NULL},     {"GL_EXT_texture_lod_bias", NULL}, -   {"GL_EXT_texture_sRGB", NULL},     {"GL_3DFX_texture_compression_FXT1", NULL},     {"GL_APPLE_client_storage", NULL},     {"GL_MESA_pack_invert", NULL}, @@ -248,6 +246,7 @@ static const struct dri_extension brw_extensions[] = {     { "GL_ARB_shading_language_120",       GL_VERSION_2_1_functions},     { "GL_ARB_shader_objects",             GL_ARB_shader_objects_functions},     { "GL_ARB_vertex_shader",              GL_ARB_vertex_shader_functions}, +   { "GL_ARB_point_sprite", 		  NULL},     { "GL_ARB_fragment_shader",            NULL },     { "GL_ARB_draw_buffers",               NULL },     { "GL_ARB_depth_texture",              NULL }, @@ -257,6 +256,7 @@ static const struct dri_extension brw_extensions[] = {     /* ARB extn won't work if not enabled */     { "GL_SGIX_depth_texture",             NULL },     { "GL_ARB_texture_env_crossbar",       NULL }, +   { "GL_EXT_texture_sRGB",		  NULL},     { NULL,                                NULL }  }; @@ -456,6 +456,7 @@ intel_init_bufmgr(struct intel_context *intel)         ttm_supported = GL_FALSE;     if (!ttm_disable && ttm_supported) { +      int bo_reuse_mode;        intel->bufmgr = intel_bufmgr_ttm_init(intel->driFd,  					    DRM_FENCE_TYPE_EXE,  					    DRM_FENCE_TYPE_EXE | @@ -463,6 +464,15 @@ intel_init_bufmgr(struct intel_context *intel)  					    BATCH_SZ);        if (intel->bufmgr != NULL)  	 intel->ttm = GL_TRUE; + +      bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse"); +      switch (bo_reuse_mode) { +      case DRI_CONF_BO_REUSE_DISABLED: +	 break; +      case DRI_CONF_BO_REUSE_ALL: +	 intel_ttm_enable_bo_reuse(intel->bufmgr); +	 break; +      }     }     /* Otherwise, use the classic buffer manager. */     if (intel->bufmgr == NULL) { @@ -548,6 +558,9 @@ intelInitContext(struct intel_context *intel,     intel->width = intelScreen->width;     intel->height = intelScreen->height; +   driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, +                       intel->driScreen->myNum, +		       IS_965(intelScreen->deviceID) ? "i965" : "i915");     if (intelScreen->deviceID == PCI_CHIP_I865_G)        intel->maxBatchSize = 4096;     else @@ -556,10 +569,6 @@ intelInitContext(struct intel_context *intel,     if (!intel_init_bufmgr(intel))        return GL_FALSE; -   driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, -                       intel->driScreen->myNum, -		       IS_965(intelScreen->deviceID) ? "i965" : "i915"); -     ctx->Const.MaxTextureMaxAnisotropy = 2.0;     /* This doesn't yet catch all non-conformant rendering, but it's a @@ -855,7 +864,7 @@ intelContendedLock(struct intel_context *intel, GLuint flags)      */     if (dPriv) {        if (sPriv->dri2.enabled) -	 drawable_changed = __driParseEvents(sPriv, dPriv); +	drawable_changed = __driParseEvents(dPriv->driContextPriv, dPriv);        else  	 DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);     } @@ -984,6 +993,7 @@ void LOCK_HARDWARE( struct intel_context *intel )   */  void UNLOCK_HARDWARE( struct intel_context *intel )  { +   intel->vtbl.note_unlock( intel );     intel->locked = 0;     DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index 6c97955b14..1348b0adcf 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -94,8 +94,9 @@ struct intel_context        void (*render_start) (struct intel_context * intel);        void (*render_prevalidate) (struct intel_context * intel);        void (*set_draw_region) (struct intel_context * intel, -                               struct intel_region * draw_region, -                               struct intel_region * depth_region); +                               struct intel_region * draw_regions[], +                               struct intel_region * depth_region, +			       GLuint num_regions);        GLuint (*flush_cmd) (void);        void (*emit_flush) (struct intel_context *intel, GLuint unused); @@ -476,6 +477,11 @@ extern void intelInitStateFuncs(struct dd_function_table *functions);  #define BLENDFACT_INV_CONST_ALPHA	0x0f  #define BLENDFACT_MASK          	0x0f +enum { +   DRI_CONF_BO_REUSE_DISABLED, +   DRI_CONF_BO_REUSE_ALL +}; +  extern int intel_translate_shadow_compare_func(GLenum func);  extern int intel_translate_compare_func(GLenum func);  extern int intel_translate_stencil_op(GLenum op); diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index 94d499f001..b3f6610546 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -517,28 +517,10 @@ intel_framebuffer_renderbuffer(GLcontext * ctx,     intel_draw_buffer(ctx, fb);  } - -/** - * When glFramebufferTexture[123]D is called this function sets up the - * gl_renderbuffer wrapper around the texture image. - * This will have the region info needed for hardware rendering. - */ -static struct intel_renderbuffer * -intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) +static GLboolean +intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb,  +                          struct gl_texture_image *texImage)  { -   const GLuint name = ~0;      /* not significant, but distinct for debugging */ -   struct intel_renderbuffer *irb; - -   /* make an intel_renderbuffer to wrap the texture image */ -   irb = CALLOC_STRUCT(intel_renderbuffer); -   if (!irb) { -      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture"); -      return NULL; -   } - -   _mesa_init_renderbuffer(&irb->Base, name); -   irb->Base.ClassID = INTEL_RB_CLASS; -     if (texImage->TexFormat == &_mesa_texformat_argb8888) {        irb->Base._ActualFormat = GL_RGBA8;        irb->Base._BaseFormat = GL_RGBA; @@ -553,12 +535,15 @@ intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage)        irb->Base._ActualFormat = GL_DEPTH_COMPONENT16;        irb->Base._BaseFormat = GL_DEPTH_COMPONENT;        DBG("Render to DEPTH16 texture OK\n"); +   } else if (texImage->TexFormat == &_mesa_texformat_z24_s8) { +      irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; +      irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; +      DBG("Render to DEPTH_STENCIL texture OK\n");     }     else {        DBG("Render to texture BAD FORMAT %d\n",  	  texImage->TexFormat->MesaFormat); -      _mesa_free(irb); -      return NULL; +      return GL_FALSE;     }     irb->Base.InternalFormat = irb->Base._ActualFormat; @@ -577,6 +562,35 @@ intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage)     irb->RenderToTexture = GL_TRUE; +   return GL_TRUE; +} + +/** + * When glFramebufferTexture[123]D is called this function sets up the + * gl_renderbuffer wrapper around the texture image. + * This will have the region info needed for hardware rendering. + */ +static struct intel_renderbuffer * +intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) +{ +   const GLuint name = ~0;      /* not significant, but distinct for debugging */ +   struct intel_renderbuffer *irb; + +   /* make an intel_renderbuffer to wrap the texture image */ +   irb = CALLOC_STRUCT(intel_renderbuffer); +   if (!irb) { +      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture"); +      return NULL; +   } + +   _mesa_init_renderbuffer(&irb->Base, name); +   irb->Base.ClassID = INTEL_RB_CLASS; + +   if (!intel_update_wrapper(ctx, irb, texImage)) { +      _mesa_free(irb); +      return NULL; +   } +     return irb;  } @@ -613,6 +627,10 @@ intel_render_texture(GLcontext * ctx,           _mesa_render_texture(ctx, fb, att);           return;        } +   } if (!intel_update_wrapper(ctx, irb, newImage)) { +       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); +       _mesa_render_texture(ctx, fb, att); +       return;     }     DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 48dcf07131..55503f45ae 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -110,10 +110,12 @@ intel_miptree_create(struct intel_context *intel,     mt = intel_miptree_create_internal(intel, target, internal_format,  				      first_level, last_level, width0,  				      height0, depth0, cpp, compress_byte); -   if (!mt) +   /* +    * pitch == 0 indicates the null texture +    */ +   if (!mt || !mt->pitch)        return NULL; -   assert (mt->pitch);     mt->region = intel_region_alloc(intel,  				   mt->cpp, mt->pitch, mt->total_height); @@ -180,7 +182,10 @@ int intel_miptree_pitch_align (struct intel_context *intel,  			       struct intel_mipmap_tree *mt,  			       int pitch)  { +#ifdef I915     GLcontext *ctx = &intel->ctx; +#endif +     if (!mt->compressed) {        int pitch_align; @@ -321,7 +326,7 @@ intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,     assert(img < mt->level[level].nr_images); -   mt->level[level].image_offset[img] = (x + y * mt->pitch); +   mt->level[level].image_offset[img] = (x + y * mt->pitch) * mt->cpp;     DBG("%s level %d img %d pos %d,%d image_offset %x\n",         __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]); @@ -352,7 +357,7 @@ intel_miptree_image_offset(struct intel_mipmap_tree *mt,  {     if (mt->target == GL_TEXTURE_CUBE_MAP_ARB)        return (mt->level[level].level_offset + -	      mt->level[level].image_offset[face] * mt->cpp); +	      mt->level[level].image_offset[face]);     else        return mt->level[level].level_offset;  } @@ -363,6 +368,8 @@ intel_miptree_image_offset(struct intel_mipmap_tree *mt,   * Map a teximage in a mipmap tree.   * \param row_stride  returns row stride in bytes   * \param image_stride  returns image stride in bytes (for 3D textures). + * \param image_offsets pointer to array of pixel offsets from the returned + *	  pointer to each depth image   * \return address of mapping   */  GLubyte * @@ -377,12 +384,16 @@ intel_miptree_image_map(struct intel_context * intel,     if (row_stride)        *row_stride = mt->pitch * mt->cpp; -   if (image_offsets) { -      if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) -		   memset(image_offsets, 0, mt->level[level].depth * sizeof(GLuint)); -	  else -		   memcpy(image_offsets, mt->level[level].image_offset, -			   mt->level[level].depth * sizeof(GLuint)); +   if (mt->target == GL_TEXTURE_3D) { +      int i; + +      for (i = 0; i < mt->level[level].depth; i++) +	 image_offsets[i] = mt->level[level].image_offset[i] / mt->cpp; +   } else { +      assert(mt->level[level].depth == 1); +      assert(mt->target == GL_TEXTURE_CUBE_MAP || +	     mt->level[level].image_offset[0] == 0); +      image_offsets[0] = 0;     }     return (intel_region_map(intel, mt->region) + diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index 3c1a6ffa2a..c9537dbb9a 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -62,18 +62,29 @@   */  struct intel_mipmap_level  { +   /** +    * Byte offset to the base of this level. +    * +    * This is used for mipmap levels of 1D/2D/3D textures.  However, CUBE +    * layouts spread images around the whole tree, so the level offset is +    * always zero in that case. +    */     GLuint level_offset;     GLuint width;     GLuint height; +   /** Depth of the mipmap at this level: 1 for 1D/2D/CUBE, n for 3D. */     GLuint depth; +   /** Number of images at this level: 1 for 1D/2D, 6 for CUBE, depth for 3D */     GLuint nr_images; -   /* Explicitly store the offset of each image for each cube face or -    * depth value.  Pretty much have to accept that hardware formats +   /** +    * Byte offset from level_offset to the image for each cube face or depth +    * level. +    * +    * Pretty much have to accept that hardware formats      * are going to be so diverse that there is no unified way to      * compute the offsets of depth/cube images within a mipmap level, -    * so have to store them as a lookup table: -    * NOTE level_offset is a byte offset, but the image_offsets are _pixel_ offsets!!! +    * so have to store them as a lookup table.      */     GLuint *image_offset;  }; diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index 77b6c53cb3..4cb68655f2 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -166,11 +166,8 @@ do_blit_bitmap( GLcontext *ctx,     struct intel_context *intel = intel_context(ctx);     struct intel_region *dst = intel_drawbuf_region(intel);     GLfloat tmpColor[4]; - -   union { -      GLuint ui; -      GLubyte ub[4]; -   } color; +   GLubyte ubcolor[4]; +   GLuint color8888, color565;     if (!dst)         return GL_FALSE; @@ -187,10 +184,13 @@ do_blit_bitmap( GLcontext *ctx,         ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor);     } -   UNCLAMPED_FLOAT_TO_CHAN(color.ub[0], tmpColor[2]); -   UNCLAMPED_FLOAT_TO_CHAN(color.ub[1], tmpColor[1]); -   UNCLAMPED_FLOAT_TO_CHAN(color.ub[2], tmpColor[0]); -   UNCLAMPED_FLOAT_TO_CHAN(color.ub[3], tmpColor[3]); +   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[0], tmpColor[0]); +   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[1], tmpColor[1]); +   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]); +   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]); + +   color8888 = INTEL_PACKCOLOR8888(ubcolor[0], ubcolor[1], ubcolor[2], ubcolor[3]); +   color565 = INTEL_PACKCOLOR565(ubcolor[0], ubcolor[1], ubcolor[2]);     /* Does zoom apply to bitmaps?      */ @@ -289,7 +289,7 @@ do_blit_bitmap( GLcontext *ctx,  						  dst->cpp,  						  (GLubyte *)stipple,   						  sz, -						  color.ui, +						  (dst->cpp == 2) ? color565 : color8888,  						  dst->pitch,  						  dst->buffer,  						  0, diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 8b8eeb77aa..3d46073daa 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -56,6 +56,15 @@ PUBLIC const char __driConfigOptions[] =     DRI_CONF_SECTION_PERFORMANCE        DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)        DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) +      /* Options correspond to DRI_CONF_BO_REUSE_DISABLED, +       * DRI_CONF_BO_REUSE_ALL +       */ +      DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 0, "0:1") +	 DRI_CONF_DESC_BEGIN(en, "Buffer object reuse") +	    DRI_CONF_ENUM(0, "Disable buffer object reuse") +	    DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects") +	 DRI_CONF_DESC_END +      DRI_CONF_OPT_END     DRI_CONF_SECTION_END     DRI_CONF_SECTION_QUALITY        DRI_CONF_FORCE_S3TC_ENABLE(false) @@ -66,7 +75,7 @@ PUBLIC const char __driConfigOptions[] =     DRI_CONF_SECTION_END  DRI_CONF_END; -const GLuint __driNConfigOptions = 5; +const GLuint __driNConfigOptions = 6;  #ifdef USE_NEW_INTERFACE  static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; @@ -284,14 +293,17 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,  static void  intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv, +			  __DRIcontextPrivate *pcp,  			  __DRIDrawableConfigEvent *event)  {     struct intel_framebuffer *intel_fb = dPriv->driverPrivate;     struct intel_region *region = NULL;     struct intel_renderbuffer *rb, *depth_rb, *stencil_rb; -   struct intel_context *intel = dPriv->driContextPriv->driverPrivate; -   int cpp = intel->ctx.Visual.rgbBits / 8; -   GLuint pitch = ((cpp * dPriv->w + 63) & ~63) / cpp; +   struct intel_context *intel = pcp->driverPrivate; +   int cpp, pitch; + +   cpp = intel->ctx.Visual.rgbBits / 8; +   pitch = ((cpp * dPriv->w + 63) & ~63) / cpp;     rb = intel_fb->color_rb[1];     if (rb) { @@ -322,12 +334,13 @@ intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv,  static void  intelHandleBufferAttach(__DRIdrawablePrivate *dPriv, +			__DRIcontextPrivate *pcp,  			__DRIBufferAttachEvent *ba)  {     struct intel_framebuffer *intel_fb = dPriv->driverPrivate;     struct intel_renderbuffer *rb;     struct intel_region *region; -   struct intel_context *intel = dPriv->driContextPriv->driverPrivate; +   struct intel_context *intel = pcp->driverPrivate;     GLuint tiled;     switch (ba->buffer.attachment) { @@ -371,22 +384,6 @@ intelHandleBufferAttach(__DRIdrawablePrivate *dPriv,     intel_renderbuffer_set_region(rb, region);  } -static void -intelUpdateBuffer(__DRIdrawablePrivate *dPriv, unsigned int *event) -{ -   switch (DRI2_EVENT_TYPE(*event)) { -   case DRI2_EVENT_DRAWABLE_CONFIG: -      /* flush all current regions, allocate new ones, except front buffer */ -      intelHandleDrawableConfig(dPriv, (__DRIDrawableConfigEvent *) event); -      break; - -   case DRI2_EVENT_BUFFER_ATTACH: -      /* attach buffer if different from what we have */ -      intelHandleBufferAttach(dPriv, (__DRIBufferAttachEvent *) event); -      break; -   } -} -  static const __DRItexOffsetExtension intelTexOffsetExtension = {     { __DRI_TEX_OFFSET },     intelSetTexOffset, @@ -671,7 +668,9 @@ static const struct __DriverAPIRec intelAPI = {     .WaitForSBC = NULL,     .SwapBuffersMSC = NULL,     .CopySubBuffer = intelCopySubBuffer, -   .UpdateBuffer = intelUpdateBuffer, + +   .HandleDrawableConfig = intelHandleDrawableConfig, +   .HandleBufferAttach = intelHandleBufferAttach,  }; diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c index c110df478f..329af0d1b0 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.c +++ b/src/mesa/drivers/dri/intel/intel_tex.c @@ -1,5 +1,6 @@  #include "swrast/swrast.h"  #include "texobj.h" +#include "teximage.h"  #include "mipmap.h"  #include "intel_context.h"  #include "intel_mipmap_tree.h" @@ -71,7 +72,7 @@ intelFreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage)     }     if (texImage->Data) { -      free(texImage->Data); +      _mesa_free_texmemory(texImage->Data);        texImage->Data = NULL;     }  } diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h index 34995f4ebf..3a87137cc9 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.h +++ b/src/mesa/drivers/dri/intel/intel_tex.h @@ -138,8 +138,7 @@ void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,  void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,  		       unsigned long long offset, GLint depth, GLuint pitch);  void intelSetTexBuffer(__DRIcontext *pDRICtx, -		       GLint target, unsigned long handle, -		       GLint cpp, GLuint pitch, GLuint height); +		       GLint target, __DRIdrawable *pDraw);  GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit); diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index df08ee1a3b..dd8fbeaa91 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -23,6 +23,7 @@  #include "intel_tex.h"  #include "intel_ioctl.h"  #include "intel_blit.h" +#include "intel_fbo.h"  #define FILE_DEBUG_FLAG DEBUG_TEXTURE @@ -359,7 +360,8 @@ intelTexImage(GLcontext * ctx,        assert(!texImage->Data);     }     else if (texImage->Data) { -      _mesa_align_free(texImage->Data); +      _mesa_free_texmemory(texImage->Data); +      texImage->Data = NULL;     }     /* If this is the only texture image in the tree, could call @@ -455,8 +457,6 @@ intelTexImage(GLcontext * ctx,  					   format, type,  					   pixels, unpack, "glTexImage");     } -   if (!pixels) -      return;     LOCK_HARDWARE(intel); @@ -482,7 +482,7 @@ intelTexImage(GLcontext * ctx,           sizeInBytes = depth * dstRowStride * postConvHeight;        } -      texImage->Data = malloc(sizeInBytes); +      texImage->Data = _mesa_alloc_texmemory(sizeInBytes);     }     DBG("Upload image %dx%dx%d row_len %d " @@ -493,27 +493,29 @@ intelTexImage(GLcontext * ctx,      * the blitter to copy.  Or, use the hardware to do the format      * conversion and copy:      */ -   if (compressed) { -       if (intelImage->mt) { -	   struct intel_region *dst = intelImage->mt->region; -	   _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch, -		   0, 0, -		   intelImage->mt->level[level].width, -		   intelImage->mt->level[level].height/4, -		   pixels, -		   srcRowStride, -		   0, 0); -       } else -	    memcpy(texImage->Data, pixels, imageSize); -   } else if (!texImage->TexFormat->StoreImage(ctx, dims,  -					       texImage->_BaseFormat,  -					       texImage->TexFormat,  -					       texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ -					       dstRowStride, -					       texImage->ImageOffsets, -					       width, height, depth, -					       format, type, pixels, unpack)) { -      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); +   if (pixels) { +       if (compressed) { +	   if (intelImage->mt) { +	       struct intel_region *dst = intelImage->mt->region; +	       _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch, +			       0, 0, +			       intelImage->mt->level[level].width, +			       intelImage->mt->level[level].height/4, +			       pixels, +			       srcRowStride, +			       0, 0); +	   } else +	       memcpy(texImage->Data, pixels, imageSize); +       } else if (!texImage->TexFormat->StoreImage(ctx, dims,  +						   texImage->_BaseFormat,  +						   texImage->TexFormat,  +						   texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ +						   dstRowStride, +						   texImage->ImageOffsets, +						   width, height, depth, +						   format, type, pixels, unpack)) { +	   _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); +       }     }     /* GL_SGIS_generate_mipmap */ @@ -694,26 +696,20 @@ intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,  }  void -intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, -		  unsigned long handle, GLint cpp, GLuint pitch, GLuint height) +intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *pDraw)  {     __DRIcontextPrivate *driContext = pDRICtx->private; +   __DRIdrawablePrivate *dPriv = pDraw->private; +   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;     struct intel_context *intel = driContext->driverPrivate;     struct intel_texture_object *intelObj;     struct intel_texture_image *intelImage;     struct intel_mipmap_tree *mt; -   struct intel_region *region; +   struct intel_renderbuffer *rb;     struct gl_texture_unit *texUnit;     struct gl_texture_object *texObj;     struct gl_texture_image *texImage; -   int level = 0; - -   /* FIXME: type, format, internalFormat */ -   int type = GL_BGRA; -   int format = GL_UNSIGNED_BYTE; -   int internalFormat = (cpp == 3 ? 3 : 4); -   cpp = 4; -   pitch /= 4; +   int level = 0, type, format, internalFormat;     texUnit = &intel->ctx.Texture.Unit[intel->ctx.Texture.CurrentUnit];     texObj = _mesa_select_tex_object(&intel->ctx, texUnit, target); @@ -722,12 +718,16 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target,     if (!intelObj)        return; -   region = intel_region_alloc_for_handle(intel, cpp, pitch, height, -					  0, handle); +   __driParseEvents(driContext, dPriv); + +   rb = intel_fb->color_rb[0]; +   type = GL_BGRA; +   format = GL_UNSIGNED_BYTE; +   internalFormat = (rb->region->cpp == 3 ? 3 : 4);     mt = intel_miptree_create_for_region(intel, target,  					internalFormat, -					0, 0, region, 1, 0); +					0, 0, rb->region, 1, 0);     if (mt == NULL)         return; @@ -739,7 +739,7 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target,     intelObj->mt = mt;     texImage = _mesa_get_tex_image(&intel->ctx, texObj, target, level);     _mesa_init_teximage_fields(&intel->ctx, target, texImage, -			      pitch, height, 1, +			      rb->region->pitch, rb->region->height, 1,  			      0, internalFormat);     intelImage = intel_texture_image(texImage); @@ -748,7 +748,7 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target,     texImage->TexFormat = intelChooseTextureFormat(&intel->ctx, internalFormat,                                                    type, format);     _mesa_set_fetch_functions(texImage, 2); -   texImage->RowStride = pitch; +   texImage->RowStride = rb->region->pitch;     intel_miptree_reference(&intelImage->mt, intelObj->mt);     if (!intel_miptree_match_image(intelObj->mt, &intelImage->base, diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c index bd27b86bf3..688e3870df 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c +++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c @@ -50,8 +50,8 @@ intelTexSubimage(GLcontext * ctx,  {     struct intel_context *intel = intel_context(ctx);     struct intel_texture_image *intelImage = intel_texture_image(texImage); -   GLuint dstRowStride; - +   GLuint dstRowStride = 0; +        DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,         _mesa_lookup_enum_by_nr(target),         level, xoffset, yoffset, width, height); @@ -76,6 +76,16 @@ intelTexSubimage(GLcontext * ctx,                                                 intelImage->level,                                                 &dstRowStride,                                                 texImage->ImageOffsets); +   else { +      if (texImage->IsCompressed) { +         dstRowStride = +            _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); +         assert(dims != 3); +      } +      else { +         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes; +      } +   }     assert(dstRowStride); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 9fe8e86870..53d00e17a1 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -214,7 +214,7 @@ static const struct __DriverAPIRec nouveauAPI = {  static __GLcontextModes * -nouveauFillInModes( __DRIscreenPRiv *psp, +nouveauFillInModes( __DRIscreenPrivate *psp,  		    unsigned pixel_bits, unsigned depth_bits,  		    unsigned stencil_bits, GLboolean have_back_buffer )  { @@ -304,7 +304,7 @@ __GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)  		  "  git://anongit.freedesktop.org/git/nouveau/mesa\n");  #if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 -#error nouveau_drm.h version doesn't match expected version +#error nouveau_drm.h version does not match expected version  #endif  	if (!driCheckDriDdxDrmVersions2("nouveau", diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 1abc92ec49..3497738eac 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -377,7 +377,7 @@ void r300InitCmdBuf(r300ContextPtr r300)  	ALLOC_STATE(ri, always, R300_RI_CMDSIZE, 0);  	r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(R300_RS_IP_0, 8);  	ALLOC_STATE(rr, variable, R300_RR_CMDSIZE, 0); -	r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_ROUTE_0, 1); +	r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, 1);  	ALLOC_STATE(sc_hyperz, always, 3, 0);  	r300->hw.sc_hyperz.cmd[0] = cmdpacket0(R300_SC_HYPERZ, 2);  	ALLOC_STATE(sc_screendoor, always, 2, 0); diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 993aa51990..780d9aa5d2 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -331,14 +331,14 @@ struct r300_state_atom {  #define R300_RI_CMDSIZE		9  #define R300_RR_CMD_0		0	/* rr is variable size (at least 1) */ -#define R300_RR_ROUTE_0		1 -#define R300_RR_ROUTE_1		2 -#define R300_RR_ROUTE_2		3 -#define R300_RR_ROUTE_3		4 -#define R300_RR_ROUTE_4		5 -#define R300_RR_ROUTE_5		6 -#define R300_RR_ROUTE_6		7 -#define R300_RR_ROUTE_7		8 +#define R300_RR_INST_0		1 +#define R300_RR_INST_1		2 +#define R300_RR_INST_2		3 +#define R300_RR_INST_3		4 +#define R300_RR_INST_4		5 +#define R300_RR_INST_5		6 +#define R300_RR_INST_6		7 +#define R300_RR_INST_7		8  #define R300_RR_CMDSIZE		9  #define R300_FP_CMD_0		0 diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c index a135376398..deb62b2762 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.c +++ b/src/mesa/drivers/dri/r300/r300_emit.c @@ -210,22 +210,18 @@ static void r300EmitVec(GLcontext * ctx, struct r300_dma_region *rvb,  static GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr,  				 int *inputs, GLint * tab, GLuint nr)  { -	GLuint i, dw; - +	GLushort i, w; +	uint16_t * dst16 = (uint16_t *) dst; +	  	/* type, inputs, stop bit, size */ -	for (i = 0; i + 1 < nr; i += 2) { -		dw = R300_INPUT_ROUTE_FLOAT | (inputs[tab[i]] << 8) | (attribptr[tab[i]]->size - 1); -		dw |= (R300_INPUT_ROUTE_FLOAT | (inputs[tab[i + 1]] << 8) | (attribptr[tab[i + 1]]->size - 1)) << 16; -		if (i + 2 == nr) { -			dw |= (R300_VAP_INPUT_ROUTE_END << 16); +	for (i = 0; i < nr; i++) { +		/* make sure input is valid, would lockup the gpu */ +		assert(inputs[tab[i]] != -1); +		w = R300_INPUT_ROUTE_FLOAT | (inputs[tab[i]] << 8) | (attribptr[tab[i]]->size - 1); +		if (i + 1 == nr) { +			w |= R300_VAP_INPUT_ROUTE_END;  		} -		dst[i >> 1] = dw; -	} - -	if (nr & 1) { -		dw = R300_INPUT_ROUTE_FLOAT | (inputs[tab[nr - 1]] << 8) | (attribptr[tab[nr - 1]]->size - 1); -		dw |= R300_VAP_INPUT_ROUTE_END; -		dst[nr >> 1] = dw; +		dst16[i] = w;  	}  	return (nr + 1) >> 1; @@ -242,14 +238,10 @@ static GLuint r300VAPInputRoute1Swizzle(int swizzle[4])  GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr)  {  	GLuint i; +	uint16_t * dst16 = (uint16_t *) dst; -	for (i = 0; i + 1 < nr; i += 2) { -		dst[i >> 1] = r300VAPInputRoute1Swizzle(swizzle[i]) | R300_INPUT_ROUTE_ENABLE; -		dst[i >> 1] |= (r300VAPInputRoute1Swizzle(swizzle[i + 1]) | R300_INPUT_ROUTE_ENABLE) << 16; -	} - -	if (nr & 1) { -		dst[nr >> 1] = r300VAPInputRoute1Swizzle(swizzle[nr - 1]) | R300_INPUT_ROUTE_ENABLE; +	for (i = 0; i < nr; i++) { +		dst16[i] = r300VAPInputRoute1Swizzle(swizzle[i]) | R300_INPUT_ROUTE_ENABLE;  	}  	return (nr + 1) >> 1; diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 3501ba2d09..1b405889c3 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -284,8 +284,8 @@ static void r300EmitClearState(GLcontext * ctx)  	e32(0x0);  	R300_STATECHANGE(r300, rr); -	reg_start(R300_RS_ROUTE_0, 0); -	e32(R300_RS_ROUTE_0_COLOR); +	reg_start(R300_RS_INST_0, 0); +	e32(R300_RS_INST_COL_CN_WRITE);  	R300_STATECHANGE(r300, fp);  	reg_start(R300_PFS_CNTL_0, 2); diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index 0614c8b2e0..2200cec6ab 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -1175,50 +1175,30 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #define R500_RS_INST_COL_CN_WRITE			(1 << 16)
  #define R500_RS_INST_COL_CN_WRITE_FBUFFER		(2 << 16)
  #define R500_RS_INST_COL_CN_WRITE_BACKFACE		(3 << 16)
 -#define R500_RS_INST_COL_COL_ADDR_SHIFT			18
 +#define R500_RS_INST_COL_ADDR_SHIFT			18
  #define R500_RS_INST_TEX_ADJ				(1 << 25)
  #define R500_RS_INST_W_CN				(1 << 26)
  /* These DWORDs control how vertex data is routed into fragment program   * registers, after interpolators.   */ -#define R300_RS_ROUTE_0                     0x4330 -#define R300_RS_ROUTE_1                     0x4334 -#define R300_RS_ROUTE_2                     0x4338 -#define R300_RS_ROUTE_3                     0x433C /* GUESS */ -#define R300_RS_ROUTE_4                     0x4340 /* GUESS */ -#define R300_RS_ROUTE_5                     0x4344 /* GUESS */ -#define R300_RS_ROUTE_6                     0x4348 /* GUESS */ -#define R300_RS_ROUTE_7                     0x434C /* GUESS */ -#       define R300_RS_ROUTE_SOURCE_INTERP_0     0 -#       define R300_RS_ROUTE_SOURCE_INTERP_1     1 -#       define R300_RS_ROUTE_SOURCE_INTERP_2     2 -#       define R300_RS_ROUTE_SOURCE_INTERP_3     3 -#       define R300_RS_ROUTE_SOURCE_INTERP_4     4 -#       define R300_RS_ROUTE_SOURCE_INTERP_5     5 /* GUESS */ -#       define R300_RS_ROUTE_SOURCE_INTERP_6     6 /* GUESS */ -#       define R300_RS_ROUTE_SOURCE_INTERP_7     7 /* GUESS */ -#       define R300_RS_ROUTE_ENABLE              (1 << 3) /* GUESS */ -#       define R300_RS_ROUTE_DEST_SHIFT          6 -#       define R300_RS_ROUTE_DEST_MASK           (31 << 6) /* GUESS */ +#define R300_RS_INST_0                     0x4330 +#define R300_RS_INST_1                     0x4334 +#define R300_RS_INST_2                     0x4338 +#define R300_RS_INST_3                     0x433C /* GUESS */ +#define R300_RS_INST_4                     0x4340 /* GUESS */ +#define R300_RS_INST_5                     0x4344 /* GUESS */ +#define R300_RS_INST_6                     0x4348 /* GUESS */ +#define R300_RS_INST_7                     0x434C /* GUESS */ +#	define R300_RS_INST_TEX_ID(x)  		((x) << 0) +#	define R300_RS_INST_TEX_CN_WRITE 	(1 << 3) +#	define R300_RS_INST_TEX_ADDR_SHIFT 	6 +#	define R300_RS_INST_COL_ID(x)		((x) << 11) +#	define R300_RS_INST_COL_CN_WRITE	(1 << 14) +#	define R300_RS_INST_COL_ADDR_SHIFT	17 +#	define R300_RS_INST_TEX_ADJ		(1 << 22) +#	define R300_RS_COL_BIAS_UNUSED_SHIFT    23 -/* Special handling for color: When the fragment program uses color, - * the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the - * color register index. - * - * Apperently you may set the R300_RS_ROUTE_0_COLOR bit, but not provide any - * R300_RS_ROUTE_0_COLOR_DEST value; this setup is used for clearing the state. - * See r300_ioctl.c:r300EmitClearState. I'm not sure if this setup is strictly - * correct or not. - Oliver. - */ -#       define R300_RS_ROUTE_0_COLOR             (1 << 14) -#       define R300_RS_ROUTE_0_COLOR_DEST_SHIFT  17 -#       define R300_RS_ROUTE_0_COLOR_DEST_MASK   (31 << 17) /* GUESS */ -/* As above, but for secondary color */ -#		define R300_RS_ROUTE_1_COLOR1            (1 << 14) -#		define R300_RS_ROUTE_1_COLOR1_DEST_SHIFT 17 -#		define R300_RS_ROUTE_1_COLOR1_DEST_MASK  (31 << 17) -#		define R300_RS_ROUTE_1_UNKNOWN11         (1 << 11)  /* END: Rasterization / Interpolators - many guesses */  /* Hierarchical Z Enable */ @@ -1890,7 +1870,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  /* Fog: Green Component of Fog Color */  #define FG_FOG_COLOR_G                           0x4bcc  /* Fog: Blue Component of Fog Color */ -#define FG_FOG_COLOR_B                           0x4db0 +#define FG_FOG_COLOR_B                           0x4bd0  #	define FG_FOG_COLOR_MASK 0x000001ff  /* Fog: Constant Factor for Fog Blending */ @@ -2262,6 +2242,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #define ZB_STENCILREFMASK                        0x4f08  #	define ZB_STENCILREFMASK_STENCILREF_SHIFT       0 +#	define ZB_STENCILREFMASK_STENCIL_MASK           0xff  #	define ZB_STENCILREFMASK_STENCILREF_MASK        0x000000ff  #	define ZB_STENCILREFMASK_STENCILMASK_SHIFT      8  #	define ZB_STENCILREFMASK_STENCILMASK_MASK       0x0000ff00 @@ -2290,8 +2271,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #       define ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE (1 << 0)  #       define ZB_ZCACHE_CTLSTAT_ZC_FREE_NO_EFFECT       (0 << 1)  #       define ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE            (1 << 1) -#       define ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE            (0 << 1) -#       define ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY            (1 << 1) +#       define ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE            (0 << 31) +#       define ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY            (1 << 31)  #define R300_ZB_BW_CNTL                     0x4f1c  #	define R300_HIZ_DISABLE                              (0 << 0) diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index c4de022d84..e11b5afc30 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -932,8 +932,8 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,  						 R300_RB3D_ZS1_BACK_FUNC_SHIFT));  	rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= -	    ~((ZB_STENCILREFMASK_STENCILREF_MASK << ZB_STENCILREFMASK_STENCILREF_SHIFT) | -	      (ZB_STENCILREFMASK_STENCILMASK_MASK << ZB_STENCILREFMASK_STENCILMASK_SHIFT)); +	    ~((ZB_STENCILREFMASK_STENCIL_MASK << ZB_STENCILREFMASK_STENCILREF_SHIFT) | +	      (ZB_STENCILREFMASK_STENCIL_MASK << ZB_STENCILREFMASK_STENCILMASK_SHIFT));  	flag = translate_func(ctx->Stencil.Function[0]);  	rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= @@ -953,11 +953,12 @@ static void r300StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask)  	R300_STATECHANGE(rmesa, zs);  	rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= -	    ~(ZB_STENCILREFMASK_STENCILMASK_MASK << +	    ~(ZB_STENCILREFMASK_STENCIL_MASK <<  	      ZB_STENCILREFMASK_STENCILWRITEMASK_SHIFT);  	rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |=  	    (ctx->Stencil. -	     WriteMask[0] & 0xff) << ZB_STENCILREFMASK_STENCILWRITEMASK_SHIFT; +	     WriteMask[0] & ZB_STENCILREFMASK_STENCIL_MASK) << +	     ZB_STENCILREFMASK_STENCILWRITEMASK_SHIFT;  }  static void r300StencilOpSeparate(GLcontext * ctx, GLenum face, @@ -1004,11 +1005,10 @@ static void r300ClearStencil(GLcontext * ctx, GLint s)  	r300ContextPtr rmesa = R300_CONTEXT(ctx);  	rmesa->state.stencil.clear = -	    ((GLuint) (ctx->Stencil.Clear & 0xff) | -	     (ZB_STENCILREFMASK_STENCILMASK_MASK << -	      ZB_STENCILREFMASK_STENCILMASK_SHIFT) | ((ctx->Stencil. -						    WriteMask[0] & 0xff) << -						   ZB_STENCILREFMASK_STENCILMASK_SHIFT)); +	    ((GLuint) (ctx->Stencil.Clear & ZB_STENCILREFMASK_STENCIL_MASK) | +	     (ZB_STENCILREFMASK_STENCIL_MASK << ZB_STENCILREFMASK_STENCILMASK_SHIFT) | +	     ((ctx->Stencil.WriteMask[0] & ZB_STENCILREFMASK_STENCIL_MASK) << +		ZB_STENCILREFMASK_STENCILMASK_SHIFT));  }  /* ============================================================= @@ -1522,7 +1522,7 @@ static void r300SetupRSUnit(GLcontext * ctx)  	fp_reg = in_texcoords = col_interp_nr = high_rr = 0; -	r300->hw.rr.cmd[R300_RR_ROUTE_1] = 0; +	r300->hw.rr.cmd[R300_RR_INST_1] = 0;  	if (InputsRead & FRAG_BIT_WPOS) {  		for (i = 0; i < ctx->Const.MaxTextureUnits; i++) @@ -1542,11 +1542,11 @@ static void r300SetupRSUnit(GLcontext * ctx)  		r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = 0 | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3) | (in_texcoords << R300_RS_INTERP_SRC_SHIFT)  		    | interp_magic[i]; -		r300->hw.rr.cmd[R300_RR_ROUTE_0 + fp_reg] = 0; +		r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] = 0;  		if (InputsRead & (FRAG_BIT_TEX0 << i)) {  			//assert(r300->state.texture.tc_count != 0); -			r300->hw.rr.cmd[R300_RR_ROUTE_0 + fp_reg] |= R300_RS_ROUTE_ENABLE | i	/* source INTERP */ -			    | (fp_reg << R300_RS_ROUTE_DEST_SHIFT); +			r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] |= R300_RS_INST_TEX_CN_WRITE | i	/* source INTERP */ +			    | (fp_reg << R300_RS_INST_TEX_ADDR_SHIFT);  			high_rr = fp_reg;  			/* Passing invalid data here can lock the GPU. */ @@ -1565,7 +1565,7 @@ static void r300SetupRSUnit(GLcontext * ctx)  	if (InputsRead & FRAG_BIT_COL0) {  		if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL0, _TNL_ATTRIB_COLOR0)) { -			r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0 | R300_RS_ROUTE_0_COLOR | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT); +			r300->hw.rr.cmd[R300_RR_INST_0] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE | (fp_reg++ << R300_RS_INST_COL_ADDR_SHIFT);  			InputsRead &= ~FRAG_BIT_COL0;  			col_interp_nr++;  		} else { @@ -1575,7 +1575,7 @@ static void r300SetupRSUnit(GLcontext * ctx)  	if (InputsRead & FRAG_BIT_COL1) {  		if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1)) { -			r300->hw.rr.cmd[R300_RR_ROUTE_1] |= R300_RS_ROUTE_1_UNKNOWN11 | R300_RS_ROUTE_1_COLOR1 | (fp_reg++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT); +			r300->hw.rr.cmd[R300_RR_INST_1] |= R300_RS_INST_COL_ID(1) | R300_RS_INST_COL_CN_WRITE | (fp_reg++ << R300_RS_INST_COL_ADDR_SHIFT);  			InputsRead &= ~FRAG_BIT_COL1;  			if (high_rr < 1)  				high_rr = 1; @@ -1587,7 +1587,7 @@ static void r300SetupRSUnit(GLcontext * ctx)  	/* Need at least one. This might still lock as the values are undefined... */  	if (in_texcoords == 0 && col_interp_nr == 0) { -		r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0 | R300_RS_ROUTE_0_COLOR | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT); +		r300->hw.rr.cmd[R300_RR_INST_0] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE | (fp_reg++ << R300_RS_INST_COL_ADDR_SHIFT);  		col_interp_nr++;  	} @@ -1596,7 +1596,7 @@ static void r300SetupRSUnit(GLcontext * ctx)  	  | R300_HIRES_EN;  	assert(high_rr >= 0); -	r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_ROUTE_0, high_rr + 1); +	r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, high_rr + 1);  	r300->hw.rc.cmd[2] = 0xC0 | high_rr;  	if (InputsRead) diff --git a/src/mesa/drivers/dri/radeon/radeon_chipset.h b/src/mesa/drivers/dri/radeon/radeon_chipset.h index 4dece95a98..6ad441bdd0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_chipset.h +++ b/src/mesa/drivers/dri/radeon/radeon_chipset.h @@ -149,6 +149,7 @@  #define PCI_CHIP_RS350_7834		0x7834  #define PCI_CHIP_RS350_7835		0x7835  #define PCI_CHIP_RS690_791E             0x791E +#define PCI_CHIP_RS690_791F             0x791F  enum {     CHIP_FAMILY_R100, diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 93b239ae9f..d6caa2ac89 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -557,7 +557,11 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )        screen->chip_family = CHIP_FAMILY_RS300;        break; +      /* 9500 with 1 pipe verified by: Reid Linnemann <lreid@cs.okstate.edu> */     case PCI_CHIP_R300_AD: +      screen->chip_family = CHIP_FAMILY_RV350; +      screen->chip_flags = RADEON_CHIPSET_TCL; +      break;     case PCI_CHIP_R300_AE:     case PCI_CHIP_R300_AF:     case PCI_CHIP_R300_AG: diff --git a/src/mesa/glapi/glX_proto_send.py b/src/mesa/glapi/glX_proto_send.py index 6207b00a94..b00b8a1ba6 100644 --- a/src/mesa/glapi/glX_proto_send.py +++ b/src/mesa/glapi/glX_proto_send.py @@ -373,7 +373,7 @@ const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };  				print '{'  				print '    __GLXcontext * const gc = __glXGetCurrentContext();'  				print '' -				print '    if (gc->isDirect) {' +				print '    if (gc->driContext) {'  				print '    %sCALL_%s(GET_DISPATCH(), (%s));' % (ret_string, func.name, func.get_called_parameter_string())  				print '    } else {'  				footer = '}\n}\n' diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 66e6aadc0f..c3c1f927fd 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -47,10 +47,10 @@  #include "stencil.h"  #include "texobj.h"  #include "texstate.h" +#include "varray.h"  #include "mtypes.h"  #include "math/m_xform.h" -  /**   * Special struct for saving/restoring texture state (GL_TEXTURE_BIT)   */ @@ -1401,7 +1401,7 @@ _mesa_PopClientAttrib(void)              ctx->Array.ActiveTexture = data->ActiveTexture;  	    if (data->LockCount != 0)  	       _mesa_LockArraysEXT(data->LockFirst, data->LockCount); -	    else +	    else if (ctx->Array.LockCount)  	       _mesa_UnlockArraysEXT();  	    _mesa_BindVertexArrayAPPLE( data->ArrayObj->Name ); diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 9ad2dccc12..eb418610a7 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -1,8 +1,8 @@  /*   * Mesa 3-D graphics library - * Version:  6.5.1 + * Version:  7.1   * - * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved. + * Copyright (C) 1999-2008  Brian Paul   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"), @@ -565,6 +565,143 @@ _mesa_validate_pbo_access(GLuint dimensions,  /** + * If the source of glBitmap data is a PBO, check that we won't read out + * of buffer bounds, then map the buffer. + * If not sourcing from a PBO, just return the bitmap pointer. + * This is a helper function for (some) drivers. + * Return NULL if error. + * If non-null return, must call _mesa_unmap_bitmap_pbo() when done. + */ +const GLubyte * +_mesa_map_bitmap_pbo(GLcontext *ctx, +                     const struct gl_pixelstore_attrib *unpack, +                     const GLubyte *bitmap) +{ +   const GLubyte *buf; + +   if (unpack->BufferObj->Name) { +      /* unpack from PBO */ +      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, +                                              GL_READ_ONLY_ARB, +                                              unpack->BufferObj); +      if (!buf) +         return NULL; + +      buf = ADD_POINTERS(buf, bitmap); +   } +   else { +      /* unpack from normal memory */ +      buf = bitmap; +   } + +   return buf; +} + + +/** + * Counterpart to _mesa_map_bitmap_pbo() + * This is a helper function for (some) drivers. + */ +void +_mesa_unmap_bitmap_pbo(GLcontext *ctx, +                       const struct gl_pixelstore_attrib *unpack) +{ +   if (unpack->BufferObj->Name) { +      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, +                              unpack->BufferObj); +   } +} + + +/** + * \sa _mesa_map_bitmap_pbo + */ +const GLvoid * +_mesa_map_drawpix_pbo(GLcontext *ctx, +                      const struct gl_pixelstore_attrib *unpack, +                      const GLvoid *pixels) +{ +   const GLvoid *buf; + +   if (unpack->BufferObj->Name) { +      /* unpack from PBO */ +      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, +                                              GL_READ_ONLY_ARB, +                                              unpack->BufferObj); +      if (!buf) +         return NULL; + +      buf = ADD_POINTERS(buf, pixels); +   } +   else { +      /* unpack from normal memory */ +      buf = pixels; +   } + +   return buf; +} + + +/** + * \sa _mesa_unmap_bitmap_pbo + */ +void +_mesa_unmap_drapix_pbo(GLcontext *ctx, +                       const struct gl_pixelstore_attrib *unpack) +{ +   if (unpack->BufferObj->Name) { +      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, +                              unpack->BufferObj); +   } +} + + +/** + * If PBO is bound, map the buffer, return dest pointer in mapped buffer. + * Call _mesa_unmap_readpix_pbo() when finished + * \return NULL if error + */ +void * +_mesa_map_readpix_pbo(GLcontext *ctx, +                      const struct gl_pixelstore_attrib *pack, +                      GLvoid *dest) +{ +   void *buf; + +   if (pack->BufferObj->Name) { +      /* pack into PBO */ +      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, +                                              GL_WRITE_ONLY_ARB, +                                              pack->BufferObj); +      if (!buf) +         return NULL; + +      buf = ADD_POINTERS(buf, dest); +   } +   else { +      /* pack to normal memory */ +      buf = dest; +   } + +   return buf; +} + + +/** + * Counterpart to _mesa_map_readpix_pbo() + */ +void +_mesa_unmap_readpix_pbo(GLcontext *ctx, +                        const struct gl_pixelstore_attrib *pack) +{ +   if (pack->BufferObj->Name) { +      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, pack->BufferObj); +   } +} + + + +/**   * Return the gl_buffer_object for the given ID.   * Always return NULL for ID 0.   */ diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h index 1d2715da84..8baa59d617 100644 --- a/src/mesa/main/bufferobj.h +++ b/src/mesa/main/bufferobj.h @@ -1,8 +1,8 @@  /*   * Mesa 3-D graphics library - * Version:  6.3 + * Version:  7.1   * - * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved. + * Copyright (C) 1999-2008  Brian Paul   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"), @@ -89,6 +89,35 @@ _mesa_validate_pbo_access(GLuint dimensions,                            GLsizei width, GLsizei height, GLsizei depth,                            GLenum format, GLenum type, const GLvoid *ptr); +extern const GLubyte * +_mesa_map_bitmap_pbo(GLcontext *ctx, +                     const struct gl_pixelstore_attrib *unpack, +                     const GLubyte *bitmap); + +extern void +_mesa_unmap_bitmap_pbo(GLcontext *ctx, +                       const struct gl_pixelstore_attrib *unpack); + +extern const GLvoid * +_mesa_map_drawpix_pbo(GLcontext *ctx, +                      const struct gl_pixelstore_attrib *unpack, +                      const GLvoid *pixels); + +extern void +_mesa_unmap_drapix_pbo(GLcontext *ctx, +                       const struct gl_pixelstore_attrib *unpack); + + +extern void * +_mesa_map_readpix_pbo(GLcontext *ctx, +                      const struct gl_pixelstore_attrib *pack, +                      GLvoid *dest); + +extern void +_mesa_unmap_readpix_pbo(GLcontext *ctx, +                        const struct gl_pixelstore_attrib *pack); + +  extern void  _mesa_unbind_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj ); diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 69c361f63e..62d592767d 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -706,10 +706,10 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )     _mesa_DeleteHashTable(ss->Programs);  #endif  #if FEATURE_ARB_vertex_program -   _mesa_delete_program(ctx, ss->DefaultVertexProgram); +   ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);  #endif  #if FEATURE_ARB_fragment_program -   _mesa_delete_program(ctx, ss->DefaultFragmentProgram); +   ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);  #endif  #if FEATURE_ATI_fragment_shader @@ -777,7 +777,7 @@ _mesa_init_current(GLcontext *ctx)     }     /* redo special cases: */ -   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 1.0 ); +   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 );     ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );     ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );     ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 ); diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index a421d04957..8d10d8a750 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -5578,6 +5578,27 @@ save_VertexAttrib4fvARB(GLuint index, const GLfloat * v)  } +/* GL_ARB_shader_objects, GL_ARB_vertex/fragment_shader */ + +static void GLAPIENTRY +exec_BindAttribLocationARB(GLuint program, GLuint index, const GLchar *name) +{ +   GET_CURRENT_CONTEXT(ctx); +   FLUSH_VERTICES(ctx, 0); +   CALL_BindAttribLocationARB(ctx->Exec, (program, index, name)); +} + +static GLint GLAPIENTRY +exec_GetAttribLocationARB(GLuint program, const GLchar *name) +{ +   GET_CURRENT_CONTEXT(ctx); +   FLUSH_VERTICES(ctx, 0); +   return CALL_GetAttribLocationARB(ctx->Exec, (program, name)); +} +/* XXX more shader functions needed here */ + + +  #if FEATURE_EXT_framebuffer_blit  static void GLAPIENTRY  save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, @@ -8111,6 +8132,11 @@ _mesa_init_dlist_table(struct _glapi_table *table)     SET_BlitFramebufferEXT(table, save_BlitFramebufferEXT);  #endif +   /* ARB 30/31/32. GL_ARB_shader_objects, GL_ARB_vertex/fragment_shader */ +   SET_BindAttribLocationARB(table, exec_BindAttribLocationARB); +   SET_GetAttribLocationARB(table, exec_GetAttribLocationARB); +   /* XXX additional functions need to be implemented here! */ +     /* 299. GL_EXT_blend_equation_separate */     SET_BlendEquationSeparateEXT(table, save_BlendEquationSeparateEXT); diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index c82abccc41..4f28766674 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -1,8 +1,8 @@  /*   * Mesa 3-D graphics library - * Version:  6.5 + * Version:  7.1   * - * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved. + * Copyright (C) 1999-2008  Brian Paul   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"), @@ -24,6 +24,7 @@  #include "glheader.h"  #include "imports.h" +#include "bufferobj.h"  #include "context.h"  #include "drawpix.h"  #include "feedback.h" @@ -105,8 +106,7 @@ error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,        }        break;     case GL_DEPTH_COMPONENT: -      if ((drawing && !_mesa_dest_buffer_exists(ctx, format)) || -          (!drawing && !_mesa_source_buffer_exists(ctx, format))) { +      if (!drawing && !_mesa_source_buffer_exists(ctx, format)) {           _mesa_error(ctx, GL_INVALID_OPERATION,                       "gl%sPixels(no depth buffer)", readDraw);           return GL_TRUE; @@ -183,6 +183,23 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,        /* Round, to satisfy conformance tests (matches SGI's OpenGL) */        GLint x = IROUND(ctx->Current.RasterPos[0]);        GLint y = IROUND(ctx->Current.RasterPos[1]); + +      if (ctx->Unpack.BufferObj->Name) { +         /* unpack from PBO */ +         if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1, +                                        format, type, pixels)) { +            _mesa_error(ctx, GL_INVALID_OPERATION, +                        "glDrawPixels(invalid PBO access)"); +            return; +         } +         if (ctx->Unpack.BufferObj->Pointer) { +            /* buffer is mapped - that's an error */ +            _mesa_error(ctx, GL_INVALID_OPERATION, +                        "glDrawPixels(PBO is mapped)"); +            return; +         } +      } +        ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type,  			     &ctx->Unpack, pixels);     } @@ -301,6 +318,21 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,        return;     } +   if (ctx->Pack.BufferObj->Name) { +      if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1, +                                     format, type, pixels)) { +         _mesa_error(ctx, GL_INVALID_OPERATION, +                     "glReadPixels(invalid PBO access)"); +         return; +      } + +      if (ctx->Pack.BufferObj->Pointer) { +         /* buffer is mapped - that's an error */ +         _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)"); +         return; +      } +   } +     ctx->Driver.ReadPixels(ctx, x, y, width, height,  			  format, type, &ctx->Pack, pixels);  } @@ -341,12 +373,27 @@ _mesa_Bitmap( GLsizei width, GLsizei height,     }     if (ctx->RenderMode == GL_RENDER) { -      if (bitmap) { -         /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */ -         GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig); -         GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig); -         ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap ); +      /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */ +      GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig); +      GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig); + +      if (ctx->Unpack.BufferObj->Name) { +         /* unpack from PBO */ +         if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1, +                                        GL_COLOR_INDEX, GL_BITMAP, +                                        (GLvoid *) bitmap)) { +            _mesa_error(ctx, GL_INVALID_OPERATION, +                        "glBitmap(invalid PBO access)"); +            return; +         } +         if (ctx->Unpack.BufferObj->Pointer) { +            /* buffer is mapped - that's an error */ +            _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)"); +            return; +         }        } + +      ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );     }  #if _HAVE_FULL_GL     else if (ctx->RenderMode == GL_FEEDBACK) { diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 671f80c7a4..9b60c73294 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -303,7 +303,7 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format,              /* OK */           }           else if (ctx->Extensions.EXT_packed_depth_stencil && -                  att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) { +                  texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {              /* OK */           }           else { diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index eb81ee4a52..9d8f2002c9 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -870,6 +870,14 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )        case GL_TEXTURE_3D:           params[0] = _mesa_IsEnabled(GL_TEXTURE_3D);           break; +      case GL_TEXTURE_1D_ARRAY_EXT: +         CHECK_EXT1(MESA_texture_array, "GetBooleanv"); +         params[0] = _mesa_IsEnabled(GL_TEXTURE_1D_ARRAY_EXT); +         break; +      case GL_TEXTURE_2D_ARRAY_EXT: +         CHECK_EXT1(MESA_texture_array, "GetBooleanv"); +         params[0] = _mesa_IsEnabled(GL_TEXTURE_2D_ARRAY_EXT); +         break;        case GL_TEXTURE_BINDING_1D:           params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1D->Name);           break; @@ -879,6 +887,14 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )        case GL_TEXTURE_BINDING_3D:           params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current3D->Name);           break; +      case GL_TEXTURE_BINDING_1D_ARRAY_EXT: +         CHECK_EXT1(MESA_texture_array, "GetBooleanv"); +         params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1DArray->Name); +         break; +      case GL_TEXTURE_BINDING_2D_ARRAY_EXT: +         CHECK_EXT1(MESA_texture_array, "GetBooleanv"); +         params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current2DArray->Name); +         break;        case GL_TEXTURE_ENV_COLOR:           {           const GLfloat *color = ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvColor; @@ -1864,6 +1880,10 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )           CHECK_EXT1(EXT_framebuffer_object, "GetBooleanv");           params[0] = INT_TO_BOOLEAN(ctx->Const.MaxRenderbufferSize);           break; +      case GL_READ_FRAMEBUFFER_BINDING_EXT: +         CHECK_EXT1(EXT_framebuffer_blit, "GetBooleanv"); +         params[0] = INT_TO_BOOLEAN(ctx->ReadBuffer->Name); +         break;        case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB:           CHECK_EXT1(ARB_fragment_shader, "GetBooleanv");           params[0] = INT_TO_BOOLEAN(ctx->Const.FragmentProgram.MaxUniformComponents); @@ -2701,6 +2721,14 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )        case GL_TEXTURE_3D:           params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_3D));           break; +      case GL_TEXTURE_1D_ARRAY_EXT: +         CHECK_EXT1(MESA_texture_array, "GetFloatv"); +         params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_1D_ARRAY_EXT)); +         break; +      case GL_TEXTURE_2D_ARRAY_EXT: +         CHECK_EXT1(MESA_texture_array, "GetFloatv"); +         params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_2D_ARRAY_EXT)); +         break;        case GL_TEXTURE_BINDING_1D:           params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1D->Name);           break; @@ -2710,6 +2738,14 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )        case GL_TEXTURE_BINDING_3D:           params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current3D->Name);           break; +      case GL_TEXTURE_BINDING_1D_ARRAY_EXT: +         CHECK_EXT1(MESA_texture_array, "GetFloatv"); +         params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1DArray->Name); +         break; +      case GL_TEXTURE_BINDING_2D_ARRAY_EXT: +         CHECK_EXT1(MESA_texture_array, "GetFloatv"); +         params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current2DArray->Name); +         break;        case GL_TEXTURE_ENV_COLOR:           {           const GLfloat *color = ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvColor; @@ -3695,6 +3731,10 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )           CHECK_EXT1(EXT_framebuffer_object, "GetFloatv");           params[0] = (GLfloat)(ctx->Const.MaxRenderbufferSize);           break; +      case GL_READ_FRAMEBUFFER_BINDING_EXT: +         CHECK_EXT1(EXT_framebuffer_blit, "GetFloatv"); +         params[0] = (GLfloat)(ctx->ReadBuffer->Name); +         break;        case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB:           CHECK_EXT1(ARB_fragment_shader, "GetFloatv");           params[0] = (GLfloat)(ctx->Const.FragmentProgram.MaxUniformComponents); @@ -4532,6 +4572,14 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )        case GL_TEXTURE_3D:           params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_3D));           break; +      case GL_TEXTURE_1D_ARRAY_EXT: +         CHECK_EXT1(MESA_texture_array, "GetIntegerv"); +         params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_1D_ARRAY_EXT)); +         break; +      case GL_TEXTURE_2D_ARRAY_EXT: +         CHECK_EXT1(MESA_texture_array, "GetIntegerv"); +         params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_2D_ARRAY_EXT)); +         break;        case GL_TEXTURE_BINDING_1D:           params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1D->Name;           break; @@ -4541,6 +4589,14 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )        case GL_TEXTURE_BINDING_3D:           params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current3D->Name;           break; +      case GL_TEXTURE_BINDING_1D_ARRAY_EXT: +         CHECK_EXT1(MESA_texture_array, "GetIntegerv"); +         params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1DArray->Name; +         break; +      case GL_TEXTURE_BINDING_2D_ARRAY_EXT: +         CHECK_EXT1(MESA_texture_array, "GetIntegerv"); +         params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current2DArray->Name; +         break;        case GL_TEXTURE_ENV_COLOR:           {           const GLfloat *color = ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvColor; @@ -5526,6 +5582,10 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )           CHECK_EXT1(EXT_framebuffer_object, "GetIntegerv");           params[0] = ctx->Const.MaxRenderbufferSize;           break; +      case GL_READ_FRAMEBUFFER_BINDING_EXT: +         CHECK_EXT1(EXT_framebuffer_blit, "GetIntegerv"); +         params[0] = ctx->ReadBuffer->Name; +         break;        case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB:           CHECK_EXT1(ARB_fragment_shader, "GetIntegerv");           params[0] = ctx->Const.FragmentProgram.MaxUniformComponents; diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py index 9055433281..819a7cc5d7 100644 --- a/src/mesa/main/get_gen.py +++ b/src/mesa/main/get_gen.py @@ -983,6 +983,11 @@ StateVars = [  	  ["ctx->Const.MaxRenderbufferSize"], "",  	  ["EXT_framebuffer_object"] ), +	# GL_EXT_framebuffer_blit +	# NOTE: GL_DRAW_FRAMEBUFFER_BINDING_EXT == GL_FRAMEBUFFER_BINDING_EXT +	( "GL_READ_FRAMEBUFFER_BINDING_EXT", GLint, ["ctx->ReadBuffer->Name"], "", +	  ["EXT_framebuffer_blit"] ), +  	# GL_ARB_fragment_shader  	( "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB", GLint,  	  ["ctx->Const.FragmentProgram.MaxUniformComponents"], "", diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h index 2d2da49fe5..bab962ad5e 100644 --- a/src/mesa/main/glheader.h +++ b/src/mesa/main/glheader.h @@ -237,7 +237,7 @@  #endif -#if (!defined(__GNUC__) || __GNUC__ < 3) && !defined(__IBMC__) +#if (!defined(__GNUC__) || __GNUC__ < 3) && (!defined(__IBMC__) || __IBMC__ < 900)  #  define __builtin_expect(x, y) x  #endif diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index 3ae56c8b0b..1aebb25163 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -104,6 +104,8 @@ _mesa_align_malloc(size_t bytes, unsigned long alignment)     (void) posix_memalign(& mem, alignment, bytes);     return mem; +#elif defined(_WIN32) && defined(_MSC_VER) +   return _aligned_malloc(bytes, alignment);  #else     uintptr_t ptr, buf; @@ -144,6 +146,15 @@ _mesa_align_calloc(size_t bytes, unsigned long alignment)     }     return mem; +#elif defined(_WIN32) && defined(_MSC_VER) +   void *mem; + +   mem = _aligned_malloc(bytes, alignment); +   if (mem != NULL) { +      (void) memset(mem, 0, bytes); +   } + +   return mem;  #else     uintptr_t ptr, buf; @@ -180,6 +191,8 @@ _mesa_align_free(void *ptr)  {  #if defined(HAVE_POSIX_MEMALIGN)     free(ptr); +#elif defined(_WIN32) && defined(_MSC_VER) +   _aligned_free(ptr);  #else     void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));     void *realAddr = *cubbyHole; @@ -194,6 +207,10 @@ void *  _mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,                      unsigned long alignment)  { +#if defined(_WIN32) && defined(_MSC_VER) +   (void) oldSize; +   return _aligned_realloc(oldBuffer, newSize, alignment); +#else     const size_t copySize = (oldSize < newSize) ? oldSize : newSize;     void *newBuf = _mesa_align_malloc(newSize, alignment);     if (newBuf && oldBuffer && copySize > 0) { @@ -202,6 +219,7 @@ _mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,     if (oldBuffer)        _mesa_align_free(oldBuffer);     return newBuf; +#endif  } @@ -560,6 +578,7 @@ _mesa_ffs(int i)           bit++;           i >>= 1;        } +      bit++;     }     return bit;  #else diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h index ebdfc452a7..b0234a2b85 100644 --- a/src/mesa/main/imports.h +++ b/src/mesa/main/imports.h @@ -1,8 +1,8 @@  /*   * Mesa 3-D graphics library - * Version:  6.5.2 + * Version:  7.1   * - * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved. + * Copyright (C) 1999-2008  Brian Paul   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"), @@ -159,7 +159,7 @@ typedef union { GLfloat f; GLint i; } fi_type;   ***/  #if defined(__i386__) || defined(__386__) || defined(__sparc__) || \      defined(__s390x__) || defined(__powerpc__) || \ -    defined(__amd64__) || \ +    defined(__amd64__) || defined(__x86_64__) || \      defined(ia64) || defined(__ia64__) || \      defined(__hppa__) || defined(hpux) || \      defined(__mips) || defined(_MIPS_ARCH) || \ diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index b1c00a36ac..fb68bf0720 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -1272,7 +1272,7 @@ _mesa_UpdateTexEnvProgram( GLcontext *ctx )     }      else {        /* _Current pointer has been updated in update_program */ -      // ctx->FragmentProgram._Current = ctx->FragmentProgram.Current; +      /* ctx->FragmentProgram._Current = ctx->FragmentProgram.Current; */     }     /* Tell the driver about the change.  Could define a new target for diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 7241cf61be..adf3d37597 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -2306,9 +2306,6 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,        return;     } -   if (!pixels) -      return; -     _mesa_lock_texture(ctx, texObj);     {        texImage = _mesa_select_tex_image(ctx, texObj, target, level); diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 11720e4073..f41ee73c88 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -443,7 +443,7 @@ void GLAPIENTRY  _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,                              GLsizei stride, const GLvoid *ptr)  { -   const GLboolean normalized = GL_FALSE; +   GLboolean normalized = GL_FALSE;     GLsizei elementSize;     GET_CURRENT_CONTEXT(ctx);     ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -471,6 +471,7 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,     /* check for valid 'type' and compute StrideB right away */     switch (type) {        case GL_UNSIGNED_BYTE: +         normalized = GL_TRUE;           elementSize = size * sizeof(GLubyte);           break;        case GL_SHORT: diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index 10fa196586..74004e9b13 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -2,7 +2,7 @@   * Mesa 3-D graphics library   * Version:  7.1   * - * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved. + * Copyright (C) 1999-2008  Brian Paul   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"), @@ -1616,8 +1616,6 @@ parse_attrib_binding(GLcontext * ctx, const GLubyte ** inst,     if (err) {        program_error(ctx, Program->Position, "Bad attribute binding"); -   } else { -       Program->Base.InputsRead |= (1 << *inputReg);     }     return err; @@ -1862,12 +1860,14 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst,           break;        case PARAM_CONSTANT: +         /* parsing something like {1.0, 2.0, 3.0, 4.0} */           parse_constant (inst, const_values, Program, use);           idx = _mesa_add_named_constant(Program->Base.Parameters,                                          (char *) param_var->name,                                          const_values, 4);           if (param_var->param_binding_begin == ~0U)              param_var->param_binding_begin = idx; +         param_var->param_binding_type = PROGRAM_CONSTANT;           param_var->param_binding_length++;           Program->Base.NumParameters++;           break; @@ -2574,26 +2574,32 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst,           return 1;     } +   /* Add attributes to InputsRead only if they are used the program. +    * This avoids the handling of unused ATTRIB declarations in the drivers. */ +   if (*File == PROGRAM_INPUT) +      Program->Base.InputsRead |= (1 << *Index); +     return 0;  } +  /** - * Parse fragment program vector source register. + * Parse vertex/fragment program vector source register.   */  static GLuint -parse_fp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst, -                        struct var_cache **vc_head, -                        struct arb_program *program, -                        struct prog_src_register *reg) +parse_vector_src_reg(GLcontext *ctx, const GLubyte **inst, +                     struct var_cache **vc_head, +                     struct arb_program *program, +                     struct prog_src_register *reg)  {     enum register_file file;     GLint index; -   GLboolean negate; +   GLubyte negateMask;     GLubyte swizzle[4];     GLboolean isRelOffset;     /* Grab the sign */ -   negate = (parse_sign (inst) == -1) ? 0xf : 0x0; +   negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE;     /* And the src reg */     if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset)) @@ -2604,66 +2610,66 @@ parse_fp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst,     reg->File = file;     reg->Index = index; -   reg->NegateBase = negate;     reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); +   reg->NegateBase = negateMask; +   reg->RelAddr = isRelOffset;     return 0;  }  /** - * Parse fragment program destination register. - * \return 1 if error, 0 if no error. + * Parse vertex/fragment program scalar source register.   */ -static GLuint  -parse_fp_dst_reg(GLcontext * ctx, const GLubyte ** inst, -		 struct var_cache **vc_head, struct arb_program *Program, -		 struct prog_dst_register *reg ) +static GLuint +parse_scalar_src_reg(GLcontext *ctx, const GLubyte **inst, +                     struct var_cache **vc_head, +                     struct arb_program *program, +                     struct prog_src_register *reg)  { -   GLint mask; -   GLuint idx;     enum register_file file; +   GLint index; +   GLubyte negateMask; +   GLubyte swizzle[4]; +   GLboolean isRelOffset; + +   /* Grab the sign */ +   negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE; -   if (parse_masked_dst_reg (ctx, inst, vc_head, Program, &file, &idx, &mask)) +   /* And the src reg */ +   if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset))        return 1; +   /* finally, the swizzle */ +   parse_swizzle_mask(inst, swizzle, 1); +     reg->File = file; -   reg->Index = idx; -   reg->WriteMask = mask; +   reg->Index = index; +   reg->Swizzle = (swizzle[0] << 0); +   reg->NegateBase = negateMask; +   reg->RelAddr = isRelOffset;     return 0;  }  /** - * Parse fragment program scalar src register. + * Parse vertex/fragment program destination register.   * \return 1 if error, 0 if no error.   */ -static GLuint -parse_fp_scalar_src_reg (GLcontext * ctx, const GLubyte ** inst, -			 struct var_cache **vc_head, -                         struct arb_program *Program, -			 struct prog_src_register *reg ) +static GLuint  +parse_dst_reg(GLcontext * ctx, const GLubyte ** inst, +              struct var_cache **vc_head, struct arb_program *program, +              struct prog_dst_register *reg )  { -   enum register_file File; -   GLint Index; -   GLubyte Negate; -   GLubyte Swizzle[4]; -   GLboolean IsRelOffset; - -   /* Grab the sign */ -   Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0; +   GLint mask; +   GLuint idx; +   enum register_file file; -   /* And the src reg */ -   if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset)) +   if (parse_masked_dst_reg (ctx, inst, vc_head, program, &file, &idx, &mask))        return 1; -   /* finally, the swizzle */ -   parse_swizzle_mask(inst, Swizzle, 1); - -   reg->File = File; -   reg->Index = Index; -   reg->NegateBase = Negate; -   reg->Swizzle = (Swizzle[0] << 0); - +   reg->File = file; +   reg->Index = idx; +   reg->WriteMask = mask;     return 0;  } @@ -2744,10 +2750,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,                 break;           } -         if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) +         if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))              return 1; -         if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) +         if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))              return 1;           break; @@ -2797,10 +2803,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,                 break;           } -         if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) +         if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))              return 1; -         if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) +         if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))              return 1;           break; @@ -2813,11 +2819,11 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,                 break;           } -         if (parse_fp_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg)) +         if (parse_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg))              return 1;           for (a = 0; a < 2; a++) { -	    if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) +	    if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))                 return 1;           }           break; @@ -2898,10 +2904,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,                 break;           } -         if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) +         if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))              return 1;           for (a = 0; a < 2; a++) { -	    if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) +	    if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))  	       return 1;           }           break; @@ -2927,11 +2933,11 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,                 break;           } -         if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) +         if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))              return 1;           for (a = 0; a < 3; a++) { -	    if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) +	    if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))  	       return 1;           }           break; @@ -2944,7 +2950,7 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,                 fp->Opcode = OPCODE_SWZ;                 break;           } -         if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) +         if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))              return 1;  	 { @@ -2987,10 +2993,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,                 break;           } -         if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) +         if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))              return 1; -	 if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) +	 if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))              return 1;           /* texImageUnit */ @@ -3062,7 +3068,7 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,        case OP_TEX_KIL:           Program->UsesKill = 1; -	 if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) +	 if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))              return 1;           fp->Opcode = OPCODE_KIL;           break; @@ -3074,23 +3080,6 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,     return 0;  } -static GLuint  -parse_vp_dst_reg(GLcontext * ctx, const GLubyte ** inst, -		 struct var_cache **vc_head, struct arb_program *Program, -		 struct prog_dst_register *reg ) -{ -   GLint mask; -   GLuint idx; -   enum register_file file; - -   if (parse_masked_dst_reg(ctx, inst, vc_head, Program, &file, &idx, &mask)) -      return 1; - -   reg->File = file; -   reg->Index = idx; -   reg->WriteMask = mask; -   return 0; -}  /**   * Handle the parsing out of a masked address register @@ -3122,71 +3111,6 @@ parse_vp_address_reg (GLcontext * ctx, const GLubyte ** inst,     return 0;  } -/** - * Parse vertex program vector source register. - */ -static GLuint -parse_vp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst, -                        struct var_cache **vc_head, -                        struct arb_program *program, -                        struct prog_src_register *reg ) -{ -   enum register_file file; -   GLint index; -   GLubyte negateMask; -   GLubyte swizzle[4]; -   GLboolean isRelOffset; - -   /* Grab the sign */ -   negateMask = (parse_sign (inst) == -1) ? 0xf : 0x0; - -   /* And the src reg */ -   if (parse_src_reg (ctx, inst, vc_head, program, &file, &index, &isRelOffset)) -      return 1; - -   /* finally, the swizzle */ -   parse_swizzle_mask(inst, swizzle, 4); - -   reg->File = file; -   reg->Index = index; -   reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], -                                swizzle[2], swizzle[3]); -   reg->NegateBase = negateMask; -   reg->RelAddr = isRelOffset; -   return 0; -} - - -static GLuint -parse_vp_scalar_src_reg (GLcontext * ctx, const GLubyte ** inst, -			 struct var_cache **vc_head, -                         struct arb_program *Program, -			 struct prog_src_register *reg ) -{ -   enum register_file File; -   GLint Index; -   GLubyte Negate; -   GLubyte Swizzle[4]; -   GLboolean IsRelOffset; - -   /* Grab the sign */ -   Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0; - -   /* And the src reg */ -   if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset)) -      return 1; - -   /* finally, the swizzle */ -   parse_swizzle_mask(inst, Swizzle, 1); - -   reg->File = File; -   reg->Index = Index; -   reg->Swizzle = (Swizzle[0] << 0); -   reg->NegateBase = Negate; -   reg->RelAddr = IsRelOffset; -   return 0; -} -  /**   * This is a big mother that handles getting opcodes into the instruction @@ -3224,7 +3148,7 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,           vp->DstReg.File = PROGRAM_ADDRESS;           /* Get a scalar src register */ -	 if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) +	 if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))              return 1;           break; @@ -3248,10 +3172,10 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,                 break;           } -         if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) +         if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))              return 1; -         if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) +         if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))              return 1;           break; @@ -3276,10 +3200,10 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,                 vp->Opcode = OPCODE_RSQ;                 break;           } -         if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) +         if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))              return 1; -	 if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) +	 if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))              return 1;           break; @@ -3289,11 +3213,11 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,                 vp->Opcode = OPCODE_POW;                 break;           } -         if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) +         if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))              return 1;           for (a = 0; a < 2; a++) { -	    if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) +	    if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))                 return 1;           }           break; @@ -3337,11 +3261,11 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,                 vp->Opcode = OPCODE_XPD;                 break;           } -         if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) +         if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))              return 1;           for (a = 0; a < 2; a++) { -	    if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) +	    if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))                 return 1;           }           break; @@ -3353,11 +3277,11 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,                 break;           } -         if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) +         if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))              return 1;           for (a = 0; a < 3; a++) { -	    if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) +	    if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))                 return 1;           }           break; @@ -3375,7 +3299,7 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,              enum register_file file;  	    GLint index; -	    if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) +	    if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))  	       return 1;  	    if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &relAddr)) diff --git a/src/mesa/shader/arbprogram.syn b/src/mesa/shader/arbprogram.syn index 1746a876c3..f3aa1ad724 100644 --- a/src/mesa/shader/arbprogram.syn +++ b/src/mesa/shader/arbprogram.syn @@ -1942,10 +1942,10 @@ stateTexEnvProperty  fragment program      <optLegacyTexUnitNum>  ::= ""                               | "[" <legacyTexUnitNum> "]" - -NOTE: <optLegaceTexUnitNum> is not optional.  */  optLegacyTexUnitNum +    optLegacyTexUnitNum_1 .or .true .emit 0x00; +optLegacyTexUnitNum_1      lbracket_ne .and legacyTexUnitNum .and rbracket;  /* diff --git a/src/mesa/shader/arbprogram_syn.h b/src/mesa/shader/arbprogram_syn.h index 5f3f7d6cf4..3f3ab073cf 100644 --- a/src/mesa/shader/arbprogram_syn.h +++ b/src/mesa/shader/arbprogram_syn.h @@ -926,6 +926,8 @@  "stateTexEnvProperty\n"  " \"color\" .emit TEX_ENV_COLOR;\n"  "optLegacyTexUnitNum\n" +" optLegacyTexUnitNum_1 .or .true .emit 0x00;\n" +"optLegacyTexUnitNum_1\n"  " lbracket_ne .and legacyTexUnitNum .and rbracket;\n"  "legacyTexUnitNum\n"  " integer;\n" diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index e92837f739..308cce2206 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -99,7 +99,23 @@ arb_input_attrib_string(GLint index, GLenum progType)        "vertex.texcoord[4]",        "vertex.texcoord[5]",        "vertex.texcoord[6]", -      "vertex.texcoord[7]" +      "vertex.texcoord[7]", +      "vertex.attrib[0]", +      "vertex.attrib[1]", +      "vertex.attrib[2]", +      "vertex.attrib[3]", +      "vertex.attrib[4]", +      "vertex.attrib[5]", +      "vertex.attrib[6]", +      "vertex.attrib[7]", +      "vertex.attrib[8]", +      "vertex.attrib[9]", +      "vertex.attrib[10]", +      "vertex.attrib[11]", +      "vertex.attrib[12]", +      "vertex.attrib[13]", +      "vertex.attrib[14]", +      "vertex.attrib[15]"     };     const char *fragAttribs[] = {        "fragment.position", diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index da0bb85f16..4ae74c1d42 100644 --- a/src/mesa/shader/prog_statevars.c +++ b/src/mesa/shader/prog_statevars.c @@ -181,7 +181,7 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],                       ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i];                 }                 /* [3] = material alpha */ -               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; +               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][3];                 return;              case STATE_DIFFUSE:                 for (i = 0; i < 3; i++) { @@ -197,7 +197,7 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],                       ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i];                 }                 /* [3] = material alpha */ -               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; +               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][3];                 return;              default:                 _mesa_problem(ctx, "Invalid lightprod state in fetch_state"); diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 2097c39591..d2c9183558 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -386,7 +386,7 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)     clone->Format = prog->Format;     clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);     if (!clone->Instructions) { -      _mesa_delete_program(ctx, clone); +      ctx->Driver.DeleteProgram(ctx, clone);        return NULL;     }     _mesa_copy_instructions(clone->Instructions, prog->Instructions, diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index e9c35fce71..76da855a07 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -79,7 +79,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx,           /* to prevent a double-free in the next call */           shProg->VertexProgram->Base.Parameters = NULL;        } -      _mesa_delete_program(ctx, &shProg->VertexProgram->Base); +      ctx->Driver.DeleteProgram(ctx, &shProg->VertexProgram->Base);        shProg->VertexProgram = NULL;     } @@ -88,7 +88,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx,           /* to prevent a double-free in the next call */           shProg->FragmentProgram->Base.Parameters = NULL;        } -      _mesa_delete_program(ctx, &shProg->FragmentProgram->Base); +      ctx->Driver.DeleteProgram(ctx, &shProg->FragmentProgram->Base);        shProg->FragmentProgram = NULL;     } @@ -246,7 +246,7 @@ _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)        _mesa_free(sh->InfoLog);     for (i = 0; i < sh->NumPrograms; i++) {        assert(sh->Programs[i]); -      _mesa_delete_program(ctx, sh->Programs[i]); +      ctx->Driver.DeleteProgram(ctx, sh->Programs[i]);     }     if (sh->Programs)        _mesa_free(sh->Programs); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 9947544a08..9c307c6275 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -677,6 +677,7 @@ static struct prog_instruction *  emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n)  {     struct prog_instruction *inst; +   slang_ir_node tmpNode;     assert(n->Opcode == IR_CLAMP);     /* ch[0] = value @@ -722,18 +723,27 @@ emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n)     emit(emitInfo, n->Children[1]);     emit(emitInfo, n->Children[2]); +   /* Some GPUs don't allow reading from output registers.  So if the +    * dest for this clamp() is an output reg, we can't use that reg for +    * the intermediate result.  Use a temp register instead. +    */ +   _mesa_bzero(&tmpNode, sizeof(tmpNode)); +   alloc_temp_storage(emitInfo, &tmpNode, n->Store->Size); +     /* tmp = max(ch[0], ch[1]) */     inst = new_instruction(emitInfo, OPCODE_MAX); -   storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); +   storage_to_dst_reg(&inst->DstReg, tmpNode.Store, n->Writemask);     storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store);     storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store); -   /* tmp = min(tmp, ch[2]) */ +   /* n->dest = min(tmp, ch[2]) */     inst = new_instruction(emitInfo, OPCODE_MIN);     storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); -   storage_to_src_reg(&inst->SrcReg[0], n->Store); +   storage_to_src_reg(&inst->SrcReg[0], tmpNode.Store);     storage_to_src_reg(&inst->SrcReg[1], n->Children[2]->Store); +   free_temp_storage(emitInfo->vt, &tmpNode); +     return inst;  } diff --git a/src/mesa/swrast/s_bitmap.c b/src/mesa/swrast/s_bitmap.c index 1e7f6c18e6..f3dda12e25 100644 --- a/src/mesa/swrast/s_bitmap.c +++ b/src/mesa/swrast/s_bitmap.c @@ -1,8 +1,8 @@  /*   * Mesa 3-D graphics library - * Version:  6.5.2 + * Version:  7.1   * - * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved. + * Copyright (C) 1999-2008  Brian Paul   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"), @@ -57,25 +57,9 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,     ASSERT(ctx->RenderMode == GL_RENDER); -   if (unpack->BufferObj->Name) { -      /* unpack from PBO */ -      GLubyte *buf; -      if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, -                                     GL_COLOR_INDEX, GL_BITMAP, -                                     (GLvoid *) bitmap)) { -         _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)"); -         return; -      } -      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, -                                              GL_READ_ONLY_ARB, -                                              unpack->BufferObj); -      if (!buf) { -         /* buffer is already mapped - that's an error */ -         _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)"); -         return; -      } -      bitmap = ADD_POINTERS(buf, bitmap); -   } +   bitmap = _mesa_map_bitmap_pbo(ctx, unpack, bitmap); +   if (!bitmap) +      return;     RENDER_START(swrast,ctx); @@ -150,11 +134,7 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,     RENDER_FINISH(swrast,ctx); -   if (unpack->BufferObj->Name) { -      /* done with PBO so unmap it now */ -      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, -                              unpack->BufferObj); -   } +   _mesa_unmap_bitmap_pbo(ctx, unpack);  } diff --git a/src/mesa/swrast/s_buffers.c b/src/mesa/swrast/s_buffers.c index b74c4ab1c8..0d1e9bac1c 100644 --- a/src/mesa/swrast/s_buffers.c +++ b/src/mesa/swrast/s_buffers.c @@ -1,8 +1,8 @@  /*   * Mesa 3-D graphics library - * Version:  6.5.2 + * Version:  7.1   * - * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved. + * Copyright (C) 1999-2008  Brian Paul   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"), @@ -331,7 +331,8 @@ _swrast_Clear(GLcontext *ctx, GLbitfield buffers)     /* do software clearing here */     if (buffers) { -      if (buffers & ctx->DrawBuffer->_NumColorDrawBuffers > 0) { +      if ((buffers & BUFFER_BITS_COLOR) +          && (ctx->DrawBuffer->_NumColorDrawBuffers > 0)) {           clear_color_buffers(ctx);        }        if (buffers & BUFFER_BIT_DEPTH) { diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c index 4733d10bb5..81f5caa270 100644 --- a/src/mesa/swrast/s_drawpix.c +++ b/src/mesa/swrast/s_drawpix.c @@ -817,7 +817,6 @@ draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,  } -  /**   * Execute software-based glDrawPixels.   * By time we get here, all error checking will have been done. @@ -840,27 +839,9 @@ _swrast_DrawPixels( GLcontext *ctx,     if (swrast->NewState)        _swrast_validate_derived( ctx ); -   if (unpack->BufferObj->Name) { -      /* unpack from PBO */ -      GLubyte *buf; -      if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, -                                     format, type, pixels)) { -         _mesa_error(ctx, GL_INVALID_OPERATION, -                     "glDrawPixels(invalid PBO access)"); -         RENDER_FINISH(swrast, ctx); -	 return; -      } -      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, -                                              GL_READ_ONLY_ARB, -                                              unpack->BufferObj); -      if (!buf) { -         /* buffer is already mapped - that's an error */ -         _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(PBO is mapped)"); -         RENDER_FINISH(swrast, ctx); -	 return; -      } -      pixels = ADD_POINTERS(buf, pixels); -   } +    pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels); +    if (!pixels) +       return;     switch (format) {     case GL_STENCIL_INDEX: @@ -899,11 +880,7 @@ _swrast_DrawPixels( GLcontext *ctx,     RENDER_FINISH(swrast,ctx); -   if (unpack->BufferObj->Name) { -      /* done with PBO so unmap it now */ -      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, -                              unpack->BufferObj); -   } +   _mesa_unmap_drapix_pbo(ctx, unpack);  } diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c index 8df15c8704..9140d12ea0 100644 --- a/src/mesa/swrast/s_readpix.c +++ b/src/mesa/swrast/s_readpix.c @@ -574,28 +574,10 @@ _swrast_ReadPixels( GLcontext *ctx,        return;     } -   if (clippedPacking.BufferObj->Name) { -      /* pack into PBO */ -      GLubyte *buf; -      if (!_mesa_validate_pbo_access(2, &clippedPacking, width, height, 1, -                                     format, type, pixels)) { -         _mesa_error(ctx, GL_INVALID_OPERATION, -                     "glReadPixels(invalid PBO access)"); -	 RENDER_FINISH(swrast, ctx); -	 return; -      } -      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, -                                              GL_WRITE_ONLY_ARB, -                                              clippedPacking.BufferObj); -      if (!buf) { -         /* buffer is already mapped - that's an error */ -         _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)"); -	 RENDER_FINISH(swrast, ctx); -	 return; -      } -      pixels = ADD_POINTERS(buf, pixels); -   } - +   pixels = _mesa_map_readpix_pbo(ctx, &clippedPacking, pixels); +   if (!pixels) +      return; +       switch (format) {        case GL_COLOR_INDEX:           read_index_pixels(ctx, x, y, width, height, type, pixels, @@ -634,9 +616,5 @@ _swrast_ReadPixels( GLcontext *ctx,     RENDER_FINISH(swrast, ctx); -   if (clippedPacking.BufferObj->Name) { -      /* done with PBO so unmap it now */ -      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, -                              clippedPacking.BufferObj); -   } +   _mesa_unmap_readpix_pbo(ctx, &clippedPacking);  } diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index d404579279..864f77a417 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1183,8 +1183,10 @@ shade_texture_span(GLcontext *ctx, SWspan *span)        if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) {           convert_color_type(span, GL_FLOAT, 0);        } -      if (span->primitive != GL_POINT || ctx->Point.PointSprite) { -         /* for points, we populated the arrays already */ +      if (span->primitive != GL_POINT || +	  (span->interpMask & SPAN_RGBA) || +	  ctx->Point.PointSprite) { +         /* for single-pixel points, we populated the arrays already */           interpolate_active_attribs(ctx, span, ~0);        }        span->array->ChanType = GL_FLOAT; diff --git a/src/mesa/tnl/t_vertex_sse.c b/src/mesa/tnl/t_vertex_sse.c index 9515d9f81f..f1c98fe2d1 100644 --- a/src/mesa/tnl/t_vertex_sse.c +++ b/src/mesa/tnl/t_vertex_sse.c @@ -648,12 +648,12 @@ void _tnl_generate_sse_emit( GLcontext *ctx )     p.ctx = ctx;     p.inputs_safe = 0;		/* for now */ -   p.outputs_safe = 1;		/* for now */ +   p.outputs_safe = 0;		/* for now */     p.have_sse2 = cpu_has_xmm2;     p.identity = x86_make_reg(file_XMM, 6);     p.chan0 = x86_make_reg(file_XMM, 7); -   if (!x86_init_func(&p.func, MAX_SSE_CODE_SIZE)) { +   if (!x86_init_func_size(&p.func, MAX_SSE_CODE_SIZE)) {        vtx->emit = NULL;        return;     } diff --git a/src/mesa/x86/rtasm/x86sse.c b/src/mesa/x86/rtasm/x86sse.c index 612cd51a6e..772471c723 100644 --- a/src/mesa/x86/rtasm/x86sse.c +++ b/src/mesa/x86/rtasm/x86sse.c @@ -1,4 +1,4 @@ -#if defined(USE_X86_ASM) || defined(SLANG_X86) +#if defined(__i386__) || defined(__386__)  #include "imports.h"  #include "x86sse.h" @@ -6,54 +6,78 @@  #define DISASSEM 0  #define X86_TWOB 0x0f -/* Emit bytes to the instruction stream: - */ -static void emit_1b( struct x86_function *p, GLbyte b0 ) +static unsigned char *cptr( void (*label)() )  { -   *(GLbyte *)(p->csr++) = b0; +   return (unsigned char *)(unsigned long)label;  } -static void emit_1i( struct x86_function *p, GLint i0 ) + +static void do_realloc( struct x86_function *p )  { -   *(GLint *)(p->csr) = i0; -   p->csr += 4; +   if (p->size == 0) { +      p->size = 1024; +      p->store = _mesa_exec_malloc(p->size); +      p->csr = p->store; +   } +   else { +      unsigned used = p->csr - p->store; +      unsigned char *tmp = p->store; +      p->size *= 2; +      p->store = _mesa_exec_malloc(p->size); +      memcpy(p->store, tmp, used); +      p->csr = p->store + used; +      _mesa_exec_free(tmp); +   }  } -static void disassem( struct x86_function *p, const char *fn ) +/* Emit bytes to the instruction stream: + */ +static unsigned char *reserve( struct x86_function *p, int bytes )  { -#if DISASSEM && 0 -   if (fn && fn != p->fn) { -      _mesa_printf("0x%x: %s\n", p->csr, fn); -      p->fn = fn; +   if (p->csr + bytes - p->store > p->size) +      do_realloc(p); + +   { +      unsigned char *csr = p->csr; +      p->csr += bytes; +      return csr;     } -#endif  } -static void emit_1ub_fn( struct x86_function *p, GLubyte b0, const char *fn ) + + +static void emit_1b( struct x86_function *p, char b0 )  { -   disassem(p, fn); -   *(p->csr++) = b0; +   char *csr = (char *)reserve(p, 1); +   *csr = b0;  } -static void emit_2ub_fn( struct x86_function *p, GLubyte b0, GLubyte b1, const char *fn ) +static void emit_1i( struct x86_function *p, int i0 )  { -   disassem(p, fn); -   *(p->csr++) = b0; -   *(p->csr++) = b1; +   int *icsr = (int *)reserve(p, sizeof(i0)); +   *icsr = i0;  } -static void emit_3ub_fn( struct x86_function *p, GLubyte b0, GLubyte b1, GLubyte b2, const char *fn ) +static void emit_1ub( struct x86_function *p, unsigned char b0 )  { -   disassem(p, fn); -   *(p->csr++) = b0; -   *(p->csr++) = b1; -   *(p->csr++) = b2; +   unsigned char *csr = reserve(p, 1); +   *csr++ = b0;  } -#define emit_1ub(p, b0)         emit_1ub_fn(p, b0, __FUNCTION__) -#define emit_2ub(p, b0, b1)     emit_2ub_fn(p, b0, b1, __FUNCTION__) -#define emit_3ub(p, b0, b1, b2) emit_3ub_fn(p, b0, b1, b2, __FUNCTION__) +static void emit_2ub( struct x86_function *p, unsigned char b0, unsigned char b1 ) +{ +   unsigned char *csr = reserve(p, 2); +   *csr++ = b0; +   *csr++ = b1; +} +static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2 ) +{ +   unsigned char *csr = reserve(p, 3); +   *csr++ = b0; +   *csr++ = b1; +   *csr++ = b2; +}  /* Build a modRM byte + possible displacement.  No treatment of SIB @@ -63,7 +87,7 @@ static void emit_modrm( struct x86_function *p,  			struct x86_reg reg,   			struct x86_reg regmem )  { -   GLubyte val = 0; +   unsigned char val = 0;     assert(reg.mod == mod_REG); @@ -71,13 +95,13 @@ static void emit_modrm( struct x86_function *p,     val |= reg.idx << 3;		/* reg field */     val |= regmem.idx;		/* r/m field */ -   emit_1ub_fn(p, val, 0); +   emit_1ub(p, val);     /* Oh-oh we've stumbled into the SIB thing.      */     if (regmem.file == file_REG32 &&         regmem.idx == reg_SP) { -      emit_1ub_fn(p, 0x24, 0);		/* simplistic! */ +      emit_1ub(p, 0x24);		/* simplistic! */     }     switch (regmem.mod) { @@ -98,7 +122,7 @@ static void emit_modrm( struct x86_function *p,  static void emit_modrm_noreg( struct x86_function *p, -			      GLuint op, +			      unsigned op,  			      struct x86_reg regmem )  {     struct x86_reg dummy = x86_make_reg(file_REG32, op); @@ -111,21 +135,21 @@ static void emit_modrm_noreg( struct x86_function *p,   * the arguments presented.   */  static void emit_op_modrm( struct x86_function *p, -			   GLubyte op_dst_is_reg,  -			   GLubyte op_dst_is_mem, +			   unsigned char op_dst_is_reg,  +			   unsigned char op_dst_is_mem,  			   struct x86_reg dst,  			   struct x86_reg src )  {       switch (dst.mod) {     case mod_REG: -      emit_1ub_fn(p, op_dst_is_reg, 0); +      emit_1ub(p, op_dst_is_reg);        emit_modrm(p, dst, src);        break;     case mod_INDIRECT:     case mod_DISP32:     case mod_DISP8:        assert(src.mod == mod_REG); -      emit_1ub_fn(p, op_dst_is_mem, 0); +      emit_1ub(p, op_dst_is_mem);        emit_modrm(p, src, dst);        break;     default: @@ -156,7 +180,7 @@ struct x86_reg x86_make_reg( enum x86_reg_file file,  }  struct x86_reg x86_make_disp( struct x86_reg reg, -			      GLint disp ) +			      int disp )  {     assert(reg.file == file_REG32); @@ -185,7 +209,7 @@ struct x86_reg x86_get_base_reg( struct x86_reg reg )     return x86_make_reg( reg.file, reg.idx );  } -GLubyte *x86_get_label( struct x86_function *p ) +unsigned char *x86_get_label( struct x86_function *p )  {     return p->csr;  } @@ -199,13 +223,13 @@ GLubyte *x86_get_label( struct x86_function *p )  void x86_jcc( struct x86_function *p,  	      enum x86_cc cc, -	      GLubyte *label ) +	      unsigned char *label )  { -   GLint offset = label - (x86_get_label(p) + 2); +   int offset = label - (x86_get_label(p) + 2);     if (offset <= 127 && offset >= -128) {        emit_1ub(p, 0x70 + cc); -      emit_1b(p, (GLbyte) offset); +      emit_1b(p, (char) offset);     }     else {        offset = label - (x86_get_label(p) + 6); @@ -216,7 +240,7 @@ void x86_jcc( struct x86_function *p,  /* Always use a 32bit offset for forward jumps:   */ -GLubyte *x86_jcc_forward( struct x86_function *p, +unsigned char *x86_jcc_forward( struct x86_function *p,  			  enum x86_cc cc )  {     emit_2ub(p, 0x0f, 0x80 + cc); @@ -224,14 +248,14 @@ GLubyte *x86_jcc_forward( struct x86_function *p,     return x86_get_label(p);  } -GLubyte *x86_jmp_forward( struct x86_function *p) +unsigned char *x86_jmp_forward( struct x86_function *p)  {     emit_1ub(p, 0xe9);     emit_1i(p, 0);     return x86_get_label(p);  } -GLubyte *x86_call_forward( struct x86_function *p) +unsigned char *x86_call_forward( struct x86_function *p)  {     emit_1ub(p, 0xe8);     emit_1i(p, 0); @@ -241,28 +265,41 @@ GLubyte *x86_call_forward( struct x86_function *p)  /* Fixup offset from forward jump:   */  void x86_fixup_fwd_jump( struct x86_function *p, -			 GLubyte *fixup ) +			 unsigned char *fixup )  {     *(int *)(fixup - 4) = x86_get_label(p) - fixup;  } -void x86_jmp( struct x86_function *p, GLubyte *label) +void x86_jmp( struct x86_function *p, unsigned char *label)  {     emit_1ub(p, 0xe9);     emit_1i(p, label - x86_get_label(p) - 4);  } -void x86_call( struct x86_function *p, GLubyte *label) +#if 0 +/* This doesn't work once we start reallocating & copying the + * generated code on buffer fills, because the call is relative to the + * current pc. + */ +void x86_call( struct x86_function *p, void (*label)())  {     emit_1ub(p, 0xe8); -   emit_1i(p, label - x86_get_label(p) - 4); +   emit_1i(p, cptr(label) - x86_get_label(p) - 4); +} +#else +void x86_call( struct x86_function *p, struct x86_reg reg) +{ +   emit_1ub(p, 0xff); +   emit_modrm(p, reg, reg);  } +#endif +  /* michal:   * Temporary. As I need immediate operands, and dont want to mess with the codegen,   * I load the immediate into general purpose register and use it.   */ -void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, GLint imm ) +void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm )  {     assert(dst.mod == mod_REG);     emit_1ub(p, 0xb8 + dst.idx); @@ -502,6 +539,14 @@ void sse_addss( struct x86_function *p,     emit_modrm( p, dst, src );  } +void sse_andnps( struct x86_function *p, +                 struct x86_reg dst, +                 struct x86_reg src ) +{ +   emit_2ub(p, X86_TWOB, 0x55); +   emit_modrm( p, dst, src ); +} +  void sse_andps( struct x86_function *p,  		struct x86_reg dst,  		struct x86_reg src ) @@ -510,6 +555,13 @@ void sse_andps( struct x86_function *p,     emit_modrm( p, dst, src );  } +void sse_rsqrtps( struct x86_function *p, +                  struct x86_reg dst, +                  struct x86_reg src ) +{ +   emit_2ub(p, X86_TWOB, 0x52); +   emit_modrm( p, dst, src ); +}  void sse_rsqrtss( struct x86_function *p,  		  struct x86_reg dst, @@ -538,6 +590,21 @@ void sse_movlhps( struct x86_function *p,     emit_modrm( p, dst, src );  } +void sse_orps( struct x86_function *p, +               struct x86_reg dst, +               struct x86_reg src ) +{ +   emit_2ub(p, X86_TWOB, 0x56); +   emit_modrm( p, dst, src ); +} + +void sse_xorps( struct x86_function *p, +                struct x86_reg dst, +                struct x86_reg src ) +{ +   emit_2ub(p, X86_TWOB, 0x57); +   emit_modrm( p, dst, src ); +}  void sse_cvtps2pi( struct x86_function *p,  		   struct x86_reg dst, @@ -559,7 +626,7 @@ void sse_cvtps2pi( struct x86_function *p,  void sse_shufps( struct x86_function *p,  		 struct x86_reg dest,  		 struct x86_reg arg0, -		 GLubyte shuf)  +		 unsigned char shuf)   {     emit_2ub(p, X86_TWOB, 0xC6);     emit_modrm(p, dest, arg0); @@ -569,13 +636,21 @@ void sse_shufps( struct x86_function *p,  void sse_cmpps( struct x86_function *p,  		struct x86_reg dest,  		struct x86_reg arg0, -		GLubyte cc)  +		unsigned char cc)   {     emit_2ub(p, X86_TWOB, 0xC2);     emit_modrm(p, dest, arg0);     emit_1ub(p, cc);   } +void sse_pmovmskb( struct x86_function *p, +                   struct x86_reg dest, +                   struct x86_reg src) +{ +    emit_3ub(p, 0x66, X86_TWOB, 0xD7); +    emit_modrm(p, dest, src); +} +  /***********************************************************************   * SSE2 instructions   */ @@ -586,13 +661,21 @@ void sse_cmpps( struct x86_function *p,  void sse2_pshufd( struct x86_function *p,  		  struct x86_reg dest,  		  struct x86_reg arg0, -		  GLubyte shuf)  +		  unsigned char shuf)   {     emit_3ub(p, 0x66, X86_TWOB, 0x70);     emit_modrm(p, dest, arg0);     emit_1ub(p, shuf);   } +void sse2_cvttps2dq( struct x86_function *p, +                     struct x86_reg dst, +                     struct x86_reg src ) +{ +   emit_3ub( p, 0xF3, X86_TWOB, 0x5B ); +   emit_modrm( p, dst, src ); +} +  void sse2_cvtps2dq( struct x86_function *p,  		    struct x86_reg dst,  		    struct x86_reg src ) @@ -625,6 +708,14 @@ void sse2_packuswb( struct x86_function *p,     emit_modrm( p, dst, src );  } +void sse2_rcpps( struct x86_function *p, +                 struct x86_reg dst, +                 struct x86_reg src ) +{ +   emit_2ub(p, X86_TWOB, 0x53); +   emit_modrm( p, dst, src ); +} +  void sse2_rcpss( struct x86_function *p,  		struct x86_reg dst,  		struct x86_reg src ) @@ -712,11 +803,11 @@ void x87_fclex( struct x86_function *p )  static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg, -			  GLubyte dst0ub0, -			  GLubyte dst0ub1, -			  GLubyte arg0ub0, -			  GLubyte arg0ub1, -			  GLubyte argmem_noreg) +			  unsigned char dst0ub0, +			  unsigned char dst0ub1, +			  unsigned char arg0ub0, +			  unsigned char arg0ub1, +			  unsigned char argmem_noreg)  {     assert(dst.file == file_x87); @@ -729,7 +820,7 @@ static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86  	 assert(0);     }     else if (dst.idx == 0) { -      assert(arg.file = file_REG32); +      assert(arg.file == file_REG32);        emit_1ub(p, 0xd8);        emit_modrm_noreg(p, argmem_noreg, arg);     } @@ -1056,44 +1147,42 @@ void mmx_movq( struct x86_function *p,   * account any push/pop activity:   */  struct x86_reg x86_fn_arg( struct x86_function *p, -			   GLuint arg ) +			   unsigned arg )  {     return x86_make_disp(x86_make_reg(file_REG32, reg_SP),   			p->stack_offset + arg * 4);	/* ??? */  } -/** - * Initialize an x86_function object, allocating space for up to - * 'code_size' bytes of code. - */ -GLboolean x86_init_func( struct x86_function *p, GLuint code_size ) +void x86_init_func( struct x86_function *p )  { -   assert(!p->store); +   p->size = 0; +   p->store = NULL; +   p->csr = p->store; +} + +int x86_init_func_size( struct x86_function *p, unsigned code_size ) +{ +   p->size = code_size;     p->store = _mesa_exec_malloc(code_size); -   if (p->store) { -      p->csr = p->store; -      return GL_TRUE; -   } -   else { -      p->csr = NULL; -      return GL_FALSE; -   } +   p->csr = p->store; +   return p->store != NULL;  }  void x86_release_func( struct x86_function *p )  { -   if (p->store) -      _mesa_exec_free(p->store); -   p->store = p->csr = NULL; +   _mesa_exec_free(p->store); +   p->store = NULL; +   p->csr = NULL; +   p->size = 0;  }  void (*x86_get_func( struct x86_function *p ))(void)  { -   if (DISASSEM) +   if (DISASSEM && p->store)        _mesa_printf("disassemble %p %p\n", p->store, p->csr); -   return (void (*)(void))p->store; +   return (void (*)(void)) (unsigned long) p->store;  }  #else diff --git a/src/mesa/x86/rtasm/x86sse.h b/src/mesa/x86/rtasm/x86sse.h index 42b09937bc..f6282f5bd4 100644 --- a/src/mesa/x86/rtasm/x86sse.h +++ b/src/mesa/x86/rtasm/x86sse.h @@ -2,26 +2,25 @@  #ifndef _X86SSE_H_  #define _X86SSE_H_ -#if defined(USE_X86_ASM) || defined(SLANG_X86) - -#include "glheader.h" +#if defined(__i386__) || defined(__386__)  /* It is up to the caller to ensure that instructions issued are   * suitable for the host cpu.  There are no checks made in this module   * for mmx/sse/sse2 support on the cpu.   */  struct x86_reg { -   GLuint file:3; -   GLuint idx:3; -   GLuint mod:2;		/* mod_REG if this is just a register */ -   GLint  disp:24;		/* only +/- 23bits of offset - should be enough... */ +   unsigned file:3; +   unsigned idx:3; +   unsigned mod:2;		/* mod_REG if this is just a register */ +   int      disp:24;		/* only +/- 23bits of offset - should be enough... */  };  struct x86_function { -   GLubyte *store; -   GLubyte *csr; -   GLuint stack_offset; -   GLint need_emms; +   unsigned size; +   unsigned char *store; +   unsigned char *csr; +   unsigned stack_offset; +   int need_emms;     const char *fn;  }; @@ -80,7 +79,8 @@ enum sse_cc {   */ -GLboolean x86_init_func( struct x86_function *p, GLuint code_size ); +void x86_init_func( struct x86_function *p ); +int x86_init_func_size( struct x86_function *p, unsigned code_size );  void x86_release_func( struct x86_function *p );  void (*x86_get_func( struct x86_function *p ))( void ); @@ -92,7 +92,7 @@ struct x86_reg x86_make_reg( enum x86_reg_file file,  			     enum x86_reg_name idx );  struct x86_reg x86_make_disp( struct x86_reg reg, -			      GLint disp ); +			      int disp );  struct x86_reg x86_deref( struct x86_reg reg ); @@ -101,31 +101,32 @@ struct x86_reg x86_get_base_reg( struct x86_reg reg );  /* Labels, jumps and fixup:   */ -GLubyte *x86_get_label( struct x86_function *p ); +unsigned char *x86_get_label( struct x86_function *p );  void x86_jcc( struct x86_function *p,  	      enum x86_cc cc, -	      GLubyte *label ); +	      unsigned char *label ); -GLubyte *x86_jcc_forward( struct x86_function *p, +unsigned char *x86_jcc_forward( struct x86_function *p,  			  enum x86_cc cc ); -GLubyte *x86_jmp_forward( struct x86_function *p); +unsigned char *x86_jmp_forward( struct x86_function *p); -GLubyte *x86_call_forward( struct x86_function *p); +unsigned char *x86_call_forward( struct x86_function *p);  void x86_fixup_fwd_jump( struct x86_function *p, -			 GLubyte *fixup ); +			 unsigned char *fixup ); -void x86_jmp( struct x86_function *p, GLubyte *label ); +void x86_jmp( struct x86_function *p, unsigned char *label ); -void x86_call( struct x86_function *p, GLubyte *label ); +/* void x86_call( struct x86_function *p, void (*label)() ); */ +void x86_call( struct x86_function *p, struct x86_reg reg);  /* michal:   * Temporary. As I need immediate operands, and dont want to mess with the codegen,   * I load the immediate into general purpose register and use it.   */ -void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, GLint imm ); +void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm );  /* Macro for sse_shufps() and sse2_pshufd(): @@ -141,19 +142,24 @@ void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg sr  void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, GLubyte shuf ); +void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, +                  unsigned char shuf ); +void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, GLubyte cc ); +void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, +                unsigned char cc );  void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); @@ -166,9 +172,14 @@ void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src )  void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, GLubyte shuf ); +void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, +                 unsigned char shuf ); +void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src );  void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src );  void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); @@ -239,7 +250,7 @@ void x87_fucom( struct x86_function *p, struct x86_reg arg );   * account any push/pop activity.  Note - doesn't track explict   * manipulation of ESP by other instructions.   */ -struct x86_reg x86_fn_arg( struct x86_function *p, GLuint arg ); +struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg );  #endif  #endif  | 
