diff options
113 files changed, 3245 insertions, 2145 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 00000000000..19e5b55fcfa --- /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 438abd94c1c..c7f94d2bada 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 00000000000..56bc6a37a4e --- /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 00000000000..b8668dc5aec --- /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 c87b206f926..00000000000 --- 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 ec1bb8288ef..8b79342e454 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 518f5d2d416..d0f91558b7d 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 407f7123126..f9915d67e54 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 2519a6cc5e1..2b22714c305 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 175ff2d3aff..fb68fd6ee71 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 ad20499f1e7..ab836eb8340 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 dcddee17d45..456bd4a2c70 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 b63693bbb5a..7865753ea97 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 d789b3098e2..6505c315a67 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 7bf64e19e40..116a19b1f5b 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 00000000000..098f5e92ebd --- /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 <[email protected]> + * + */ + +#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 00000000000..f25e52616aa --- /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 <[email protected]> + * + */ + +#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 989697fbcaa..6c7029b6ecf 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 fa52b090768..c872d1641ab 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 3366f005eb5..8fa3700a04c 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 dab454e8e30..514c082f6cd 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; - - for ( i = 0 ; ExtractDir(i, libPaths, 1000, libDir) != 0 ; i++ ) { - char realDriverName[200]; - void *handle = NULL; + if (libPaths == NULL) + libPaths = DEFAULT_DRIVER_DIR; + + 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) +{ + 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 */ + + 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; +} + +static void driDestroyContext(__GLXDRIcontext *context, + __GLXscreenConfigs *psc, Display *dpy) { - __DRIdisplayPrivate *pdpyp = (__DRIdisplayPrivate *)private; - - if (pdpyp) { - const int numScreens = ScreenCount(dpy); - int i; - for (i = 0; i < numScreens; i++) { - if (pdpyp->libraryHandles[i]) { - __DRIdriver *driver, *prev; - - /* 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; - - Xfree(driver->name); - Xfree(driver->libpath); - Xfree(driver); - break; - } - } - - dlclose(pdpyp->libraryHandles[i]); - } - } - Xfree(pdpyp->libraryHandles); - Xfree(pdpyp); + __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 75561685c81..00000000000 --- 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 <[email protected]> - * Brian Paul <[email protected]> - * - */ - -#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 002f7693a0c..ea90282b08f 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 1bcfb94030c..8d0f07fd0a1 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 7eef38446b8..525faab10e9 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 84f556e0cc8..6d78c7067d1 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 1b284c5f451..9ed04290329 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 a8a649c5e33..871adddb953 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 a7b5b798707..bc5b162c679 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 843a2298b24..b650c17c551 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 d0c78b71eed..695a4160942 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 8f67798a085..9d94ca3b39e 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 89c1a099d9d..1f5d65265cf 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) - break; - - if (pdp->w != dc->width || pdp->h != dc->height) - changed = 1; - - 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->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.UpdateBuffer)(pdp, p); + if (dc->drawable == pdp->hHWDrawable) + last_dc = dc; 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; + + pdp->x = last_dc->x; + pdp->y = last_dc->y; + pdp->w = last_dc->width; + pdp->h = last_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->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); + + if (changed) + (*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc); + } - if (ba->drawable != pdp->hHWDrawable) - 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); + + /* Like for buffer attachments, we only care about the most recent + * drawable config. */ + if (last_dc) + (*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc); + + /* 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 e6659811d75..59c64e4adfe 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 9bc868b043b..d1b07c5a2f2 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 dfd02112bad..b5085f49d41 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 */ - - /* 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 (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); - - 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; - } - 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); - - /* 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); - - 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); - - 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; - break; + 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; + + 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 (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); + + d >>= 1; + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; } + } +} - default:{ - GLuint width = mt->width0; - GLuint height = mt->height0; - GLuint img_height; +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; - mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); - mt->total_height = 0; + /* Calculate the size of a single slice. */ + mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0); - 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); + /* 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); - if (mt->compressed) - img_height = MAX2(1, height / 4); - else - img_height = (MAX2(2, height) + 1) & ~1; + stack_height += MAX2(2, height); - mt->total_height += img_height; + width = minify(width); + height = minify(height); + depth = minify(depth); + } - width = minify(width); - height = minify(height); - } - break; + /* 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); + } + + /* 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; +} + +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; + + 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); + + if (mt->compressed) + img_height = MAX2(1, height / 4); + else + img_height = (MAX2(2, height) + 1) & ~1; + + mt->total_height += img_height; + + width = minify(width); + height = minify(height); + } +} + +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; - - mt->total_height = dim * 4 + 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; + 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 * 2); + else + mt->pitch = intel_miptree_pitch_align (intel, mt, 14 * 8); + + 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; + + 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); + + 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; + } + + case 2: + y = mt->total_height - 4; + x = 16 + face * 8; + break; + + case 1: + x += 48; + break; + + default: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; } + } + } +} + +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; + + 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; + + for (level = mt->first_level; level <= mt->last_level; level++) { + GLint x = 0; + GLint y = 0; + GLint q, j; + + 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; + } + + x = 0; + y += pack_y_pitch; + } + mt->total_height += y; - 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; - } - - for (level = mt->first_level; level <= mt->last_level; level++) { - intel_miptree_set_image_offset(mt, level, face, x, y); - - 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; - } - - case 2: - y = mt->total_height - 4; - x = 16 + face * 8; - break; - - case 1: - x += 48; - break; - - default: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - } - } - } - break; + if (pack_x_pitch > 4) { + pack_x_pitch >>= 1; + pack_x_nr <<= 1; + assert(pack_x_pitch * pack_x_nr <= mt->pitch); } - 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; - - 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; - - intel_miptree_set_level_info(mt, level, nr_images, - 0, mt->total_height, - width, height, depth); - - 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; - } - - x = 0; - y += pack_y_pitch; - } - - - mt->total_height += y; - - if (pack_x_pitch > 4) { - pack_x_pitch >>= 1; - pack_x_nr <<= 1; - assert(pack_x_pitch * pack_x_nr <= mt->pitch); - } - - if (pack_y_pitch > 2) { - pack_y_pitch >>= 1; - } - - 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 1c45fd5dcd5..e489d25ae82 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 c856a8627de..94d70be441b 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 29f0b51ba63..bbb4e0f3cda 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 24b0288f887..ce34da165cb 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 918e0001870..57ebf388f58 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 49e739b0ad8..56021fa2094 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 58aeeb4228c..ce0df0357b6 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 dd62be34f4a..252a8996e26 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 8e8fea48e9f..f717b6f6c35 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 2b6087d6915..398048429b7 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 7b5eff4f2d1..d617650fadd 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 ef14b8e89f8..258c6260fb9 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 cdbbe7b6994..31e96a250ac 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 342e7f8496b..abdc92bf014 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 <[email protected]> */ - +#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 645286d4700..297617ee2dc 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 df51f73dd84..a02f70a50c7 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 55527373bcf..7e80724130c 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 fd237ee0287..b2ffc82ed2d 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 1bfae5a069b..205a7160d39 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 26c044d4002..f6f3a38e9e0 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 f2ae210c386..c5c944f781f 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 5199f833e2c..2a25f079e95 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 fb65e66555a..f164b489639 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 0738839cefb..d267a168cd4 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 d3f0681807e..e2388dbb09a 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 6c97955b145..1348b0adcf0 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 94d499f001c..b3f66105469 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 48dcf071317..55503f45ae8 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 3c1a6ffa2a8..c9537dbb9a4 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 77b6c53cb33..4cb68655f2b 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 8b8eeb77aa3..3d46073daad 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 c110df478f2..329af0d1b04 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 34995f4ebf2..3a87137cc9e 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 df08ee1a3be..dd8fbeaa911 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 bd27b86bf32..688e3870df7 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 9fe8e868704..53d00e17a12 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 1abc92ec492..3497738eacf 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 993aa519905..780d9aa5d28 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 a135376398c..deb62b27621 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 3501ba2d093..1b405889c3c 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 0614c8b2e06..2200cec6abe 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 */ - -/* 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) +#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 + /* 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 c4de022d84a..e11b5afc30c 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 4dece95a982..6ad441bdd04 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 93b239ae9f1..d6caa2ac897 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 <[email protected]> */ 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 6207b00a943..b00b8a1ba6d 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 66e6aadc0f0..c3c1f927fd2 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 9ad2dccc124..eb418610a72 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 1d2715da846..8baa59d6171 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 69c361f63e2..62d592767d1 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 a421d049578..8d10d8a7500 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 c82abccc41a..4f287666746 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 671f80c7a48..9b60c732940 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 eb81ee4a528..9d8f2002c9c 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 90554332814..819a7cc5d7b 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 2d2da49fe5b..bab962ad5e1 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 3ae56c8b0b6..1aebb25163f 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 ebdfc452a7a..b0234a2b85e 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 b1c00a36ac6..fb68bf0720e 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 7241cf61be3..adf3d375979 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 11720e4073b..f41ee73c884 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 10fa1965865..74004e9b137 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 1746a876c30..f3aa1ad7249 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 5f3f7d6cf46..3f3ab073cf9 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 e92837f739e..308cce2206c 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 da0bb85f16f..4ae74c1d42b 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 2097c395918..d2c9183558f 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 e9c35fce715..76da855a07e 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 9947544a085..9c307c6275b 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 1e7f6c18e6a..f3dda12e252 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 b74c4ab1c8c..0d1e9bac1c9 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 4733d10bb59..81f5caa2706 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 8df15c8704e..9140d12ea07 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 d4045792790..864f77a4174 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 9515d9f81f5..f1c98fe2d12 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 612cd51a6ee..772471c7230 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 42b09937bca..f6282f5bd41 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 |