diff options
460 files changed, 25049 insertions, 6574 deletions
@@ -183,7 +183,7 @@ ultrix-gcc: # Rules for making release tarballs -VERSION=7.11-devel +VERSION=7.12-devel DIRECTORY = Mesa-$(VERSION) LIB_NAME = MesaLib-$(VERSION) GLUT_NAME = MesaGLUT-$(VERSION) @@ -345,6 +345,16 @@ EGL_FILES = \ $(DIRECTORY)/src/egl/main/*.pc.in \ $(DIRECTORY)/src/egl/main/*.def +GBM_FILES = \ + $(DIRECTORY)/src/gbm/Makefile \ + $(DIRECTORY)/src/gbm/main/*.pc.in \ + $(DIRECTORY)/src/gbm/main/*.[ch] \ + $(DIRECTORY)/src/gbm/main/Makefile \ + $(DIRECTORY)/src/gbm/backends/Makefile \ + $(DIRECTORY)/src/gbm/backends/Makefile.template \ + $(DIRECTORY)/src/gbm/backends/*/*.[ch] \ + $(DIRECTORY)/src/gbm/backends/*/Makefile \ + GALLIUM_FILES = \ $(DIRECTORY)/src/mesa/state_tracker/*[ch] \ $(DIRECTORY)/src/gallium/Makefile \ @@ -376,8 +386,7 @@ DRI_FILES = \ $(DIRECTORY)/src/glx/Makefile \ $(DIRECTORY)/src/glx/*.[ch] \ $(APPLE_DRI_FILES) \ - $(DIRECTORY)/src/mesa/drivers/dri/Makefile \ - $(DIRECTORY)/src/mesa/drivers/dri/Makefile.template \ + $(DIRECTORY)/src/mesa/drivers/dri/Makefile* \ $(DIRECTORY)/src/mesa/drivers/dri/dri.pc.in \ $(DIRECTORY)/src/mesa/drivers/dri/common/xmlpool/*.po \ $(DIRECTORY)/src/mesa/drivers/dri/*/*.[chS] \ @@ -443,6 +452,7 @@ LIB_FILES = \ $(MAPI_FILES) \ $(ES_FILES) \ $(EGL_FILES) \ + $(GBM_FILES) \ $(GALLIUM_FILES) \ $(DRI_FILES) \ $(SGI_GLU_FILES) \ diff --git a/SConstruct b/SConstruct index 8607d2cd8e0..4a3fef08059 100644 --- a/SConstruct +++ b/SConstruct @@ -40,6 +40,9 @@ env = Environment( ENV = os.environ, ) +# XXX: This creates a many problems as it saves... +#opts.Save('config.py', env) + # Backwards compatability with old target configuration variable try: targets = ARGUMENTS['targets'] @@ -80,44 +83,6 @@ env.Append(CPPPATH = [ if env['msvc']: env.Append(CPPPATH = ['#include/c99']) -# Embedded -if env['platform'] == 'embedded': - env.Append(CPPDEFINES = [ - '_POSIX_SOURCE', - ('_POSIX_C_SOURCE', '199309L'), - '_SVID_SOURCE', - '_BSD_SOURCE', - '_GNU_SOURCE', - - 'PTHREADS', - ]) - env.Append(LIBS = [ - 'm', - 'pthread', - 'dl', - ]) - -# Posix -if env['platform'] in ('posix', 'linux', 'freebsd', 'darwin'): - env.Append(CPPDEFINES = [ - '_POSIX_SOURCE', - ('_POSIX_C_SOURCE', '199309L'), - '_SVID_SOURCE', - '_BSD_SOURCE', - '_GNU_SOURCE', - 'PTHREADS', - 'HAVE_POSIX_MEMALIGN', - ]) - if env['gcc']: - env.Append(CFLAGS = ['-fvisibility=hidden']) - if env['platform'] == 'darwin': - env.Append(CPPDEFINES = ['_DARWIN_C_SOURCE']) - env.Append(LIBS = [ - 'm', - 'pthread', - 'dl', - ]) - # for debugging #print env.Dump() @@ -130,7 +95,7 @@ if env['platform'] in ('posix', 'linux', 'freebsd', 'darwin'): # # Create host environent -if env['crosscompile'] and env['platform'] != 'embedded': +if env['crosscompile'] and not env['embedded']: host_env = Environment( options = opts, # no tool used @@ -179,3 +144,18 @@ SConscript( duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html ) + +######################################################################## +# List all aliases + +try: + from SCons.Node.Alias import default_ans +except ImportError: + pass +else: + aliases = default_ans.keys() + aliases.sort() + env.Help('\n') + env.Help('Recognized targets:\n') + for alias in aliases: + env.Help(' %s\n' % alias) diff --git a/common.py b/common.py index 0a3dcdcf543..8657030ea3f 100644 --- a/common.py +++ b/common.py @@ -79,14 +79,17 @@ def AddOptions(opts): from SCons.Options.EnumOption import EnumOption opts.Add(EnumOption('build', 'build type', 'debug', allowed_values=('debug', 'checked', 'profile', 'release'))) - opts.Add(BoolOption('quiet', 'quiet command lines', 'yes')) + opts.Add(BoolOption('verbose', 'verbose output', 'no')) opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine, allowed_values=('generic', 'ppc', 'x86', 'x86_64'))) opts.Add(EnumOption('platform', 'target platform', host_platform, - allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince', 'darwin', 'embedded', 'cygwin', 'sunos', 'freebsd8'))) + allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince', 'darwin', 'cygwin', 'sunos', 'freebsd8'))) + opts.Add(BoolOption('embedded', 'embedded build', 'no')) opts.Add('toolchain', 'compiler toolchain', default_toolchain) opts.Add(BoolOption('gles', 'EXPERIMENTAL: enable OpenGL ES support', 'no')) opts.Add(BoolOption('llvm', 'use LLVM', default_llvm)) opts.Add(BoolOption('debug', 'DEPRECATED: debug build', 'yes')) opts.Add(BoolOption('profile', 'DEPRECATED: profile build', 'no')) - opts.Add(EnumOption('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0'))) + opts.Add(BoolOption('quiet', 'DEPRECATED: profile build', 'yes')) + if host_platform == 'windows': + opts.Add(EnumOption('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0'))) diff --git a/configs/autoconf.in b/configs/autoconf.in index 5595e2abbb6..584f5fd7763 100644 --- a/configs/autoconf.in +++ b/configs/autoconf.in @@ -75,6 +75,7 @@ GLESv2_LIB = GLESv2 VG_LIB = OpenVG GLAPI_LIB = glapi WAYLAND_EGL_LIB = wayland-egl +GBM_LIB = gbm # Library names (actual file names) GL_LIB_NAME = @GL_LIB_NAME@ @@ -88,6 +89,7 @@ GLESv2_LIB_NAME = @GLESv2_LIB_NAME@ VG_LIB_NAME = @VG_LIB_NAME@ GLAPI_LIB_NAME = @GLAPI_LIB_NAME@ WAYLAND_EGL_LIB_NAME = @WAYLAND_EGL_LIB_NAME@ +GBM_LIB_NAME = @GBM_LIB_NAME@ # Globs used to install the lib and all symlinks GL_LIB_GLOB = @GL_LIB_GLOB@ @@ -101,6 +103,7 @@ GLESv2_LIB_GLOB = @GLESv2_LIB_GLOB@ VG_LIB_GLOB = @VG_LIB_GLOB@ GLAPI_LIB_GLOB = @GLAPI_LIB_GLOB@ WAYLAND_EGL_LIB_GLOB = @WAYLAND_EGL_LIB_GLOB@ +GBM_LIB_GLOB = @GBM_LIB_GLOB@ # Directories to build LIB_DIR = @LIB_DIR@ @@ -108,6 +111,7 @@ SRC_DIRS = @SRC_DIRS@ GLU_DIRS = @GLU_DIRS@ DRIVER_DIRS = @DRIVER_DIRS@ EGL_DRIVERS_DIRS = @EGL_DRIVERS_DIRS@ +GBM_BACKEND_DIRS = @GBM_BACKEND_DIRS@ GALLIUM_DIRS = @GALLIUM_DIRS@ GALLIUM_DRIVERS_DIRS = @GALLIUM_DRIVERS_DIRS@ GALLIUM_WINSYS_DIRS = @GALLIUM_WINSYS_DIRS@ @@ -147,7 +151,8 @@ GLESv1_CM_LIB_DEPS = $(EXTRA_LIB_PATH) @GLESv1_CM_LIB_DEPS@ GLESv2_LIB_DEPS = $(EXTRA_LIB_PATH) @GLESv2_LIB_DEPS@ VG_LIB_DEPS = $(EXTRA_LIB_PATH) @VG_LIB_DEPS@ GLAPI_LIB_DEPS = $(EXTRA_LIB_PATH) @GLAPI_LIB_DEPS@ -WAYLAND_EGL_LIB_DEPS = $(EXTRA_LIBPATH) @WAYLAND_EGL_LIB_DEPS@ +WAYLAND_EGL_LIB_DEPS = $(EXTRA_LIB_PATH) @WAYLAND_EGL_LIB_DEPS@ +GBM_LIB_DEPS = $(EXTRA_LIB_PATH) @GBM_LIB_DEPS@ # DRI dependencies MESA_MODULES = @MESA_MODULES@ @@ -212,6 +217,9 @@ EGL_PC_CFLAGS = @GL_PC_CFLAGS@ WAYLAND_EGL_PC_REQ_PRIV = @WAYLAND_EGL_PC_REQ_PRIV@ WAYLAND_EGL_PC_LIB_PRIV = @WAYLAND_EGL_PC_LIB_PRIV@ WAYLAND_EGL_PC_CFLAGS = @WAYLAND_EGL_PC_CFLAGS@ +GBM_PC_REQ_PRIV = @GBM_PC_REQ_PRIV@ +GBM_PC_LIB_PRIV = @GBM_PC_LIB_PRIV@ +GBM_PC_CFLAGS = @GBM_PC_CFLAGS@ XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@ XCB_DRI2_LIBS = @XCB_DRI2_LIBS@ diff --git a/configs/default b/configs/default index b7acfd2f1a5..132ccbee3cf 100644 --- a/configs/default +++ b/configs/default @@ -9,7 +9,7 @@ CONFIG_NAME = default # Version info MESA_MAJOR=7 -MESA_MINOR=11 +MESA_MINOR=12 MESA_TINY=0 MESA_VERSION = $(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY) @@ -63,7 +63,7 @@ GLESv2_LIB = GLESv2 VG_LIB = OpenVG GLAPI_LIB = glapi WAYLAND_EGL_LIB = wayland-egl - +GBM_LIB = gbm # Library names (actual file names) GL_LIB_NAME = lib$(GL_LIB).so @@ -77,6 +77,7 @@ GLESv2_LIB_NAME = lib$(GLESv2_LIB).so VG_LIB_NAME = lib$(VG_LIB).so GLAPI_LIB_NAME = lib$(GLAPI_LIB).so WAYLAND_EGL_LIB_NAME = lib$(WAYLAND_EGL_LIB).so +GBM_LIB_NAME = lib$(GBM_LIB).so # globs used to install the lib and all symlinks GL_LIB_GLOB = $(GL_LIB_NAME)* @@ -90,6 +91,7 @@ GLESv2_LIB_GLOB = $(GLESv2_LIB_NAME)* VG_LIB_GLOB = $(VG_LIB_NAME)* GLAPI_LIB_GLOB = $(GLAPI_LIB_NAME)* WAYLAND_EGL_LIB_GLOB = $(WAYLAND_EGL_LIB_NAME)* +GBM_LIB_GLOB = $(GBM_LIB_NAME)* DRI_CFLAGS = $(CFLAGS) DRI_CXXFLAGS = $(CXXFLAGS) @@ -113,6 +115,9 @@ DRIVER_DIRS = x11 osmesa # EGL drivers to build EGL_DRIVERS_DIRS = glx +# gbm backends to build +GBM_BACKEND_DIRS = dri + # Gallium directories and GALLIUM_DIRS = auxiliary drivers state_trackers GALLIUM_AUXILIARIES = $(TOP)/src/gallium/auxiliary/libgallium.a @@ -140,6 +145,7 @@ GLESv2_LIB_DEPS = $(EXTRA_LIB_PATH) -lpthread VG_LIB_DEPS = $(EXTRA_LIB_PATH) -lpthread GLAPI_LIB_DEPS = $(EXTRA_LIB_PATH) -lpthread WAYLAND_EGL_LIB_DEPS = $(EXTRA_LIB_PATH) -lwayland-client -ldrm +GBM_LIB_DEPS = $(EXTRA_LIB_PATH) -ludev -ldl # Program dependencies - specific GL/glut libraries added in Makefiles APP_LIB_DEPS = -lm @@ -159,6 +165,9 @@ DRI_DRIVER_SEARCH_DIR = $(DRI_DRIVER_INSTALL_DIR) # EGL driver install directory EGL_DRIVER_INSTALL_DIR = $(INSTALL_LIB_DIR)/egl +# gbm backend install directory +GBM_BACKEND_INSTALL_DIR = $(INSTALL_LIB_DIR)/gbm + # Xorg driver install directory (for xorg state-tracker) XORG_DRIVER_INSTALL_DIR = $(INSTALL_LIB_DIR)/xorg/modules/drivers @@ -191,3 +200,6 @@ VG_PC_CFLAGS = WAYLAND_EGL_PC_REQ_PRIV = WAYLAND_EGL_PC_LIB_PRIV = WAYLAND_EGL_PC_CFLAGS = +GBM_PC_REQ_PRIV = +GBM_PC_LIB_PRIV = +GBM_PC_CFLAGS = diff --git a/configs/linux-llvm b/configs/linux-llvm index 359bee28250..54d82b5376c 100644 --- a/configs/linux-llvm +++ b/configs/linux-llvm @@ -42,3 +42,6 @@ endif LD = g++ GL_LIB_DEPS = $(LLVM_LDFLAGS) $(LLVM_LIBS) $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread -lstdc++ + +# to allow the NV drivers to compile +LIBDRM_CFLAGS = $(shell pkg-config --cflags libdrm) diff --git a/configure.ac b/configure.ac index f758f05544a..f470d871e4b 100644 --- a/configure.ac +++ b/configure.ac @@ -177,8 +177,10 @@ if test "x$GXX" = xyes; then AC_MSG_CHECKING([whether $CXX supports -fvisibility=hidden]) VISIBILITY_CXXFLAGS="-fvisibility=hidden" CXXFLAGS="$CXXFLAGS $VISIBILITY_CXXFLAGS" + AC_LANG_PUSH([C++]) AC_LINK_IFELSE([AC_LANG_PROGRAM()], AC_MSG_RESULT([yes]), [VISIBILITY_CXXFLAGS="" ; AC_MSG_RESULT([no])]); + AC_LANG_POP([C++]) # Restore CXXFLAGS; VISIBILITY_CXXFLAGS are added to it where needed. CXXFLAGS=$save_CXXFLAGS @@ -187,6 +189,15 @@ if test "x$GXX" = xyes; then CXXFLAGS="$CXXFLAGS -fno-strict-aliasing" fi +dnl even if the compiler appears to support it, using visibility attributes isn't +dnl going to do anything useful currently on cygwin apart from emit lots of warnings +case "$host_os" in +cygwin*) + VISIBILITY_CFLAGS="" + VISIBILITY_CXXFLAGS="" + ;; +esac + AC_SUBST([VISIBILITY_CFLAGS]) AC_SUBST([VISIBILITY_CXXFLAGS]) @@ -352,6 +363,7 @@ GLESv2_LIB_NAME='lib$(GLESv2_LIB).'${LIB_EXTENSION} VG_LIB_NAME='lib$(VG_LIB).'${LIB_EXTENSION} GLAPI_LIB_NAME='lib$(GLAPI_LIB).'${LIB_EXTENSION} WAYLAND_EGL_LIB_NAME='lib$(WAYLAND_EGL_LIB).'${LIB_EXTENSION} +GBM_LIB_NAME='lib$(GBM_LIB).'${LIB_EXTENSION} GL_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GL_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*' GLU_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GLU_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*' @@ -365,6 +377,7 @@ GLESv2_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GLESv2_LIB)'${LIB_VERSION_SEPARATOR}'*'${LI VG_LIB_GLOB=${LIB_PREFIX_GLOB}'$(VG_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*' GLAPI_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GLAPI_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*' WAYLAND_EGL_LIB_GLOB=${LIB_PREFIX_GLOB}'$(WAYLAND_EGL_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*' +GBM_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GBM_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*' AC_SUBST([GL_LIB_NAME]) AC_SUBST([GLU_LIB_NAME]) @@ -377,6 +390,7 @@ AC_SUBST([GLESv2_LIB_NAME]) AC_SUBST([VG_LIB_NAME]) AC_SUBST([GLAPI_LIB_NAME]) AC_SUBST([WAYLAND_EGL_LIB_NAME]) +AC_SUBST([GBM_LIB_NAME]) AC_SUBST([GL_LIB_GLOB]) AC_SUBST([GLU_LIB_GLOB]) @@ -389,6 +403,7 @@ AC_SUBST([GLESv2_LIB_GLOB]) AC_SUBST([VG_LIB_GLOB]) AC_SUBST([GLAPI_LIB_GLOB]) AC_SUBST([WAYLAND_EGL_LIB_GLOB]) +AC_SUBST([GBM_LIB_GLOB]) dnl dnl Arch/platform-specific settings @@ -507,7 +522,7 @@ if test "x$enable_selinux" = "xyes"; then DEFINES="$DEFINES -DMESA_SELINUX" fi -dnl Determine which APIs to support +dnl Options for APIs AC_ARG_ENABLE([opengl], [AS_HELP_STRING([--disable-opengl], [disable support for standard OpenGL API @<:@default=no@:>@])], @@ -523,32 +538,111 @@ AC_ARG_ENABLE([gles2], [enable support for OpenGL ES 2.x API @<:@default=no@:>@])], [enable_gles2="$enableval"], [enable_gles2=no]) -AC_ARG_ENABLE([gles-overlay], - [AS_HELP_STRING([--enable-gles-overlay], - [DEPRECATED. Same as --enable-gles1 and --enable-gles2])], - [enable_gles1="$enableval"; enable_gles2="$enableval"], - []) - AC_ARG_ENABLE([openvg], [AS_HELP_STRING([--enable-openvg], [enable support for OpenVG API @<:@default=no@:>@])], [enable_openvg="$enableval"], [enable_openvg=no]) -dnl smooth the transition; should be removed eventually -if test "x$enable_openvg" = xno; then - case "x$with_state_trackers" in - x*vega*) - AC_MSG_WARN([vega state tracker is enabled without --enable-openvg]) - enable_openvg=yes - ;; - esac -fi +AC_ARG_ENABLE([dri], + [AS_HELP_STRING([--enable-dri], + [enable DRI modules @<:@default=auto@:>@])], + [enable_dri="$enableval"], + [enable_dri=auto]) +AC_ARG_ENABLE([glx], + [AS_HELP_STRING([--enable-glx], + [enable GLX library @<:@default=auto@:>@])], + [enable_glx="$enableval"], + [enable_glx=auto]) +AC_ARG_ENABLE([osmesa], + [AS_HELP_STRING([--enable-osmesa], + [enable OSMesa library @<:@default=auto@:>@])], + [enable_osmesa="$enableval"], + [enable_osmesa=auto]) +AC_ARG_ENABLE([egl], + [AS_HELP_STRING([--disable-egl], + [disable EGL library @<:@default=enabled@:>@])], + [enable_egl="$enableval"], + [enable_egl=yes]) + +AC_ARG_ENABLE([xorg], + [AS_HELP_STRING([--enable-xorg], + [enable support for X.Org DDX API @<:@default=no@:>@])], + [enable_xorg="$enableval"], + [enable_xorg=no]) +AC_ARG_ENABLE([xa], + [AS_HELP_STRING([--enable-xa], + [enable build of the XA X Acceleration API @<:@default=no@:>@])], + [enable_xa="$enableval"], + [enable_xa=no]) +AC_ARG_ENABLE([d3d1x], + [AS_HELP_STRING([--enable-d3d1x], + [enable support for Direct3D 10 & 11 low-level API @<:@default=no@:>@])], + [enable_d3d1x="$enableval"], + [enable_d3d1x=no]) +AC_ARG_ENABLE([gbm], + [AS_HELP_STRING([--enable-gbm], + [enable gbm library @<:@default=auto@:>@])], + [enable_gbm="$enableval"], + [enable_gbm=auto]) + +AC_ARG_ENABLE([xvmc], + [AS_HELP_STRING([--enable-xvmc], + [enable xvmc library @<:@default=auto@:>@])], + [enable_xvmc="$enableval"], + [enable_xvmc=auto]) +AC_ARG_ENABLE([vdpau], + [AS_HELP_STRING([--enable-vdpau], + [enable vdpau library @<:@default=auto@:>@])], + [enable_vdpau="$enableval"], + [enable_vdpau=auto]) +AC_ARG_ENABLE([va], + [AS_HELP_STRING([--enable-va], + [enable va library @<:@default=auto@:>@])], + [enable_va="$enableval"], + [enable_va=auto]) + +AC_ARG_ENABLE([xlib_glx], + [AS_HELP_STRING([--enable-xlib-glx], + [make GLX library Xlib-based instead of DRI-based @<:@default=disable@:>@])], + [enable_xlib_glx="$enableval"], + [enable_xlib_glx=auto]) +AC_ARG_ENABLE([gallium_egl], + [AS_HELP_STRING([--enable-gallium-egl], + [enable optional EGL state tracker (not required + for EGL support in Gallium with OpenGL and OpenGL ES) + @<:@default=disable@:>@])], + [enable_gallium_egl="$enableval"], + [enable_gallium_egl=no]) +AC_ARG_ENABLE([gallium_gbm], + [AS_HELP_STRING([--enable-gallium-gbm], + [enable optional gbm state tracker (not required for + gbm support in Gallium) + @<:@default=auto@:>@])], + [enable_gallium_gbm="$enableval"], + [enable_gallium_gbm=auto]) + +# Option for Gallium drivers +GALLIUM_DRIVERS_DEFAULT="r300,r600,swrast" + +AC_ARG_WITH([gallium-drivers], + [AS_HELP_STRING([--with-gallium-drivers@<:@=DIRS...@:>@], + [comma delimited Gallium drivers list, e.g. + "i915,i965,nouveau,r300,r600,svga,swrast" + @<:@default=r300,r600,swrast@:>@])], + [with_gallium_drivers="$withval"], + [with_gallium_drivers="$GALLIUM_DRIVERS_DEFAULT"]) if test "x$enable_opengl" = xno -a \ "x$enable_gles1" = xno -a \ "x$enable_gles2" = xno -a \ - "x$enable_openvg" = xno; then + "x$enable_openvg" = xno -a \ + "x$enable_xorg" = xno -a \ + "x$enable_xa" = xno -a \ + "x$enable_d3d1x" = xno -a \ + "x$enable_xvmc" = xno -a \ + "x$enable_vdpau" = xno -a \ + "x$enable_va" = xno; then AC_MSG_ERROR([at least one API should be enabled]) fi @@ -602,24 +696,60 @@ if test "x$enable_opengl" = xno; then fi AC_ARG_WITH([driver], - [AS_HELP_STRING([--with-driver=DRIVER], - [driver for Mesa: xlib,dri,osmesa @<:@default=dri when available, or xlib@:>@])], + [AS_HELP_STRING([--with-driver=DRIVER], [DEPRECATED])], [mesa_driver="$withval"], - [mesa_driver="$default_driver"]) + [mesa_driver=auto]) dnl Check for valid option case "x$mesa_driver" in -xxlib|xdri|xosmesa) - if test "x$enable_opengl" = xno; then - AC_MSG_ERROR([Driver '$mesa_driver' requires OpenGL enabled]) +xxlib|xdri|xosmesa|xno) + if test "x$enable_dri" != xauto -o \ + "x$enable_glx" != xauto -o \ + "x$enable_osmesa" != xauto -o \ + "x$enable_xlib_glx" != xauto; then + AC_MSG_ERROR([--with-driver=$mesa_driver is deprecated]) fi ;; -xno) +xauto) + mesa_driver="$default_driver" ;; *) AC_MSG_ERROR([Driver '$mesa_driver' is not a valid option]) ;; esac +# map $mesa_driver to APIs +if test "x$enable_dri" = xauto; then + case "x$mesa_driver" in + xdri) enable_dri=yes ;; + *) enable_dri=no ;; + esac +fi + +if test "x$enable_glx" = xauto; then + case "x$mesa_driver" in + xdri|xxlib) enable_glx=yes ;; + *) enable_glx=no ;; + esac +fi + +if test "x$enable_osmesa" = xauto; then + case "x$mesa_driver" in + xxlib|xosmesa) enable_osmesa=yes ;; + *) enable_osmesa=no ;; + esac +fi + +if test "x$enable_xlib_glx" = xauto; then + case "x$mesa_driver" in + xxlib) enable_xlib_glx=yes ;; + *) enable_xlib_glx=no ;; + esac +fi + +if test "x$enable_glx" = xno; then + enable_xlib_glx=no +fi + dnl dnl Driver specific build directories dnl @@ -657,11 +787,6 @@ if test "x$enable_gles2" = xyes; then CORE_DIRS="$CORE_DIRS mapi/es2api" fi -# build vgapi if OpenVG is enabled -if test "x$enable_openvg" = xyes; then - CORE_DIRS="$CORE_DIRS mapi/vgapi" -fi - # build glsl and mesa if OpenGL or OpenGL ES is enabled case "x$enable_opengl$enable_gles1$enable_gles2" in x*yes*) @@ -669,24 +794,36 @@ x*yes*) ;; esac -case "$mesa_driver" in -xlib) - DRIVER_DIRS="x11" +case "x$enable_glx$enable_xlib_glx" in +xyesyes) + DRIVER_DIRS="$DRIVER_DIRS x11" GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/xlib" GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS libgl-xlib" + GALLIUM_STATE_TRACKERS_DIRS="glx $GALLIUM_STATE_TRACKERS_DIRS" ;; -dri) +xyesno) + # DRI-based GLX SRC_DIRS="$SRC_DIRS glx" - DRIVER_DIRS="dri" - GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/xlib sw/dri" - ;; -osmesa) - DRIVER_DIRS="osmesa" - ;; -no) - DRIVER_DRIS="" ;; esac + +if test "x$enable_dri" = xyes; then + DRIVER_DIRS="$DRIVER_DIRS dri" + + GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/xlib sw/dri" + GALLIUM_STATE_TRACKERS_DIRS="dri $GALLIUM_STATE_TRACKERS_DIRS" + HAVE_ST_DRI="yes" +fi + +if test "x$enable_osmesa" = xyes; then + # the empty space matters for osmesa... (see src/mesa/Makefile) + if test -n "$DRIVER_DIRS"; then + DRIVER_DIRS="$DRIVER_DIRS osmesa" + else + DRIVER_DIRS="osmesa" + fi +fi + AC_SUBST([SRC_DIRS]) AC_SUBST([GLU_DIRS]) AC_SUBST([DRIVER_DIRS]) @@ -697,6 +834,22 @@ AC_SUBST([GALLIUM_DRIVERS_DIRS]) AC_SUBST([GALLIUM_STATE_TRACKERS_DIRS]) AC_SUBST([MESA_LLVM]) +# Check for libdrm +PKG_CHECK_MODULES([LIBDRM], [libdrm >= $LIBDRM_REQUIRED], + [have_libdrm=yes], [have_libdrm=no]) + +if test "x$enable_dri" = xyes; then + # DRI must be shared, I think + if test "$enable_static" = yes; then + AC_MSG_ERROR([Can't use static libraries for DRI drivers]) + fi + + # not a hard requirement as swrast does not depend on it + if test "x$have_libdrm" = xyes; then + DRI_PC_REQ_PRIV="libdrm >= $LIBDRM_REQUIRED" + fi +fi + dnl dnl Find out if X is available. The variable have_x is set if libX11 is dnl found to mimic AC_PATH_XTRA. @@ -731,13 +884,9 @@ m4_divert_once([HELP_BEGIN], pkg-config utility.]) dnl We need X for xlib and dri, so bomb now if it's not found -case "$mesa_driver" in -xlib|dri) - if test "$no_x" = yes; then - AC_MSG_ERROR([X11 development libraries needed for $mesa_driver driver]) - fi - ;; -esac +if test "x$enable_glx" = xyes -a "x$no_x" = xyes; then + AC_MSG_ERROR([X11 development libraries needed for GLX]) +fi dnl XCB - this is only used for GLX right now AC_ARG_ENABLE([xcb], @@ -775,8 +924,9 @@ AC_ARG_ENABLE([driglx-direct], dnl dnl libGL configuration per driver dnl -case "$mesa_driver" in -xlib) +case "x$enable_glx$enable_xlib_glx" in +xyesyes) + # Xlib-based GLX if test "$x11_pkgconfig" = yes; then PKG_CHECK_MODULES([XLIBGL], [x11 xext]) GL_PC_REQ_PRIV="x11 xext" @@ -799,22 +949,16 @@ xlib) GL_LIB_DEPS="" fi ;; -dri|no) # these checks are still desired when there is no mesa_driver - # DRI must be shared, I think - if test "$enable_static" = yes; then - AC_MSG_ERROR([Can't use static libraries for DRI drivers]) - fi - +xyesno) + # DRI-based GLX PKG_CHECK_MODULES([GLPROTO], [glproto >= $GLPROTO_REQUIRED]) GL_PC_REQ_PRIV="glproto >= $GLPROTO_REQUIRED" - DRI_PC_REQ_PRIV="" - if test x"$driglx_direct" = xyes; then - # Check for libdrm - PKG_CHECK_MODULES([LIBDRM], [libdrm >= $LIBDRM_REQUIRED]) + if test "x$have_libdrm" != xyes; then + AC_MSG_ERROR([Direct rendering requires libdrm >= $LIBDRM_REQUIRED]) + fi PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= $DRI2PROTO_REQUIRED]) GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV libdrm >= $LIBDRM_REQUIRED dri2proto >= $DRI2PROTO_REQUIRED" - DRI_PC_REQ_PRIV="libdrm >= $LIBDRM_REQUIRED" fi # find the DRI deps for libGL @@ -839,7 +983,11 @@ dri|no) # these checks are still desired when there is no mesa_driver else # should check these... X11_INCLUDES="$X11_INCLUDES $X_CFLAGS" - GL_LIB_DEPS="$X_LIBS -lX11 -lXext -lXxf86vm -lXdamage -lXfixes" + if test "x$HAVE_XF86VIDMODE" == xyes; then + GL_LIB_DEPS="$X_LIBS -lX11 -lXext -lXxf86vm -lXdamage -lXfixes" + else + GL_LIB_DEPS="$X_LIBS -lX11 -lXext -lXdamage -lXfixes" + fi GL_PC_LIB_PRIV="$GL_LIB_DEPS" GL_PC_CFLAGS="$X11_INCLUDES" @@ -855,16 +1003,14 @@ dri|no) # these checks are still desired when there is no mesa_driver # need DRM libs, -lpthread, etc. GL_LIB_DEPS="$GL_LIB_DEPS $LIBDRM_LIBS -lm -lpthread $DLOPEN_LIBS" GL_PC_LIB_PRIV="-lm -lpthread $DLOPEN_LIBS" - GLESv1_CM_LIB_DEPS="$LIBDRM_LIBS -lm -lpthread $DLOPEN_LIBS" - GLESv1_CM_PC_LIB_PRIV="-lm -lpthread $DLOPEN_LIBS" - GLESv2_LIB_DEPS="$LIBDRM_LIBS -lm -lpthread $DLOPEN_LIBS" - GLESv2_PC_LIB_PRIV="-lm -lpthread $DLOPEN_LIBS" - ;; -osmesa) - # No libGL for osmesa - GL_LIB_DEPS="" ;; esac + +GLESv1_CM_LIB_DEPS="$LIBDRM_LIBS -lm -lpthread $DLOPEN_LIBS" +GLESv1_CM_PC_LIB_PRIV="-lm -lpthread $DLOPEN_LIBS" +GLESv2_LIB_DEPS="$LIBDRM_LIBS -lm -lpthread $DLOPEN_LIBS" +GLESv2_PC_LIB_PRIV="-lm -lpthread $DLOPEN_LIBS" + AC_SUBST([GL_LIB_DEPS]) AC_SUBST([GL_PC_REQ_PRIV]) AC_SUBST([GL_PC_LIB_PRIV]) @@ -890,7 +1036,7 @@ AC_ARG_ENABLE([shared-dricore], [link DRI modules with shared core DRI routines @<:@default=disabled@:>@])], [enable_dricore="$enableval"], [enable_dricore=no]) -if test "$mesa_driver" = dri ; then +if test "x$enable_dri" = xyes ; then if test "$enable_dricore" = yes ; then if test "$GCC$GXX" != yesyes ; then AC_MSG_WARN([Shared dricore requires GCC-compatible rpath handling. Disabling shared dricore]) @@ -921,11 +1067,19 @@ PKG_CHECK_MODULES([LIBDRM_RADEON], HAVE_LIBDRM_RADEON=no) dnl -dnl More X11 setup +dnl More GLX setup dnl -if test "$mesa_driver" = xlib; then +case "x$enable_glx$enable_xlib_glx" in +xyesyes) DEFINES="$DEFINES -DUSE_XSHM" -fi + ;; +xyesno) + DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING" + if test "x$driglx_direct" = xyes; then + DEFINES="$DEFINES -DGLX_DIRECT_RENDERING" + fi + ;; +esac dnl dnl TLS detection @@ -975,7 +1129,10 @@ DRI_DIRS="" case "$with_dri_drivers" in no) ;; yes) - DRI_DIRS="yes" + # classic DRI drivers require FEATURE_GL to build + if test "x$enable_opengl" = xyes; then + DRI_DIRS="yes" + fi ;; *) # verify the requested driver directories exist @@ -985,19 +1142,19 @@ yes) AC_MSG_ERROR([DRI driver directory '$driver' doesn't exist]) done DRI_DIRS="$dri_drivers" + if test -n "$DRI_DIRS" -a "x$enable_opengl" != xyes; then + AC_MSG_ERROR([--with-dri-drivers requires OpenGL]) + fi ;; esac dnl Set DRI_DIRS, DEFINES and LIB_DEPS -if test "$mesa_driver" = dri -o "$mesa_driver" = no; then +if test "x$enable_dri" = xyes; then # Platform specific settings and drivers to build case "$host_os" in linux*) DEFINES="$DEFINES -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER" - if test "x$driglx_direct" = xyes; then - DEFINES="$DEFINES -DGLX_DIRECT_RENDERING" - fi - DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING -DHAVE_ALIAS" + DEFINES="$DEFINES -DHAVE_ALIAS" case "$host_cpu" in x86_64) @@ -1027,10 +1184,6 @@ if test "$mesa_driver" = dri -o "$mesa_driver" = no; then freebsd* | dragonfly* | *netbsd*) DEFINES="$DEFINES -DPTHREADS -DUSE_EXTERNAL_DXTN_LIB=1" DEFINES="$DEFINES -DIN_DRI_DRIVER -DHAVE_ALIAS" - DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING" - if test "x$driglx_direct" = xyes; then - DEFINES="$DEFINES -DGLX_DIRECT_RENDERING" - fi if test "x$DRI_DIRS" = "xyes"; then DRI_DIRS="i810 i915 i965 mach64 mga nouveau r128 r200 r300 r600 \ @@ -1039,21 +1192,13 @@ if test "$mesa_driver" = dri -o "$mesa_driver" = no; then ;; gnu*) DEFINES="$DEFINES -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER" - DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING -DHAVE_ALIAS" + DEFINES="$DEFINES -DHAVE_ALIAS" ;; solaris*) DEFINES="$DEFINES -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER" - DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING" - if test "x$driglx_direct" = xyes; then - DEFINES="$DEFINES -DGLX_DIRECT_RENDERING" - fi ;; cygwin*) DEFINES="$DEFINES -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER" - DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING" - if test "x$driglx_direct" = xyes; then - DEFINES="$DEFINES -DGLX_DIRECT_RENDERING" - fi if test "x$DRI_DIRS" = "xyes"; then DRI_DIRS="swrast" fi @@ -1069,7 +1214,7 @@ if test "$mesa_driver" = dri -o "$mesa_driver" = no; then DRI_DIRS=`echo "$DRI_DIRS" | $SED 's/ */ /g'` # Check for expat - if test "$mesa_driver" = dri; then + if test "x$enable_dri" = xyes; then EXPAT_INCLUDES="" EXPAT_LIB=-lexpat AC_ARG_WITH([expat], @@ -1085,6 +1230,13 @@ if test "$mesa_driver" = dri -o "$mesa_driver" = no; then [AC_MSG_ERROR([Expat required for DRI.])]) fi + # libdrm is required for all except swrast + if test -n "$DRI_DIRS" -a x"$DRI_DIRS" != xswrast; then + if test "x$have_libdrm" != xyes; then + AC_MSG_ERROR([DRI drivers requires libdrm >= $LIBDRM_REQUIRED]) + fi + fi + # put all the necessary libs together, including possibly libdricore DRI_LIB_DEPS="$DRI_LIB_DEPS $SELINUX_LIBS $LIBDRM_LIBS $EXPAT_LIB -lm -lpthread $DLOPEN_LIBS" fi @@ -1119,26 +1271,6 @@ AC_SUBST([RADEON_LDFLAGS]) dnl dnl OSMesa configuration dnl -if test "$mesa_driver" = xlib; then - default_gl_osmesa=yes -else - default_gl_osmesa=no -fi -AC_ARG_ENABLE([gl-osmesa], - [AS_HELP_STRING([--enable-gl-osmesa], - [enable OSMesa with libGL @<:@default=enabled for xlib driver@:>@])], - [gl_osmesa="$enableval"], - [gl_osmesa="$default_gl_osmesa"]) -if test "x$gl_osmesa" = xyes; then - if test "x$enable_opengl" = xno; then - AC_MSG_ERROR([OpenGL is not available for OSMesa driver]) - fi - if test "$mesa_driver" = osmesa; then - AC_MSG_ERROR([libGL is not available for OSMesa driver]) - else - DRIVER_DIRS="$DRIVER_DIRS osmesa" - fi -fi dnl Configure the channel bits for OSMesa (libOSMesa, libOSMesa16, ...) AC_ARG_WITH([osmesa-bits], @@ -1146,9 +1278,11 @@ AC_ARG_WITH([osmesa-bits], [OSMesa channel bits and library name: 8, 16, 32 @<:@default=8@:>@])], [osmesa_bits="$withval"], [osmesa_bits=8]) -if test "$mesa_driver" != osmesa && test "x$osmesa_bits" != x8; then - AC_MSG_WARN([Ignoring OSMesa channel bits for non-OSMesa driver]) - osmesa_bits=8 +if test "x$osmesa_bits" != x8; then + if test "x$enable_dri" = xyes -o "x$enable_glx" = xyes; then + AC_MSG_WARN([Ignoring OSMesa channel bits because of non-OSMesa driver]) + osmesa_bits=8 + fi fi case "x$osmesa_bits" in x8) @@ -1164,8 +1298,7 @@ x16|x32) esac AC_SUBST([OSMESA_LIB]) -case "$DRIVER_DIRS" in -*osmesa*) +if test "x$enable_osmesa" = xyes; then # only link libraries with osmesa if shared if test "$enable_static" = no; then OSMESA_LIB_DEPS="-lm -lpthread $SELINUX_LIBS $DLOPEN_LIBS" @@ -1174,8 +1307,7 @@ case "$DRIVER_DIRS" in fi OSMESA_MESA_DEPS="" OSMESA_PC_LIB_PRIV="-lm -lpthread $SELINUX_LIBS $DLOPEN_LIBS" - ;; -esac +fi AC_SUBST([OSMESA_LIB_DEPS]) AC_SUBST([OSMESA_MESA_DEPS]) AC_SUBST([OSMESA_PC_REQ]) @@ -1184,26 +1316,16 @@ AC_SUBST([OSMESA_PC_LIB_PRIV]) dnl dnl EGL configuration dnl -AC_ARG_ENABLE([egl], - [AS_HELP_STRING([--disable-egl], - [disable EGL library @<:@default=enabled@:>@])], - [enable_egl="$enableval"], - [enable_egl=yes]) -if test "x$enable_egl" = xno; then - if test "x$mesa_driver" = xno; then - AC_MSG_ERROR([cannot disable EGL when there is no mesa driver]) - fi - if test "x$enable_openvg" = xyes; then - AC_MSG_ERROR([cannot enable OpenVG without EGL]) - fi -fi +EGL_CLIENT_APIS="" + if test "x$enable_egl" = xyes; then SRC_DIRS="$SRC_DIRS egl" EGL_LIB_DEPS="$DLOPEN_LIBS $SELINUX_LIBS -lpthread" EGL_DRIVERS_DIRS="" + if test "$enable_static" != yes; then # build egl_glx when libGL is built - if test "$mesa_driver" = xlib -o "$mesa_driver" = dri; then + if test "x$enable_glx" = xyes; then EGL_DRIVERS_DIRS="glx" fi @@ -1212,7 +1334,7 @@ if test "x$enable_egl" = xyes; then if test "$have_libudev" = yes; then DEFINES="$DEFINES -DHAVE_LIBUDEV" fi - if test "$mesa_driver" = dri; then + if test "x$enable_dri" = xyes; then # build egl_dri2 when xcb-dri2 is available PKG_CHECK_MODULES([XCB_DRI2], [x11-xcb xcb-dri2 xcb-xfixes], [have_xcb_dri2=yes],[have_xcb_dri2=no]) @@ -1233,6 +1355,192 @@ AC_SUBST([EGL_LIB_DEPS]) AC_SUBST([EGL_DRIVERS_DIRS]) dnl +dnl gbm configuration +dnl +if test "x$enable_gbm" = xauto; then + case "$with_egl_platforms" in + *drm*) + enable_gbm=yes ;; + *) + enable_gbm=no ;; + esac +fi +if test "x$enable_gbm" = xyes; then + SRC_DIRS="$SRC_DIRS gbm" + GBM_BACKEND_DIRS="" + + PKG_CHECK_MODULES([LIBUDEV], [libudev], [], + AC_MSG_ERROR([gbm needs udev])) + GBM_LIB_DEPS="$DLOPEN_LIBS $LIBUDEV_LIBS" + + if test "x$enable_dri" = xyes; then + GBM_BACKEND_DIRS="$GBM_BACKEND_DIRS dri" + if test "$SHARED_GLAPI" -eq 0; then + AC_MSG_ERROR([gbm_dri requires --enable-shared-glapi]) + fi + fi +fi +AC_SUBST([GBM_LIB_DEPS]) +AC_SUBST([GBM_BACKEND_DIRS]) +GBM_PC_REQ_PRIV="libudev" +GBM_PC_LIB_PRIV="$DLOPEN_LIBS" +GBM_PC_CFLAGS= +AC_SUBST([GBM_PC_REQ_PRIV]) +AC_SUBST([GBM_PC_LIB_PRIV]) +AC_SUBST([GBM_PC_CFLAGS]) + +dnl +dnl EGL Gallium configuration +dnl +if test "x$enable_gallium_egl" = xyes; then + if test "x$with_gallium_drivers" = x; then + AC_MSG_ERROR([cannot enable egl_gallium without Gallium]) + fi + if test "x$enable_egl" = xno; then + AC_MSG_ERROR([cannot enable egl_gallium without EGL]) + fi + if test "x$have_libdrm" != xyes; then + AC_MSG_ERROR([egl_gallium requires libdrm >= $LIBDRM_REQUIRED]) + fi + + GALLIUM_STATE_TRACKERS_DIRS="egl $GALLIUM_STATE_TRACKERS_DIRS" + GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS egl-static" + HAVE_ST_EGL="yes" +fi + +dnl +dnl gbm Gallium configuration +dnl +if test "x$enable_gallium_gbm" = xauto; then + case "$enable_gbm$HAVE_ST_EGL$with_egl_platforms" in + yesyes*drm*) + enable_gallium_gbm=yes ;; + *) + enable_gallium_gbm=no ;; + esac +fi +if test "x$enable_gallium_gbm" = xyes; then + if test "x$with_gallium_drivers" = x; then + AC_MSG_ERROR([cannot enable gbm_gallium without Gallium]) + fi + if test "x$enable_gbm" = xno; then + AC_MSG_ERROR([cannot enable gbm_gallium without gbm]) + fi + + GALLIUM_STATE_TRACKERS_DIRS="gbm $GALLIUM_STATE_TRACKERS_DIRS" + GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS gbm" + HAVE_ST_GBM="yes" +fi + +dnl +dnl X.Org DDX configuration +dnl +if test "x$enable_xorg" = xyes; then + PKG_CHECK_MODULES([XORG], [xorg-server >= 1.6.0]) + PKG_CHECK_MODULES([LIBDRM_XORG], [libdrm >= $LIBDRM_XORG_REQUIRED]) + PKG_CHECK_MODULES([LIBKMS_XORG], [libkms >= $LIBKMS_XORG_REQUIRED]) + PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1], + HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71", + HAVE_XEXTPROTO_71="no") + GALLIUM_STATE_TRACKERS_DIRS="xorg $GALLIUM_STATE_TRACKERS_DIRS" + HAVE_ST_XORG=yes +fi + +dnl +dnl XA configuration +dnl +if test "x$enable_xa" = xyes; then + GALLIUM_STATE_TRACKERS_DIRS="xa $GALLIUM_STATE_TRACKERS_DIRS" + HAVE_ST_XA=yes +fi + +dnl +dnl OpenVG configuration +dnl +VG_LIB_DEPS="" + +if test "x$enable_openvg" = xyes; then + if test "x$enable_egl" = xno; then + AC_MSG_ERROR([cannot enable OpenVG without EGL]) + fi + if test "x$with_gallium_drivers" = x; then + AC_MSG_ERROR([cannot enable OpenVG without Gallium]) + fi + if test "x$enable_gallium_egl" = xno; then + AC_MSG_ERROR([cannot enable OpenVG without egl_gallium]) + fi + + EGL_CLIENT_APIS="$EGL_CLIENT_APIS "'$(VG_LIB)' + VG_LIB_DEPS="$VG_LIB_DEPS $SELINUX_LIBS -lpthread" + CORE_DIRS="$CORE_DIRS mapi/vgapi" + GALLIUM_STATE_TRACKERS_DIRS="vega $GALLIUM_STATE_TRACKERS_DIRS" + HAVE_ST_VEGA=yes +fi + +dnl +dnl D3D1X configuration +dnl + +if test "x$enable_d3d1x" = xyes; then + if test "x$with_gallium_drivers" = x; then + AC_MSG_ERROR([cannot enable D3D1X without Gallium]) + fi + + GALLIUM_STATE_TRACKERS_DIRS="d3d1x $GALLIUM_STATE_TRACKERS_DIRS" + HAVE_ST_D3D1X=yes +fi + +dnl +dnl Gallium G3DVL configuration +dnl +AC_ARG_ENABLE([gallium-g3dvl], + [AS_HELP_STRING([--enable-gallium-g3dvl], + [build gallium g3dvl @<:@default=disabled@:>@])], + [enable_gallium_g3dvl="$enableval"], + [enable_gallium_g3dvl=no]) +if test "x$enable_gallium_g3dvl" = xyes; then + if test "x$with_gallium_drivers" = x; then + AC_MSG_ERROR([cannot enable G3DVL without Gallium]) + fi + + if test "x$enable_xvmc" = xauto; then + enable_xvmc=yes + fi + + if test "x$enable_vdpau" = xauto; then + enable_vdpau=yes + fi + + if test "x$enable_va" = xauto; then + enable_va=no + fi +fi + +#TODO: Check for xvmc libs/headers +if test "x$enable_xvmc" = xyes; then + GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS xorg/xvmc" + HAVE_ST_XVMC="yes" +fi + +#TODO: Check for vdpau libs/headers +if test "x$enable_vdpau" = xyes; then + GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS vdpau" + HAVE_ST_VDPAU="yes" +fi + +#TODO: Check for va libs/headers +if test "x$enable_va" = xyes; then + GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS va" + HAVE_ST_VA="yes" +fi + +if test "x$enable_xvmc" = xyes || + test "x$enable_vdpau" = xyes || + test "x$enable_va" = xyes; then + GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS g3dvl/dri" +fi + +dnl dnl GLU configuration dnl AC_ARG_ENABLE([glu], @@ -1241,16 +1549,17 @@ AC_ARG_ENABLE([glu], [enable_glu="$enableval"], [enable_glu=yes]) -if test "x$enable_glu" = xyes -a "x$mesa_driver" = xno; then - AC_MSG_NOTICE([Disabling GLU since there is no OpenGL driver]) - enable_glu=no +if test "x$enable_glu" = xyes; then + if test "x$enable_glx" = xno -a "x$enable_osmesa" = xno; then + AC_MSG_NOTICE([Disabling GLU since there is no OpenGL driver]) + enable_glu=no + fi fi if test "x$enable_glu" = xyes; then SRC_DIRS="$SRC_DIRS glu" - case "$mesa_driver" in - osmesa) + if test "x$enable_glx" = xno; then # Link libGLU to libOSMesa instead of libGL GLU_LIB_DEPS="" GLU_PC_REQ="osmesa" @@ -1259,8 +1568,7 @@ if test "x$enable_glu" = xyes; then else GLU_MESA_DEPS="" fi - ;; - *) + else # If static, empty GLU_LIB_DEPS and add libs for programs to link GLU_PC_REQ="gl" GLU_PC_LIB_PRIV="-lm" @@ -1272,8 +1580,7 @@ if test "x$enable_glu" = xyes; then GLU_MESA_DEPS="" APP_LIB_DEPS="$APP_LIB_DEPS -lstdc++" fi - ;; - esac + fi fi if test "$enable_static" = no; then GLU_LIB_DEPS="$GLU_LIB_DEPS $OS_CPLUSPLUS_LIBS" @@ -1295,13 +1602,9 @@ AC_ARG_ENABLE([glw], [enable_glw="$enableval"], [enable_glw=yes]) dnl Don't build GLw on osmesa -if test "x$enable_glw" = xyes; then - case "$mesa_driver" in - osmesa|no) - AC_MSG_NOTICE([Disabling GLw since there is no OpenGL driver]) - enable_glw=no - ;; - esac +if test "x$enable_glw" = xyes -a "x$enable_glx" = xno; then + AC_MSG_NOTICE([Disabling GLw since there is no OpenGL driver]) + enable_glw=no fi AC_ARG_ENABLE([motif], [AS_HELP_STRING([--enable-motif], @@ -1375,14 +1678,10 @@ AC_ARG_ENABLE([glut], [enable_glut="$enableval"], [enable_glut="$default_glut"]) -dnl Don't build glut on osmesa -if test "x$enable_glut" = xyes; then - case "$mesa_driver" in - osmesa|no) - AC_MSG_NOTICE([Disabling glut since there is no OpenGL driver]) - enable_glut=no - ;; - esac +dnl Don't build glut without GLX +if test "x$enable_glut" = xyes -a "x$enable_glx" = xno; then + AC_MSG_NOTICE([Disabling glut since there is no OpenGL driver]) + enable_glut=no fi dnl Can't build glut if GLU not available if test "x$enable_glu$enable_glut" = xnoyes; then @@ -1448,17 +1747,11 @@ AC_SUBST([PROGRAM_DIRS]) dnl dnl Gallium configuration dnl -AC_ARG_ENABLE([gallium], - [AS_HELP_STRING([--disable-gallium], - [build gallium @<:@default=enabled@:>@])], - [enable_gallium="$enableval"], - [enable_gallium=yes]) -if test "x$enable_gallium" = xno -a "x$enable_openvg" = xyes; then - AC_MSG_ERROR([cannot enable OpenVG without Gallium]) -fi -if test "x$enable_gallium" = xyes; then +if test "x$with_gallium_drivers" != x; then SRC_DIRS="$SRC_DIRS gallium gallium/winsys gallium/targets" AC_PATH_PROG([LLVM_CONFIG], [llvm-config], [no]) +else + LLVM_CONFIG=no fi AC_SUBST([LLVM_CFLAGS]) @@ -1466,192 +1759,29 @@ AC_SUBST([LLVM_LIBS]) AC_SUBST([LLVM_LDFLAGS]) AC_SUBST([LLVM_VERSION]) -dnl -dnl Gallium state trackers configuration -dnl - -AC_ARG_ENABLE([gallium-egl], - [AS_HELP_STRING([--enable-gallium-egl], - [enable gallium EGL state tracker @<:@default=auto@:>@])], - [enable_gallium_egl="$enableval"], - [enable_gallium_egl=auto]) -if test "x$enable_gallium_egl" = xauto; then - case "$mesa_driver" in - dri|no) - enable_gallium_egl=$enable_egl - ;; - *) - enable_gallium_egl=$enable_openvg - ;; - esac -fi -case "x$enable_egl$enable_gallium_egl" in -xnoyes) - AC_MSG_ERROR([cannot build Gallium EGL state tracker without EGL]) -esac - -AC_ARG_WITH([state-trackers], - [AS_HELP_STRING([--with-state-trackers@<:@=DIRS...@:>@], - [comma delimited state_trackers list, e.g. - "egl,glx" @<:@default=auto@:>@])], - [with_state_trackers="$withval"], - [with_state_trackers=yes]) - -case "$with_state_trackers" in -no) - GALLIUM_STATE_TRACKERS_DIRS="" - ;; -yes) - # look at what else is built - case "$mesa_driver" in - xlib) - GALLIUM_STATE_TRACKERS_DIRS=glx - ;; - dri) - GALLIUM_STATE_TRACKERS_DIRS="dri" - HAVE_ST_DRI="yes" - # Have only tested st/xorg on 1.6.0 servers - PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0 libdrm >= $LIBDRM_XORG_REQUIRED libkms >= $LIBKMS_XORG_REQUIRED], - HAVE_ST_XORG="yes"; GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS xorg", - HAVE_ST_XORG="no") - ;; - esac - - if test "x$enable_egl" = xyes; then - if test "$enable_openvg" = yes; then - GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS vega" - st_egl="yes" - fi - - if test "$enable_gallium_egl" = yes; then - GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl" - HAVE_ST_EGL="yes" - fi - fi - ;; -*) - # verify the requested state tracker exist - state_trackers="" - _state_trackers=`IFS=', '; echo $with_state_trackers` - for tracker in $_state_trackers; do - case "$tracker" in - dri) - if test "x$mesa_driver" != xdri; then - AC_MSG_ERROR([cannot build dri state tracker without mesa driver set to dri]) - fi - HAVE_ST_DRI="yes" - ;; - egl) - if test "x$enable_egl" != xyes; then - AC_MSG_ERROR([cannot build egl state tracker without EGL library]) - fi - HAVE_ST_EGL="yes" - ;; - xorg) - PKG_CHECK_MODULES([XORG], [xorg-server >= 1.6.0]) - PKG_CHECK_MODULES([LIBDRM_XORG], [libdrm >= $LIBDRM_XORG_REQUIRED]) - PKG_CHECK_MODULES([LIBKMS_XORG], [libkms >= $LIBKMS_XORG_REQUIRED]) - HAVE_ST_XORG="yes" - ;; - vega) - if test "x$enable_openvg" != xyes; then - AC_MSG_ERROR([cannot build vega state tracker without --enable-openvg]) - fi - have_st_vega="yes" - ;; - xorg/xvmc) - # Check for xvmc? - if test "x$enable_gallium_g3dvl" != xyes; then - AC_MSG_ERROR([cannot build XvMC state tracker without --enable-gallium-g3dvl]) - fi - HAVE_ST_XVMC="yes" - ;; - vdpau) - # Check for libvdpau? - if test "x$enable_gallium_g3dvl" != xyes; then - AC_MSG_ERROR([cannot build vdpau state tracker without --enable-gallium-g3dvl]) - fi - HAVE_ST_VDPAU="yes" - ;; - va) - # Check for libva? - if test "x$enable_gallium_g3dvl" != xyes; then - AC_MSG_ERROR([cannot build va state tracker without --enable-gallium-g3dvl]) - fi - HAVE_ST_VA="yes" - ;; - esac - - if test -n "$tracker"; then - test -d "$srcdir/src/gallium/state_trackers/$tracker" || \ - AC_MSG_ERROR([state tracker '$tracker' doesn't exist]) - if test -n "$state_trackers"; then - state_trackers="$state_trackers $tracker" - else - state_trackers="$tracker" - fi - fi - done - GALLIUM_STATE_TRACKERS_DIRS="$state_trackers" - - # append --enable-openvg/--enable-gallium-egl to --with-state-trackers - if test "x$have_st_vega" != xyes -a "x$enable_openvg" = xyes; then - AC_MSG_ERROR([--with-state-trackers specified but vega is missing]) - fi - if test "x$HAVE_ST_EGL" != xyes -a "x$enable_gallium_egl" = xyes; then - AC_MSG_ERROR([--with-state-trackers specified but egl is missing]) - fi - ;; -esac - - -EGL_CLIENT_APIS="" -VG_LIB_DEPS="" - case "x$enable_opengl$enable_gles1$enable_gles2" in x*yes*) EGL_CLIENT_APIS="$EGL_CLIENT_APIS "'$(GL_LIB)' ;; esac -if test "x$enable_openvg" = xyes; then - EGL_CLIENT_APIS="$EGL_CLIENT_APIS "'$(VG_LIB)' - VG_LIB_DEPS="$VG_LIB_DEPS $SELINUX_LIBS -lpthread" -fi AC_SUBST([VG_LIB_DEPS]) AC_SUBST([EGL_CLIENT_APIS]) -if test "x$HAVE_ST_EGL" = xyes; then - GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS egl" -fi - -if test "x$HAVE_ST_XORG" = xyes; then - PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1], - HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71", - HAVE_XEXTPROTO_71="no") -fi - AC_ARG_WITH([egl-platforms], [AS_HELP_STRING([--with-egl-platforms@<:@=DIRS...@:>@], [comma delimited native platforms libEGL supports, e.g. "x11,drm" @<:@default=auto@:>@])], [with_egl_platforms="$withval"], [with_egl_platforms=yes]) -AC_ARG_WITH([egl-displays], - [AS_HELP_STRING([--with-egl-displays@<:@=DIRS...@:>@], - [DEPRECATED. Use --with-egl-platforms instead])], - [with_egl_platforms="$withval"]) EGL_PLATFORMS="" WAYLAND_EGL_LIB_DEPS="" case "$with_egl_platforms" in yes) - if test "x$enable_egl" = xyes && test "x$mesa_driver" != xosmesa; then + if test "x$enable_egl" = xyes; then EGL_PLATFORMS="x11" - if test "$mesa_driver" = dri; then - EGL_PLATFORMS="$EGL_PLATFORMS drm" - fi fi ;; *) @@ -1672,6 +1802,13 @@ yes) WAYLAND_EGL_LIB_DEPS="$WAYLAND_LIBS $LIBDRM_LIBS" GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/wayland" fi + if test "$plat" = "drm" && test "x$enable_gbm" = "xno"; then + AC_MSG_ERROR([EGL platform drm needs gbm]) + fi + case "$plat$have_libudev" in + waylandno|drmno) + AC_MSG_ERROR([cannot build $plat platfrom without udev]) ;; + esac done EGL_PLATFORMS="$egl_platforms" ;; @@ -1725,6 +1862,9 @@ AC_ARG_ENABLE([gallium-llvm], [build gallium LLVM support @<:@default=enabled on x86/x86_64@:>@])], [enable_gallium_llvm="$enableval"], [enable_gallium_llvm=auto]) +if test "x$with_gallium_drivers" = x; then + enable_gallium_llvm=no +fi if test "x$enable_gallium_llvm" = xauto; then case "$host_cpu" in i*86|x86_64) enable_gallium_llvm=yes;; @@ -1747,11 +1887,32 @@ else MESA_LLVM=0 fi +dnl Directory for VDPAU libs +AC_ARG_WITH([vdpau-libdir], + [AS_HELP_STRING([--with-vdpau-libdir=DIR], + [directory for the VDPAU libraries @<:@default=${libdir}/vdpau@:>@])], + [VDPAU_LIB_INSTALL_DIR="$withval"], + [VDPAU_LIB_INSTALL_DIR='${libdir}/vdpau']) +AC_SUBST([VDPAU_LIB_INSTALL_DIR]) + +dnl Directory for VA libs +AC_ARG_WITH([va-libdir], + [AS_HELP_STRING([--with-va-libdir=DIR], + [directory for the VA libraries @<:@default=${libdir}/va@:>@])], + [VA_LIB_INSTALL_DIR="$withval"], + [VA_LIB_INSTALL_DIR='${libdir}/va']) +AC_SUBST([VA_LIB_INSTALL_DIR]) + dnl dnl Gallium helper functions dnl gallium_check_st() { - if test "x$HAVE_ST_DRI" = xyes || test "x$HAVE_ST_XORG" = xyes || test "x$HAVE_ST_XVMC" = xyes || test "x$HAVE_ST_VDPAU" = xyes || test "x$HAVE_ST_VA" = xyes; then + if test "x$HAVE_ST_DRI" = xyes || test "x$HAVE_ST_XORG" = xyes || + test "x$HAVE_ST_XA" = xyes || test "x$HAVE_ST_XVMC" = xyes || + test "x$HAVE_ST_VDPAU" = xyes || test "x$HAVE_ST_VA" = xyes; then + if test "x$have_libdrm" != xyes; then + AC_MSG_ERROR([DRI or Xorg DDX requires libdrm >= $LIBDRM_REQUIRED]) + fi GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS $1" fi if test "x$HAVE_ST_DRI" = xyes && test "x$2" != x; then @@ -1760,175 +1921,77 @@ gallium_check_st() { if test "x$HAVE_ST_XORG" = xyes && test "x$3" != x; then GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $3" fi - if test "x$HAVE_ST_XVMC" = xyes && test "x$4" != x; then + if test "x$HAVE_ST_XA" = xyes && test "x$4" != x; then GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $4" fi - if test "x$HAVE_ST_VDPAU" = xyes && test "x$5" != x; then + if test "x$HAVE_ST_XVMC" = xyes && test "x$5" != x; then GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $5" fi - if test "x$HAVE_ST_VA" = xyes && test "x$6" != x; then + if test "x$HAVE_ST_VDPAU" = xyes && test "x$6" != x; then GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $6" fi -} - - -dnl -dnl Gallium SVGA configuration -dnl -AC_ARG_ENABLE([gallium-svga], - [AS_HELP_STRING([--enable-gallium-svga], - [build gallium SVGA @<:@default=disabled@:>@])], - [enable_gallium_svga="$enableval"], - [enable_gallium_svga=auto]) -if test "x$enable_gallium_svga" = xyes; then - GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS svga" - gallium_check_st "svga/drm" "dri-vmwgfx" "xorg-vmwgfx" -elif test "x$enable_gallium_svga" = xauto; then - GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS svga" -fi - -dnl -dnl Gallium i915 configuration -dnl -AC_ARG_ENABLE([gallium-i915], - [AS_HELP_STRING([--enable-gallium-i915], - [build gallium i915 @<:@default=disabled@:>@])], - [enable_gallium_i915="$enableval"], - [enable_gallium_i915=auto]) -if test "x$enable_gallium_i915" = xyes; then - GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS i915/sw" - GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915" - gallium_check_st "i915/drm" "dri-i915" "xorg-i915" -elif test "x$enable_gallium_i915" = xauto; then - GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS i915/sw" - GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915" -fi - -dnl -dnl Gallium i965 configuration -dnl -AC_ARG_ENABLE([gallium-i965], - [AS_HELP_STRING([--enable-gallium-i965], - [build gallium i965 @<:@default=disabled@:>@])], - [enable_gallium_i965="$enableval"], - [enable_gallium_i965=auto]) -if test "x$enable_gallium_i965" = xyes; then - GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i965" - gallium_check_st "i965/drm" "dri-i965" "xorg-i965" -elif test "x$enable_gallium_i965" = xauto; then - GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i965" -fi - -dnl -dnl Gallium Radeon r300g configuration -dnl -AC_ARG_ENABLE([gallium-r300], - [AS_HELP_STRING([--enable-gallium-r300], - [build gallium r300 @<:@default=build DRI driver only@:>@])], - [enable_gallium_r300="$enableval"], - [enable_gallium_r300=auto]) - -if test "$mesa_driver" != dri ; then - if test "x$enable_gallium_r300" = xauto; then - enable_gallium_r300=no + if test "x$HAVE_ST_VA" = xyes && test "x$7" != x; then + GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $7" fi -fi +} -if test "x$enable_gallium_r300" != xno; then +gallium_require_llvm() { if test "x$MESA_LLVM" = x0; then case "$host_cpu" in - i*86|x86_64) AC_MSG_ERROR([LLVM is required to build Gallium R300 on x86 and x86_64]);; + i*86|x86_64) AC_MSG_ERROR([LLVM is required to build $1 on x86 and x86_64]);; esac fi -fi -if test "x$enable_gallium_r300" = xauto; then - GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r300" - gallium_check_st "radeon/drm" "dri-r300" -elif test "x$enable_gallium_r300" = xyes; then - GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r300" - gallium_check_st "radeon/drm" "dri-r300" "xorg-radeon" "xvmc-r300" "vdpau-r300" "va-r300" -fi - -dnl -dnl Gallium Radeon r600g configuration -dnl -AC_ARG_ENABLE([gallium-r600], - [AS_HELP_STRING([--enable-gallium-r600], - [build gallium r600 @<:@default=disabled@:>@])], - [enable_gallium_r600="$enableval"], - [enable_gallium_r600=auto]) -if test "x$enable_gallium_r600" = xyes; then - GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r600" - gallium_check_st "r600/drm" "dri-r600" "" "xvmc-r600" "vdpau-r600" "va-r600" -fi - -dnl -dnl Gallium Nouveau configuration -dnl -AC_ARG_ENABLE([gallium-nouveau], - [AS_HELP_STRING([--enable-gallium-nouveau], - [build gallium nouveau @<:@default=disabled@:>@])], - [enable_gallium_nouveau="$enableval"], - [enable_gallium_nouveau=no]) -if test "x$enable_gallium_nouveau" = xyes; then - GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nvfx nv50 nvc0" - gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau" "xvmc-nouveau" -fi - -dnl -dnl Gallium G3DVL configuration -dnl -AC_ARG_ENABLE([gallium-g3dvl], - [AS_HELP_STRING([--enable-gallium-g3dvl], - [build gallium g3dvl @<:@default=disabled@:>@])], - [enable_gallium_g3dvl="$enableval"], - [enable_gallium_g3dvl=no]) -if test "x$enable_gallium_g3dvl" = xyes; then - case "$mesa_driver" in - xlib) - if test "x$HAVE_ST_VDPAU" = xyes; then - GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS vdpau-softpipe" - fi - if test "x$HAVE_ST_XVMC" = xyes; then - GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS xvmc-softpipe" - fi - if test "x$HAVE_ST_VA" = xyes; then - GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS va-softpipe" - fi - ;; - dri) - GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS g3dvl/dri" - ;; - esac -fi -dnl Directory for VDPAU libs -AC_ARG_WITH([vdpau-libdir], - [AS_HELP_STRING([--with-vdpau-libdir=DIR], - [directory for the VDPAU libraries @<:@default=${libdir}/vdpau@:>@])], - [VDPAU_LIB_INSTALL_DIR="$withval"], - [VDPAU_LIB_INSTALL_DIR='${libdir}/vdpau']) -AC_SUBST([VDPAU_LIB_INSTALL_DIR]) +} -dnl Directory for VA libs -AC_ARG_WITH([va-libdir], - [AS_HELP_STRING([--with-va-libdir=DIR], - [directory for the VA libraries @<:@default=${libdir}/va@:>@])], - [VA_LIB_INSTALL_DIR="$withval"], - [VA_LIB_INSTALL_DIR='${libdir}/va']) -AC_SUBST([VA_LIB_INSTALL_DIR]) +dnl Gallium drivers +if test "x$with_gallium_drivers" != x; then + # This is for compile-testing + GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915 i965 r300 svga" + GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS i915/sw" -dnl -dnl Gallium swrast configuration -dnl -AC_ARG_ENABLE([gallium-swrast], - [AS_HELP_STRING([--enable-gallium-swrast], - [build gallium swrast @<:@default=auto@:>@])], - [enable_gallium_swrast="$enableval"], - [enable_gallium_swrast=auto]) -if test "x$enable_gallium_swrast" = xyes || test "x$enable_gallium_swrast" = xauto; then - if test "x$HAVE_ST_DRI" = xyes; then - GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS dri-swrast" - fi + gallium_drivers=`IFS=', '; echo $with_gallium_drivers` + for driver in $gallium_drivers; do + case "x$driver" in + xsvga) + gallium_check_st "svga/drm" "dri-vmwgfx" "xorg-vmwgfx" "xa-vmwgfx" + ;; + xi915) + gallium_check_st "i915/drm" "dri-i915" "xorg-i915" + ;; + xi965) + gallium_check_st "i965/drm" "dri-i965" "xorg-i965" + ;; + xr300) + gallium_require_llvm "Gallium R300" + gallium_check_st "radeon/drm" "dri-r300" "xorg-radeon" "" "xvmc-r300" "vdpau-r300" "va-r300" + ;; + xr600) + GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r600" + gallium_check_st "r600/drm" "dri-r600" "" "" "xvmc-r600" "vdpau-r600" "va-r600" + ;; + xnouveau) + GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nvfx nv50 nvc0" + gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau" "" "xvmc-nouveau" + ;; + xswrast) + if test "x$HAVE_ST_DRI" = xyes; then + GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS dri-swrast" + fi + if test "x$HAVE_ST_VDPAU" = xyes; then + GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS vdpau-softpipe" + fi + if test "x$HAVE_ST_XVMC" = xyes; then + GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS xvmc-softpipe" + fi + if test "x$HAVE_ST_VA" = xyes; then + GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS va-softpipe" + fi + ;; + *) + AC_MSG_ERROR([Unknown Gallium driver: $driver]) + ;; + esac + done fi dnl prepend CORE_DIRS to SRC_DIRS @@ -1949,6 +2012,12 @@ fi ln -s autoconf configs/current ]) +dnl Sort the dirs alphabetically +GALLIUM_TARGET_DIRS=`echo $GALLIUM_TARGET_DIRS|tr " " "\n"|sort|tr "\n" " "` +GALLIUM_WINSYS_DIRS=`echo $GALLIUM_WINSYS_DIRS|tr " " "\n"|sort|tr "\n" " "` +GALLIUM_DRIVERS_DIRS=`echo $GALLIUM_DRIVERS_DIRS|tr " " "\n"|sort|tr "\n" " "` +GALLIUM_STATE_TRACKERS_DIRS=`echo $GALLIUM_STATE_TRACKERS_DIRS|tr " " "\n"|sort|tr "\n" " "` + AC_OUTPUT dnl @@ -1967,14 +2036,13 @@ echo " OpenVG: $enable_openvg" dnl Driver info echo "" -echo " Driver: $mesa_driver" -if test "$mesa_driver" != no; then - if echo "$DRIVER_DIRS" | grep 'osmesa' >/dev/null 2>&1; then +if test "x$enable_osmesa" != xno; then echo " OSMesa: lib$OSMESA_LIB" - else +else echo " OSMesa: no" - fi - if test "$mesa_driver" = dri; then +fi + +if test "x$enable_dri" != xno; then # cleanup the drivers var dri_dirs=`echo $DRI_DIRS | $SED 's/^ *//;s/ */ /;s/ *$//'` if test "x$DRI_DIRS" = x; then @@ -1983,10 +2051,22 @@ if test "$mesa_driver" != no; then echo " DRI drivers: $dri_dirs" fi echo " DRI driver dir: $DRI_DRIVER_INSTALL_DIR" - echo " Use XCB: $enable_xcb" echo " Shared dricore: $enable_dricore" - fi fi + +case "x$enable_glx$enable_xlib_glx" in +xyesyes) + echo " GLX: Xlib-based" + ;; +xyesno) + echo " GLX: DRI-based" + echo " Use XCB: $enable_xcb" + ;; +*) + echo " GLX: $enable_glx" + ;; +esac + echo "" echo " GLU: $enable_glu" echo " GLw: $enable_glw (Motif: $enable_motif)" @@ -2003,7 +2083,7 @@ if test "$enable_egl" = yes; then egl_drivers="$egl_drivers builtin:egl_$d" done - if test "$enable_gallium" = yes -a "$HAVE_ST_EGL" = yes; then + if test "x$HAVE_ST_EGL" = xyes; then echo " EGL drivers: ${egl_drivers} egl_gallium" echo " EGL Gallium STs:$EGL_CLIENT_APIS" else diff --git a/docs/GL3.txt b/docs/GL3.txt index d86c4b0bf60..49b48472a4a 100644 --- a/docs/GL3.txt +++ b/docs/GL3.txt @@ -40,7 +40,7 @@ glTexParameterI, glGetTexParameterI commands DONE glVertexAttribI commands DONE (but converts int values to floats) Depth format cube textures 0% done - +GLX_ARB_create_context (GLX 1.4 is required) not started GL 3.1: @@ -49,7 +49,7 @@ GLSL 1.40 not started Instanced drawing (GL_ARB_draw_instanced) DONE (gallium, swrast) Buffer copying (GL_ARB_copy_buffer) DONE Primitive restart (GL_NV_primitive_restart) DONE (gallium) -16 vertex texture image units not started +16 vertex texture image units DONE Texture buffer objs (GL_ARB_texture_buffer_object) not started Rectangular textures (GL_ARB_texture_rectangle) DONE Uniform buffer objs (GL_ARB_uniform_buffer_object) not started @@ -69,6 +69,7 @@ Seamless cubemaps (GL_ARB_seamless_cube_map) DONE Multisample textures (GL_ARB_texture_multisample) not started Frag depth clamp (GL_ARB_depth_clamp) DONE Fence objects (GL_ARB_sync) DONE +GLX_ARB_create_context_profile not started GL 3.3: diff --git a/docs/egl.html b/docs/egl.html index fb15086679f..5b750070ca1 100644 --- a/docs/egl.html +++ b/docs/egl.html @@ -29,12 +29,14 @@ directly dispatched to the drivers.</p> the driver for your hardware. For example</p> <pre> - $ ./configure --enable-gles2 --enable-openvg --enable-gallium-nouveau + $ ./configure --enable-gles1 --enable-gles2 \ + --with-dri-drivers=... \ + --with-gallium-drivers=... </pre> -<p>The main library and OpenGL is enabled by default. The first option above -enables <a href="opengles.html">OpenGL ES 2.x</a>. The second option enables -<a href="openvg.html">OpenVG</a>.</p> +<p>The main library and OpenGL is enabled by default. The first two options +above enables <a href="opengles.html">OpenGL ES 1.x and 2.x</a>. The last two +options enables the listed classic and and Gallium drivers respectively.</p> </li> @@ -42,8 +44,8 @@ enables <a href="opengles.html">OpenGL ES 2.x</a>. The second option enables </ol> <p>In the given example, it will build and install <code>libEGL</code>, -<code>libGL</code>, <code>libGLESv1_CM</code>, <code>libGLESv2</code>, -<code>libOpenVG</code>, and one or more EGL drivers.</p> +<code>libGL</code>, <code>libGLESv1_CM</code>, <code>libGLESv2</code>, and one +or more EGL drivers.</p> <h3>Configure Options</h3> @@ -65,6 +67,12 @@ drivers will be installed to <code>${libdir}/egl</code>.</p> </li> +<li><code>--enable-gallium-egl</code> + +<p>Enable the optional <code>egl_gallium</code> driver.</p> + +</li> + <li><code>--with-egl-platforms</code> <p>List the platforms (window systems) to support. Its argument is a comma @@ -88,15 +96,17 @@ internal library that supports multiple APIs.</p> </li> -<li><code>--enable-openvg</code> +<li><code>--enable-shared-glapi</code> -<p>OpenVG must be explicitly enabled by this option.</p> +<p>By default, <code>libGL</code> has its own copy of <code>libglapi</code>. +This options makes <code>libGL</code> use the shared <code>libglapi</code>. This +is required if applications mix OpenGL and OpenGL ES.</p> </li> -<li><code>--enable-gallium-egl</code> +<li><code>--enable-openvg</code> -<p>Explicitly enable or disable <code>egl_gallium</code>.</p> +<p>OpenVG must be explicitly enabled by this option.</p> </li> @@ -220,8 +230,7 @@ distribution.</p> <p>Generally, <code>egl_dri2</code> is preferred over <code>egl_gallium</code> when the system already has DRI drivers. As <code>egl_gallium</code> is loaded before <code>egl_dri2</code> when both are available, <code>egl_gallium</code> -may either be disabled with <code>--disable-gallium-egl</code> or packaged -separately.</p> +is disabled by default.</p> <h2>Developers</h2> @@ -307,17 +316,5 @@ not be called with the sample display at the same time. If a driver has access to an <code>EGLDisplay</code> without going through the EGL APIs, the driver should as well lock the display before using it. -<h3>TODOs</h3> - -<ul> -<li>Pass the conformance tests</li> -<li>Mixed use of OpenGL, OpenGL ES 1.1, and OpenGL ES 2.0 is supported. But -which one of <code>libGL.so</code>, <code>libGLESv1_CM.so</code>, and -<code>libGLESv2.so</code> should an application link to? Bad things may happen -when, say, an application is linked to <code>libGLESv2.so</code> and -<code>libcairo</code>, which is linked to <code>libGL.so</code> instead.</li> - -</ul> - </body> </html> diff --git a/docs/news.html b/docs/news.html index a6a658aefaf..eea6cd609e9 100644 --- a/docs/news.html +++ b/docs/news.html @@ -11,11 +11,18 @@ <H1>News</H1> +<h2>June 13, 2011</h2> + +<p> +<a href="relnotes-7.10.3.html">Mesa 7.10.3</a> is released. This is a bug +fix release. +</p> + <h2>April 6, 2011</h2> <p> <a href="relnotes-7.10.2.html">Mesa 7.10.2</a> is released. This is a bug -fix release release. +fix release. </p> <h2>March 2, 2011</h2> diff --git a/docs/opengles.html b/docs/opengles.html index 742182e76a3..0fee488e1a1 100644 --- a/docs/opengles.html +++ b/docs/opengles.html @@ -34,27 +34,10 @@ EGL drivers for your hardware.</p> <h2>Run the Demos</h2> -<p>There are some demos in <code>progs/egl/</code>. You can use them to test -your build. For example,</p> - -<pre> - $ cd progs/egl/eglut - $ make - $ cd ../opengles1 - $ make - $ ./torus_x11 -</pre> +<p>There are some demos in <code>mesa/demos</code> repository.</p> <h2>Developers</h2> -<h3>Internal Libraries</h3> - -<table border="1" style="text-align: center;"> - <tr><td>Library Name</td><td>Used By</td><td>Enabled</td><td>OpenGL</td><td>OpenGL ES 1.x</td><td>OpenGL ES 2.x</td></tr> - <tr><td><code>libmesa.a</td><td>Classic DRI drivers</td><td>y</td><td>y</td><td>--enable-gles1</td><td>--enable-gles2</td></tr> - <tr><td><code>libmesagallium.a</td><td>Gallium EGL and DRI drivers</td><td>y</td><td>y</td><td>--enable-gles1</td><td>--enable-gles2</td></tr> -</table> - <h3>Dispatch Table</h3> <p>OpenGL ES has an additional indirection when dispatching fucntions</p> diff --git a/docs/openvg.html b/docs/openvg.html index eff8c5828e2..81e50b65f36 100644 --- a/docs/openvg.html +++ b/docs/openvg.html @@ -11,7 +11,7 @@ <H1>OpenVG State Tracker</H1> <p> -The current version of the OpenVG state tracker implements OpenVG 1.0. +The current version of the OpenVG state tracker implements OpenVG 1.1. </p> <p> More informations about OpenVG can be found at @@ -26,9 +26,9 @@ Please refer to <a href="egl.html">Mesa EGL</a> for more information about EGL. <h2>Building the library</h2> <ol> -<li>Run <code>configure</code> with <code>--enable-openvg</code>. If you do -not need OpenGL, you can add <code>--disable-opengl</code> to save the -compilation time.</li> +<li>Run <code>configure</code> with <code>--enable-openvg</code> and +<code>--enable-gallium-egl</code>. If you do not need OpenGL, you can add +<code>--disable-opengl</code> to save the compilation time.</li> <li>Build and install Mesa as usual.</li> </ol> @@ -36,7 +36,7 @@ compilation time.</li> <h3>Sample build</h3> A sample build looks as follows: <pre> - $ ./configure --disable-opengl --enable-openvg + $ ./configure --disable-opengl --enable-openvg --enable-gallium-egl $ make $ make install </pre> diff --git a/docs/relnotes-7.10.3.html b/docs/relnotes-7.10.3.html new file mode 100644 index 00000000000..9ac5ef28e16 --- /dev/null +++ b/docs/relnotes-7.10.3.html @@ -0,0 +1,303 @@ +<HTML> + +<head> +<TITLE>Mesa Release Notes</TITLE> +<link rel="stylesheet" type="text/css" href="mesa.css"> +<meta http-equiv="content-type" content="text/html; charset=utf-8" /> +</head> + +<BODY> + +<body bgcolor="#eeeeee"> + +<H1>Mesa 7.10.3 Release Notes / June 13, 2011</H1> + +<p> +Mesa 7.10.3 is a bug fix release which fixes bugs found since the 7.10.2 release. +</p> +<p> +Mesa 7.10.3 implements the OpenGL 2.1 API, but the version reported by +glGetString(GL_VERSION) depends on the particular driver being used. +Some drivers don't support all the features required in OpenGL 2.1. +</p> +<p> +See the <a href="install.html">Compiling/Installing page</a> for prerequisites +for DRI hardware acceleration. +</p> + + +<h2>MD5 checksums</h2> +<pre> +d77b02034c11d6c2a55c07f82367d780 MesaLib-7.10.3.tar.gz +8c38fe8266be8e1ed1d84076ba5a703b MesaLib-7.10.3.tar.bz2 +614d063ecd170940d9ae7b355d365d59 MesaLib-7.10.3.zip +8768fd562ede7ed763d92b2d22232d7a MesaGLUT-7.10.3.tar.gz +1496415b89da9549f0f3b34d9622e2e2 MesaGLUT-7.10.3.tar.bz2 +1f29d0e7398fd3bf9f36f5db02941198 MesaGLUT-7.10.3.zip +</pre> + + +<h2>New features</h2> +<p>None.</p> + + +<h2>Bug fixes</h2> +<p>This list is likely incomplete.</p> +<ul> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=29162">Bug 29162</a> - mesa/darwin is severly broken</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=31590">Bug 31590</a> - Black space between colors on mole hill example</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32395">Bug 32395</a> - [glsl] Incorrect code generation for shadow2DProj() with bias</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32564">Bug 32564</a> - [llvmpipe] prog: Unknown command line argument '-disable-mmx'. Try: 'prog -help' with llvm-2.9svn</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32835">Bug 32835</a> - [glsl] recursive #define results in infinite stack recursion</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33303">Bug 33303</a> - [glsl] ir_constant_expression.cpp:72: virtual ir_constant* ir_expression::constant_expression_value(): Assertion `op[0]->type->base_type == op[1]->type->base_type' failed.</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33314">Bug 33314</a> - [glsl] ir_constant_expression.cpp:122: virtual ir_constant* ir_expression::constant_expression_value(): Assertion `op[0]->type->base_type == GLSL_TYPE_BOOL' failed.</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33512">Bug 33512</a> - [SNB] case ogles2conform/GL/gl_FragCoord/gl_FragCoord_xy_frag.test and gl_FragCoord_w_frag.test fail</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=34280">Bug 34280</a> - r200 mesa-7.10 font distortion</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=34321">Bug 34321</a> - The ARB_fragment_program subset of ARB_draw_buffers not implemented</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=35603">Bug 35603</a> - GLSL compiler freezes compiling shaders</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=36173">Bug 36173</a> - struct renderbuffer's 'format' field never set when using FBO</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=36238">Bug 36238</a> - Mesa release files don't contain scons control files</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=36410">Bug 36410</a> - [SNB] Rendering errors in 3DMMES subtest taiji</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=36527">Bug 36527</a> - [wine] Wolfenstein: Failed to translate rgb instruction.</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=36651">Bug 36651</a> - mesa requires bison and flex to build but configure does not check for them</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=36738">Bug 36738</a> - Openarena crash with r300g, swrastg + llvm > 2.8</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=37648">Bug 37648</a> - Logic error in mesa/main/teximage.c:texsubimage</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=37739">Bug 37739</a> - Color clear of FBO without color buffer crashes</li> + +<!-- <li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=">Bug </a> - </li> --> +</ul> + + +<h2>Changes</h2> +<p>The full set of changes can be viewed by using the following GIT command:</p> + +<pre> + git log mesa-7.10.2..mesa-7.10.3 +</pre> + +<p>Alan Hourihane (1): +<ul> + <li>Check for out of memory when creating fence</li> +</ul></p> + +<p>Alex Buell (1): +<ul> + <li>configure: bump LIBDRM_REQUIRED to 2.4.24</li> +</ul></p> + +<p>Alex Deucher (2): +<ul> + <li>r600c: add new pci ids</li> + <li>r600g: add new pci ids</li> +</ul></p> + +<p>Brian Paul (19): +<ul> + <li>docs: add link to 7.10.2 release notes</li> + <li>scons: remove dangling reference to state_trackers/python/SConscript</li> + <li>Makefile: add missing Scons files</li> + <li>llvmpipe: document issue with LLVM 2.8 and earlier with AVX</li> + <li>docs: replace llvmpipe/README with docs/llvmpipe.html</li> + <li>glsl: add static qualifier to silence warning</li> + <li>glsl: add cast to silence signed/unsigned comparison warning</li> + <li>mesa: s/height/depth/ in texsubimage()</li> + <li>mesa: fix void pointer arithmetic warnings</li> + <li>mesa: add some missing GLAPIENTRY keywords</li> + <li>mesa: check that flex/bison are installed</li> + <li>st/mesa: fix incorrect texture level/face/slice accesses</li> + <li>draw: fix edge flag handling in clipper (for unfilled tris/quads/polygons)</li> + <li>vbo: check array indexes to prevent negative indexing</li> + <li>vbo: remove node->count > 0 test in vbo_save_playback_vertex_list()</li> + <li>st/mesa: fix software accum buffer format bug</li> + <li>mesa: add include/c99/inttypes.h include/c99/stdbool.h include/c99/stdint.h files to tarballs</li> + <li>docs: 7.10.3 release notes skeleton file, links</li> + <li>mesa: bump version to 7.10.3</li> +</ul></p> + +<p>Carl Worth (2): +<ul> + <li>glcpp: Simplify calling convention of parser's active_list functions</li> + <li>glcpp: Fix attempts to expand recursive macros infinitely (bug #32835).</li> +</ul></p> + +<p>Dave Airlie (1): +<ul> + <li>st/mesa: fix compressed mipmap generation.</li> +</ul></p> + +<p>Eric Anholt (19): +<ul> + <li>i965: Fix the VS thread limits for GT1, and clarify the WM limits on both.</li> + <li>glsl: Avoid cascading errors when looking for a scalar boolean and failing.</li> + <li>glsl: Semantically check the RHS of `&&' even when short-circuiting.</li> + <li>glsl: Semantically check the RHS of `||' even when short-circuiting.</li> + <li>glsl: When we've emitted a semantic error for ==, return a bool constant.</li> + <li>glsl: Perform type checking on "^^" operands.</li> + <li>intel: Use _mesa_base_tex_format for FBO texture attachments.</li> + <li>swrast: Don't assert against glReadPixels of GL_RED and GL_RG.</li> + <li>mesa: Add a gl_renderbuffer.RowStride field like textures have.</li> + <li>mesa: Add a function to set up the default renderbuffer accessors.</li> + <li>intel: Use Mesa core's renderbuffer accessors for depth.</li> + <li>mesa: Use _mesa_get_format_bytes to refactor out the RB get_pointer_*</li> + <li>mesa: Use _mesa_get_format_bytes to refactor out the RB get_row_*</li> + <li>mesa: Add renderbuffer accessors for R8/RG88/R16/RG1616.</li> + <li>swrast: Don't try to adjust_colors for <8bpc when handling R16, RG1616.</li> + <li>intel: Use mesa core's R8, RG88, R16, RG1616 RB accessors.</li> + <li>Revert "intel: Add spans code for the ARB_texture_rg support."</li> + <li>mesa: Add support for the ARB_fragment_program part of ARB_draw_buffers.</li> + <li>mesa: Add support for OPTION ATI_draw_buffers to ARB_fp.</li> +</ul></p> + +<p>Hans de Goede (1): +<ul> + <li>texstore: fix regression stricter check for memcpy path for unorm88 and unorm1616</li> +</ul></p> + +<p>Henri Verbeet (3): +<ul> + <li>mesa: Also update the color draw buffer if it's explicitly set to GL_NONE.</li> + <li>glx: Destroy dri2Hash on DRI2 display destruction.</li> + <li>glx: Only remove the glx_display from the list after it's destroyed.</li> +</ul></p> + +<p>Ian Romanick (9): +<ul> + <li>docs: Add 7.10.2 md5sums</li> + <li>glsl: Fix off-by-one error setting max_array_access for non-constant indexing</li> + <li>ir_to_mesa: Handle shadow compare w/projection and LOD bias correctly</li> + <li>intel: Fix ROUND_DOWN_TO macro</li> + <li>glsl: Regenerate compiler and glcpp files from cherry picks</li> + <li>i965: Remove hint_gs_always and resulting dead code</li> + <li>mesa: Don't try to clear a NULL renderbuffer</li> + <li>mesa: Ignore blits to/from missing buffers</li> + <li>docs: Add list of bugs fixed in 7.10.3 release</li> +</ul></p> + +<p>Jeremy Huddleston (18): +<ul> + <li>apple: Update GL specs</li> + <li>apple: Rename glcontextmodes.[ch] to glxconfig.[ch]</li> + <li>apple: Rename __GLcontextModes to struct glx_config</li> + <li>apple: Rename GLXcontext</li> + <li>apple: Re-add driContext and do_destroy</li> + <li>apple: Rename _gl_context_modes_find_visual to glx_config_find_visual</li> + <li>apple: Rename GLXcontext</li> + <li>apple: Change from XExtDisplayInfo to struct glx_display</li> + <li>apple: ifdef out come glapi-foo on darwin</li> + <li>glx: Dead code removal</li> + <li>apple: Build darwin using applegl rather than indirect</li> + <li>apple: Fix build failures in applegl_glx.c</li> + <li>darwin: Define GALLIUM_DRIVERS_DIRS in darwin config</li> + <li>apple: Package applegl source into MesaLib tarball</li> + <li>darwin: Set VG_LIB_{NAME,GLOB} to fix make install</li> + <li>darwin: Don't link against libGL when building libOSMesa</li> + <li>darwin: Fix VG_LIB_GLOB to also match the unversioned symlink</li> + <li>osmesa: Fix missing symbols when GLX_INDIRECT_RENDERING is defined.</li> +</ul></p> + +<p>José Fonseca (13): +<ul> + <li>llvmpipe: Update readme.</li> + <li>mesa: GL_PROVOKING_VERTEX_EXT is a GLenum, not GLboolean.</li> + <li>mesa: Fix GetVertexAttrib* inside display lists.</li> + <li>draw: Fix draw_variant_output::format's type.</li> + <li>gallivm: Tell LLVM to not assume a 16-byte aligned stack on x86.</li> + <li>gallivm: Fix for dynamically linked LLVM 2.8 library.</li> + <li>st/wgl: Adjust the pbuffer invisible window size.</li> + <li>st/wgl: Fix debug output format specifiers of stw_framebuffer_get_size().</li> + <li>st/wgl: Prevent spurious framebuffer sizes when the window is minimized.</li> + <li>st/wgl: Cope with zero width/height windows.</li> + <li>st/wgl: Allow to create pbuffers bigger than the desktop.</li> + <li>st/wgl: Remove buggy assertion.</li> + <li>wgl: Don't hold on to user supplied HDC.</li> +</ul></p> + +<p>Kenneth Graunke (10): +<ul> + <li>i965/fs: Switch W and 1/W in Sandybridge interpolation setup.</li> + <li>i965: Refactor Sandybridge implied move handling.</li> + <li>i965: Resolve implied moves in brw_dp_READ_4_vs_relative.</li> + <li>intel: Add IS_GT2 macro for recognizing Sandybridge GT2 systems.</li> + <li>i965: Allocate the whole URB to the VS and fix calculations for Gen6.</li> + <li>intel: Support glCopyTexImage() from ARGB8888 to XRGB8888.</li> + <li>glsl: Fix memory error when creating the supported version string.</li> + <li>glsl: Regenerate autogenerated file builtin_function.cpp.</li> + <li>i965: Rename various gen6 #defines to match the documentation.</li> + <li>i965: Never enable the GS on Gen6.</li> +</ul></p> + +<p>Kostas Georgiou (1): +<ul> + <li>r600c/g: Add pci id for FirePro 2270</li> +</ul></p> + +<p>Marek Olšák (18): +<ul> + <li>tgsi/ureg: bump the limit of immediates</li> + <li>st/mesa: fix changing internal format via RenderbufferStorage</li> + <li>st/mesa: GenerateMipmap should not be killed by conditional rendering</li> + <li>swrast: BlitFramebuffer should not be killed by conditional rendering</li> + <li>st/mesa: BlitFramebuffer should not be killed by conditional rendering</li> + <li>st/mesa: CopyTex(Sub)Image should not be killed by conditional rendering</li> + <li>st/mesa: conditional rendering should not kill texture decompression via blit</li> + <li>mesa: forbid UseProgram to be called inside Begin/End</li> + <li>mesa: UseShaderProgramEXT and Uniform* shouldn't be allowed inside Begin/End</li> + <li>mesa: queries of non-existent FBO attachments should return INVALID_OPERATION</li> + <li>r300g: fix draw_vbo splitting on r3xx-r4xx</li> + <li>r300g: fix texturing with non-3D textures and wrap R mode set to sample border</li> + <li>r300g: fix occlusion queries when depth test is disabled or zbuffer is missing</li> + <li>r300g: clear can be killed by render condition</li> + <li>st/mesa: remove asserts in st_texture_image_copy</li> + <li>mesa: fix up assertion in _mesa_source_buffer_exists</li> + <li>mesa: invalidate framebuffer if internal format of renderbuffer is changed</li> + <li>mesa: return after invalidating renderbuffer</li> +</ul></p> + +<p>Matt Turner (1): +<ul> + <li>r300/compiler: align memory allocations to 8-bytes</li> +</ul></p> + +<p>Tom Stellard (3): +<ul> + <li>r300/compiler: Fix incorrect presubtract conversion</li> + <li>r300/compiler: Fix dataflow analysis bug with ELSE blocks</li> + <li>r300/compiler: Limit instructions to 3 source selects</li> +</ul></p> + +<p>Vinson Lee (1): +<ul> + <li>gallivm: Disable MMX-disabling code on llvm-2.9.</li> +</ul></p> + +<p>Zou Nan hai (1): +<ul> + <li>i965: Align interleaved URB write length to 2</li> +</ul></p> + +<p>pepp (1): +<ul> + <li>st/mesa: assign renderbuffer's format field when allocating storage</li> +</ul></p> + +</body> +</html> diff --git a/docs/relnotes-7.11.html b/docs/relnotes-7.11.html index aaeabc25288..c81ac9f15c9 100644 --- a/docs/relnotes-7.11.html +++ b/docs/relnotes-7.11.html @@ -45,7 +45,7 @@ tbd <li>GL_ARB_robustness (all drivers) <li>GL_ARB_sampler_objects (gallium drivers) <li>GL_ARB_seamless_cube_map (gallium r600) -<li>GL_ARB_shader_texture_lod (gallium drivers) +<li>GL_ARB_shader_texture_lod (gallium drivers, i965) <li>GL_ARB_sync (gallium drivers only, intel support was in 7.6) <li>GL_ARB_texture_compression_rgtc (gallium drivers, swrast, i965) <li>GL_ARB_texture_float (gallium, i965) diff --git a/docs/relnotes.html b/docs/relnotes.html index c1a7ab78dfd..e1f0c3299c0 100644 --- a/docs/relnotes.html +++ b/docs/relnotes.html @@ -14,6 +14,7 @@ The release notes summarize what's new or changed in each Mesa release. <UL> <LI><A HREF="relnotes-7.11.html">7.11 release notes</A> +<LI><A HREF="relnotes-7.10.3.html">7.10.3 release notes</A> <LI><A HREF="relnotes-7.10.2.html">7.10.2 release notes</A> <LI><A HREF="relnotes-7.10.1.html">7.10.1 release notes</A> <LI><A HREF="relnotes-7.10.html">7.10 release notes</A> diff --git a/include/EGL/eglplatform.h b/include/EGL/eglplatform.h index e4aa0994be9..fbfdce32ef4 100644 --- a/include/EGL/eglplatform.h +++ b/include/EGL/eglplatform.h @@ -84,6 +84,12 @@ typedef struct wl_display *EGLNativeDisplayType; typedef struct wl_egl_pixmap *EGLNativePixmapType; typedef struct wl_egl_window *EGLNativeWindowType; +#elif defined(__GBM__) + +typedef struct gbm_device *EGLNativeDisplayType; +typedef struct gbm_bo *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + #elif defined(__unix__) || defined(__unix) #ifdef MESA_EGL_NO_X11_HEADERS diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index f022b44b260..4fe9e943b55 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -849,6 +849,11 @@ struct __DRIimageExtensionRec { void *loaderPrivate); GLboolean (*queryImage)(__DRIimage *image, int attrib, int *value); + + /** + * The new __DRIimage will share the content with the old one, see dup(2). + */ + __DRIimage *(*dupImage)(__DRIimage *image, void *loaderPrivate); }; diff --git a/scons/custom.py b/scons/custom.py index a2c690f655e..df7ac93bb00 100644 --- a/scons/custom.py +++ b/scons/custom.py @@ -33,6 +33,8 @@ Custom builders and methods. import os import os.path import re +import sys +import subprocess import SCons.Action import SCons.Builder @@ -154,15 +156,90 @@ def createCodeGenerateMethod(env): env.AddMethod(code_generate, 'CodeGenerate') +def _pkg_check_modules(env, name, modules): + '''Simple wrapper for pkg-config.''' + + env['HAVE_' + name] = False + + # For backwards compatability + env[name.lower()] = False + + if env['platform'] == 'windows': + return + + if not env.Detect('pkg-config'): + return + + if subprocess.call(["pkg-config", "--exists", ' '.join(modules)]) != 0: + return + + # Other flags may affect the compilation of unrelated targets, so store + # them with a prefix, (e.g., XXX_CFLAGS, XXX_LIBS, etc) + try: + flags = env.ParseFlags('!pkg-config --cflags --libs ' + ' '.join(modules)) + except OSError: + return + prefix = name + '_' + for flag_name, flag_value in flags.iteritems(): + assert '_' not in flag_name + env[prefix + flag_name] = flag_value + + env['HAVE_' + name] = True + +def pkg_check_modules(env, name, modules): + + sys.stdout.write('Checking for %s...' % name) + _pkg_check_modules(env, name, modules) + result = env['HAVE_' + name] + sys.stdout.write(' %s\n' % ['no', 'yes'][int(bool(result))]) + + # XXX: For backwards compatability + env[name.lower()] = result + + +def pkg_use_modules(env, names): + '''Search for all environment flags that match NAME_FOO and append them to + the FOO environment variable.''' + + names = env.Flatten(names) + + for name in names: + prefix = name + '_' + + if not 'HAVE_' + name in env: + print 'Attempt to use unknown module %s' % name + env.Exit(1) + + if not env['HAVE_' + name]: + print 'Attempt to use unavailable module %s' % name + env.Exit(1) + + flags = {} + for flag_name, flag_value in env.Dictionary().iteritems(): + if flag_name.startswith(prefix): + flag_name = flag_name[len(prefix):] + if '_' not in flag_name: + flags[flag_name] = flag_value + if flags: + env.MergeFlags(flags) + + +def createPkgConfigMethods(env): + env.AddMethod(pkg_check_modules, 'PkgCheckModules') + env.AddMethod(pkg_use_modules, 'PkgUseModules') + + def generate(env): """Common environment generation code""" - if env.get('quiet', True): + verbose = env.get('verbose', False) or not env.get('quiet', True) + if not verbose: quietCommandLines(env) # Custom builders and methods createConvenienceLibBuilder(env) createCodeGenerateMethod(env) + createPkgConfigMethods(env) # for debugging #print env.Dump() diff --git a/scons/gallium.py b/scons/gallium.py index a94bf736480..8cd3bc7f6e0 100755 --- a/scons/gallium.py +++ b/scons/gallium.py @@ -104,41 +104,6 @@ def num_jobs(): return 1 -def pkg_config_modules(env, name, modules): - '''Simple wrapper for pkg-config.''' - - env[name] = False - - if env['platform'] == 'windows': - return - - if not env.Detect('pkg-config'): - return - - if subprocess.call(["pkg-config", "--exists", ' '.join(modules)]) != 0: - return - - # Put -I and -L flags directly into the environment, as these don't affect - # the compilation of targets that do not use them - try: - env.ParseConfig('pkg-config --cflags-only-I --libs-only-L ' + ' '.join(modules)) - except OSError: - return - - # Other flags may affect the compilation of unrelated targets, so store - # them with a prefix, (e.g., XXX_CFLAGS, XXX_LIBS, etc) - try: - flags = env.ParseFlags('!pkg-config --cflags-only-other --libs-only-l --libs-only-other ' + ' '.join(modules)) - except OSError: - return - prefix = name.upper() + '_' - for flag_name, flag_value in flags.iteritems(): - env[prefix + flag_name] = flag_value - - env[name] = True - - - def generate(env): """Common environment generation code""" @@ -247,6 +212,8 @@ def generate(env): # configuration. See also http://www.scons.org/wiki/AdvancedBuildExample build_topdir = 'build' build_subdir = env['platform'] + if env['embedded']: + build_subdir = 'embedded-' + build_subdir if env['machine'] != 'generic': build_subdir += '-' + env['machine'] if env['build'] != 'release': @@ -277,6 +244,31 @@ def generate(env): cppdefines += ['NDEBUG'] if env['build'] == 'profile': cppdefines += ['PROFILE'] + if env['platform'] in ('posix', 'linux', 'freebsd', 'darwin'): + cppdefines += [ + '_POSIX_SOURCE', + ('_POSIX_C_SOURCE', '199309L'), + '_SVID_SOURCE', + '_BSD_SOURCE', + '_GNU_SOURCE', + 'PTHREADS', + 'HAVE_POSIX_MEMALIGN', + ] + if env['platform'] == 'darwin': + cppdefines += [ + '_DARWIN_C_SOURCE', + 'GLX_USE_APPLEGL', + 'GLX_DIRECT_RENDERING', + ] + else: + cppdefines += [ + 'GLX_DIRECT_RENDERING', + 'GLX_INDIRECT_RENDERING', + ] + if env['platform'] in ('linux', 'freebsd'): + cppdefines += ['HAVE_ALIAS'] + else: + cppdefines += ['GLX_ALIAS_UNSUPPORTED'] if platform == 'windows': cppdefines += [ 'WIN32', @@ -349,8 +341,8 @@ def generate(env): if platform == 'wince': cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_CE'] cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_CE_OGL'] - if platform == 'embedded': - cppdefines += ['PIPE_OS_EMBEDDED'] + if env['embedded']: + cppdefines += ['PIPE_SUBSYSTEM_EMBEDDED'] env.Append(CPPDEFINES = cppdefines) # C compiler options @@ -367,6 +359,8 @@ def generate(env): ccflags += ['-O0'] else: ccflags += ['-O3'] + # Work around aliasing bugs - developers should comment this out + ccflags += ['-fno-strict-aliasing'] ccflags += ['-g3'] if env['build'] in ('checked', 'profile'): # See http://code.google.com/p/jrfonseca/wiki/Gprof2Dot#Which_options_should_I_pass_to_gcc_when_compiling_for_profiling? @@ -403,6 +397,8 @@ def generate(env): ccflags += ['-m64'] if platform == 'darwin': ccflags += ['-fno-common'] + if env['platform'] != 'windows': + ccflags += ['-fvisibility=hidden'] # See also: # - http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html ccflags += [ @@ -421,10 +417,10 @@ def generate(env): ] if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('4.2'): ccflags += [ - '-Werror=pointer-arith', + '-Wpointer-arith', ] cflags += [ - '-Werror=declaration-after-statement', + '-Wdeclaration-after-statement', ] if msvc: # See also: @@ -595,7 +591,10 @@ def generate(env): env['LINK'] = env['CXX'] # Default libs - env.Append(LIBS = []) + libs = [] + if env['platform'] in ('posix', 'linux', 'freebsd', 'darwin'): + libs += ['m', 'pthread', 'dl'] + env.Append(LIBS = libs) # Load tools env.Tool('lex') @@ -603,19 +602,21 @@ def generate(env): if env['llvm']: env.Tool('llvm') - pkg_config_modules(env, 'x11', ['x11', 'xext']) - pkg_config_modules(env, 'drm', ['libdrm']) - pkg_config_modules(env, 'drm_intel', ['libdrm_intel']) - pkg_config_modules(env, 'drm_radeon', ['libdrm_radeon']) - pkg_config_modules(env, 'xorg', ['xorg-server']) - pkg_config_modules(env, 'kms', ['libkms']) - - env['dri'] = env['x11'] and env['drm'] - # Custom builders and methods env.Tool('custom') createInstallMethods(env) + env.PkgCheckModules('X11', ['x11', 'xext', 'xdamage', 'xfixes']) + env.PkgCheckModules('XF86VIDMODE', ['xxf86vm']) + env.PkgCheckModules('DRM', ['libdrm']) + env.PkgCheckModules('DRM_INTEL', ['libdrm_intel']) + env.PkgCheckModules('DRM_RADEON', ['libdrm_radeon']) + env.PkgCheckModules('XORG', ['xorg-server']) + env.PkgCheckModules('KMS', ['libkms']) + env.PkgCheckModules('UDEV', ['libudev']) + + env['dri'] = env['x11'] and env['drm'] + # for debugging #print env.Dump() diff --git a/src/SConscript b/src/SConscript index 7b614daeea1..6d7bd6cd6ec 100644 --- a/src/SConscript +++ b/src/SConscript @@ -22,6 +22,7 @@ SConscript('mesa/SConscript') SConscript('mapi/vgapi/SConscript') if env['platform'] != 'embedded': + SConscript('glx/SConscript') SConscript('egl/main/SConscript') SConscript('glu/sgi/SConscript') SConscript('glut/glx/SConscript') diff --git a/src/egl/drivers/dri2/Makefile b/src/egl/drivers/dri2/Makefile index f8ff82b49c2..d2b1f4f077a 100644 --- a/src/egl/drivers/dri2/Makefile +++ b/src/egl/drivers/dri2/Makefile @@ -4,12 +4,14 @@ TOP = ../../../.. include $(TOP)/configs/current EGL_DRIVER = egl_dri2 -EGL_SOURCES = egl_dri2.c platform_drm.c common.c +EGL_SOURCES = egl_dri2.c common.c EGL_INCLUDES = \ -I$(TOP)/include \ -I$(TOP)/src/egl/main \ -I$(TOP)/src/mapi \ + -I$(TOP)/src/gbm/main \ + -I$(TOP)/src/gbm/backends/dri \ -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \ $(LIBUDEV_CFLAGS) \ $(LIBDRM_CFLAGS) @@ -29,6 +31,11 @@ EGL_INCLUDES += -DHAVE_X11_PLATFORM $(XCB_DRI2_CFLAGS) EGL_LIBS += $(XCB_DRI2_LIBS) endif +ifneq ($(findstring drm, $(EGL_PLATFORMS)),) +EGL_SOURCES += platform_drm.c +EGL_INCLUDES += -DHAVE_DRM_PLATFORM +endif + ifneq ($(findstring wayland, $(EGL_PLATFORMS)),) EGL_SOURCES += platform_wayland.c EGL_INCLUDES += -DHAVE_WAYLAND_PLATFORM $(WAYLAND_CFLAGS) \ diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index ea8c8fba8c0..5680c360f1d 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -97,6 +97,18 @@ EGLint dri2_to_egl_attribute_map[] = { 0, /* __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE */ }; +static EGLBoolean +dri2_match_config(const _EGLConfig *conf, const _EGLConfig *criteria) +{ + if (_eglCompareConfigs(conf, criteria, NULL, EGL_FALSE) != 0) + return EGL_FALSE; + + if (!_eglMatchConfig(conf, criteria)) + return EGL_FALSE; + + return EGL_TRUE; +} + struct dri2_egl_config * dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, int depth, EGLint surface_type, const EGLint *attr_list) @@ -190,7 +202,7 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, base.ConfigID = EGL_DONT_CARE; base.SurfaceType = EGL_DONT_CARE; num_configs = _eglFilterArray(disp->Configs, (void **) &matching_config, 1, - (_EGLArrayForEach) _eglMatchConfig, &base); + (_EGLArrayForEach) dri2_match_config, &base); if (num_configs == 1) { conf = (struct dri2_egl_config *) matching_config; @@ -232,7 +244,7 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, return conf; } -static __DRIimage * +__DRIimage * dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data) { _EGLDisplay *disp = data; @@ -322,8 +334,8 @@ dri2_bind_extensions(struct dri2_egl_display *dri2_dpy, return ret; } -EGLBoolean -dri2_load_driver(_EGLDisplay *disp) +static const __DRIextension ** +dri2_open_driver(_EGLDisplay *disp) { struct dri2_egl_display *dri2_dpy = disp->DriverData; const __DRIextension **extensions; @@ -362,9 +374,9 @@ dri2_load_driver(_EGLDisplay *disp) if (dri2_dpy->driver == NULL) { _eglLog(_EGL_WARNING, - "DRI2: failed to open any driver (search paths %s)", - search_paths); - return EGL_FALSE; + "DRI2: failed to open %s (search paths %s)", + dri2_dpy->driver_name, search_paths); + return NULL; } _eglLog(_EGL_DEBUG, "DRI2: dlopen(%s)", path); @@ -373,60 +385,60 @@ dri2_load_driver(_EGLDisplay *disp) _eglLog(_EGL_WARNING, "DRI2: driver exports no extensions (%s)", dlerror()); dlclose(dri2_dpy->driver); - return EGL_FALSE; } - if (strcmp(dri2_dpy->driver_name, "swrast") == 0) { - if (!dri2_bind_extensions(dri2_dpy, swrast_driver_extensions, extensions)) { - dlclose(dri2_dpy->driver); - return EGL_FALSE; - } - } else { - if (!dri2_bind_extensions(dri2_dpy, dri2_driver_extensions, extensions)) { - dlclose(dri2_dpy->driver); - return EGL_FALSE; - } - } + return extensions; +} + +EGLBoolean +dri2_load_driver(_EGLDisplay *disp) +{ + struct dri2_egl_display *dri2_dpy = disp->DriverData; + const __DRIextension **extensions; + + extensions = dri2_open_driver(disp); + if (!extensions) + return EGL_FALSE; + + if (!dri2_bind_extensions(dri2_dpy, dri2_driver_extensions, extensions)) { + dlclose(dri2_dpy->driver); + return EGL_FALSE; + } return EGL_TRUE; } EGLBoolean -dri2_create_screen(_EGLDisplay *disp) +dri2_load_driver_swrast(_EGLDisplay *disp) { + struct dri2_egl_display *dri2_dpy = disp->DriverData; const __DRIextension **extensions; - struct dri2_egl_display *dri2_dpy; - unsigned int api_mask; - dri2_dpy = disp->DriverData; - - if (dri2_dpy->dri2) { - dri2_dpy->dri_screen = - dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions, - &dri2_dpy->driver_configs, disp); - } else { - assert(dri2_dpy->swrast); - dri2_dpy->dri_screen = - dri2_dpy->swrast->createNewScreen(0, dri2_dpy->extensions, - &dri2_dpy->driver_configs, disp); + dri2_dpy->driver_name = "swrast"; + extensions = dri2_open_driver(disp); + if (!extensions) { + /* try again with swrastg */ + dri2_dpy->driver_name = "swrastg"; + extensions = dri2_open_driver(disp); } - if (dri2_dpy->dri_screen == NULL) { - _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen"); + if (!extensions) return EGL_FALSE; - } - extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen); - - if (dri2_dpy->dri2) { - if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions)) - goto cleanup_dri_screen; - } else { - assert(dri2_dpy->swrast); - if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions)) - goto cleanup_dri_screen; + if (!dri2_bind_extensions(dri2_dpy, swrast_driver_extensions, extensions)) { + dlclose(dri2_dpy->driver); + return EGL_FALSE; } + return EGL_TRUE; +} + +void +dri2_setup_screen(_EGLDisplay *disp) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + unsigned int api_mask; + if (dri2_dpy->dri2) { if (dri2_dpy->dri2->base.version >= 2) api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen); @@ -468,6 +480,46 @@ dri2_create_screen(_EGLDisplay *disp) disp->Extensions.KHR_image_base = EGL_TRUE; disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE; } +} + +EGLBoolean +dri2_create_screen(_EGLDisplay *disp) +{ + const __DRIextension **extensions; + struct dri2_egl_display *dri2_dpy; + + dri2_dpy = disp->DriverData; + + if (dri2_dpy->dri2) { + dri2_dpy->dri_screen = + dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions, + &dri2_dpy->driver_configs, disp); + } else { + assert(dri2_dpy->swrast); + dri2_dpy->dri_screen = + dri2_dpy->swrast->createNewScreen(0, dri2_dpy->extensions, + &dri2_dpy->driver_configs, disp); + } + + if (dri2_dpy->dri_screen == NULL) { + _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen"); + return EGL_FALSE; + } + + dri2_dpy->own_dri_screen = 1; + + extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen); + + if (dri2_dpy->dri2) { + if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions)) + goto cleanup_dri_screen; + } else { + assert(dri2_dpy->swrast); + if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions)) + goto cleanup_dri_screen; + } + + dri2_setup_screen(disp); return EGL_TRUE; @@ -496,10 +548,12 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp) #endif #ifdef HAVE_LIBUDEV +#ifdef HAVE_DRM_PLATFORM case _EGL_PLATFORM_DRM: if (disp->Options.TestOnly) return EGL_TRUE; return dri2_initialize_drm(drv, disp); +#endif #ifdef HAVE_WAYLAND_PLATFORM case _EGL_PLATFORM_WAYLAND: if (disp->Options.TestOnly) @@ -524,14 +578,30 @@ dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp) _eglReleaseDisplayResources(drv, disp); _eglCleanupDisplay(disp); - dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); + if (dri2_dpy->own_dri_screen) + dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); if (dri2_dpy->fd) close(dri2_dpy->fd); - dlclose(dri2_dpy->driver); + if (dri2_dpy->driver) + dlclose(dri2_dpy->driver); + + if (disp->PlatformDisplay == NULL) { + switch (disp->Platform) { #ifdef HAVE_X11_PLATFORM - if (disp->PlatformDisplay == NULL) - xcb_disconnect(dri2_dpy->conn); + case _EGL_PLATFORM_X11: + xcb_disconnect(dri2_dpy->conn); + break; +#endif +#ifdef HAVE_WAYLAND_PLATFORM + case _EGL_PLATFORM_WAYLAND: + wl_display_destroy(dri2_dpy->wl_dpy); + break; #endif + default: + break; + } + } + free(dri2_dpy); disp->DriverData = NULL; diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index 97f541b5e83..3854200bc69 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -44,6 +44,10 @@ #include <GL/gl.h> #include <GL/internal/dri_interface.h> +#ifdef HAVE_DRM_PLATFORM +#include <gbm_driint.h> +#endif + #include "eglconfig.h" #include "eglcontext.h" #include "egldisplay.h" @@ -69,6 +73,7 @@ struct dri2_egl_display int dri2_major; int dri2_minor; __DRIscreen *dri_screen; + int own_dri_screen; const __DRIconfig **driver_configs; void *driver; __DRIcoreExtension *core; @@ -79,12 +84,16 @@ struct dri2_egl_display __DRIimageExtension *image; int fd; +#ifdef HAVE_DRM_PLATFORM + struct gbm_dri_device *gbm_dri; +#endif + char *device_name; char *driver_name; __DRIdri2LoaderExtension dri2_loader_extension; __DRIswrastLoaderExtension swrast_loader_extension; - const __DRIextension *extensions[3]; + const __DRIextension *extensions[4]; #ifdef HAVE_X11_PLATFORM xcb_connection_t *conn; @@ -110,6 +119,7 @@ struct dri2_egl_context enum wayland_buffer_type { WL_BUFFER_FRONT, WL_BUFFER_BACK, + WL_BUFFER_THIRD, WL_BUFFER_COUNT }; @@ -145,9 +155,11 @@ struct dri2_egl_surface struct wl_egl_window *wl_win; struct wl_egl_pixmap *wl_pix; struct wl_buffer *wl_drm_buffer[WL_BUFFER_COUNT]; + int wl_buffer_lock[WL_BUFFER_COUNT]; int dx; int dy; __DRIbuffer *dri_buffers[__DRI_BUFFER_COUNT]; + __DRIbuffer *third_buffer; __DRIbuffer *pending_buffer; EGLBoolean block_swap_buffers; #endif @@ -182,9 +194,19 @@ extern const __DRIuseInvalidateExtension use_invalidate; EGLBoolean dri2_load_driver(_EGLDisplay *disp); +/* Helper for platforms not using dri2_create_screen */ +void +dri2_setup_screen(_EGLDisplay *disp); + +EGLBoolean +dri2_load_driver_swrast(_EGLDisplay *disp); + EGLBoolean dri2_create_screen(_EGLDisplay *disp); +__DRIimage * +dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data); + struct dri2_egl_config * dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, int depth, EGLint surface_type, const EGLint *attr_list); diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c index 27846de39d2..579baf9f9d2 100644 --- a/src/egl/drivers/dri2/platform_drm.c +++ b/src/egl/drivers/dri2/platform_drm.c @@ -33,6 +33,50 @@ #include "egl_dri2.h" +static _EGLImage * +dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, + EGLClientBuffer buffer, const EGLint *attr_list) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct gbm_dri_bo *dri_bo = gbm_dri_bo((struct gbm_bo *) buffer); + struct dri2_egl_image *dri2_img; + + dri2_img = malloc(sizeof *dri2_img); + if (!dri2_img) { + _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap"); + return NULL; + } + + if (!_eglInitImage(&dri2_img->base, disp)) { + free(dri2_img); + return NULL; + } + + dri2_img->dri_image = dri2_dpy->image->dupImage(dri_bo->image, dri2_img); + if (dri2_img->dri_image == NULL) { + free(dri2_img); + _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap"); + return NULL; + } + + return &dri2_img->base; +} + +static _EGLImage * +dri2_drm_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, + _EGLContext *ctx, EGLenum target, + EGLClientBuffer buffer, const EGLint *attr_list) +{ + (void) drv; + + switch (target) { + case EGL_NATIVE_PIXMAP_KHR: + return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list); + default: + return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list); + } +} + static int dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id) { @@ -45,57 +89,58 @@ EGLBoolean dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp) { struct dri2_egl_display *dri2_dpy; + struct gbm_device *gbm; int i; dri2_dpy = malloc(sizeof *dri2_dpy); if (!dri2_dpy) return _eglError(EGL_BAD_ALLOC, "eglInitialize"); - + memset(dri2_dpy, 0, sizeof *dri2_dpy); disp->DriverData = (void *) dri2_dpy; - dri2_dpy->fd = (int) (intptr_t) disp->PlatformDisplay; - dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd); - if (dri2_dpy->driver_name == NULL) - return _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name"); + gbm = (struct gbm_device *) disp->PlatformDisplay; + if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) { + free(dri2_dpy); + return EGL_FALSE; + } - dri2_dpy->device_name = dri2_get_device_name_for_fd(dri2_dpy->fd); - if (dri2_dpy->device_name == NULL) { - _eglError(EGL_BAD_ALLOC, "DRI2: failed to get device name"); - goto cleanup_driver_name; + dri2_dpy->gbm_dri = gbm_dri_device(gbm); + if (dri2_dpy->gbm_dri->base.type != GBM_DRM_DRIVER_TYPE_DRI) { + free(dri2_dpy); + return EGL_FALSE; } - if (!dri2_load_driver(disp)) - goto cleanup_device_name; + dri2_dpy->fd = gbm_device_get_fd(gbm); + dri2_dpy->device_name = dri2_get_device_name_for_fd(dri2_dpy->fd); + dri2_dpy->driver_name = dri2_dpy->gbm_dri->base.driver_name; + + dri2_dpy->dri_screen = dri2_dpy->gbm_dri->screen; + dri2_dpy->core = dri2_dpy->gbm_dri->core; + dri2_dpy->dri2 = dri2_dpy->gbm_dri->dri2; + dri2_dpy->image = dri2_dpy->gbm_dri->image; + dri2_dpy->driver_configs = dri2_dpy->gbm_dri->driver_configs; - dri2_dpy->extensions[0] = &image_lookup_extension.base; - dri2_dpy->extensions[1] = &use_invalidate.base; - dri2_dpy->extensions[2] = NULL; + dri2_dpy->gbm_dri->lookup_image = dri2_lookup_egl_image; + dri2_dpy->gbm_dri->lookup_user_data = disp; - if (!dri2_create_screen(disp)) - goto cleanup_driver; + dri2_setup_screen(disp); for (i = 0; dri2_dpy->driver_configs[i]; i++) - dri2_add_config(disp, dri2_dpy->driver_configs[i], i + 1, 0, 0, NULL); + dri2_add_config(disp, dri2_dpy->driver_configs[i], + i + 1, 0, 0, NULL); + + drv->API.CreateImageKHR = dri2_drm_create_image_khr; #ifdef HAVE_WAYLAND_PLATFORM disp->Extensions.WL_bind_wayland_display = EGL_TRUE; #endif dri2_dpy->authenticate = dri2_drm_authenticate; - + /* we're supporting EGL 1.4 */ disp->VersionMajor = 1; disp->VersionMinor = 4; return EGL_TRUE; - - cleanup_driver: - dlclose(dri2_dpy->driver); - cleanup_device_name: - free(dri2_dpy->device_name); - cleanup_driver_name: - free(dri2_dpy->driver_name); - - return EGL_FALSE; } diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index 1d6ce2ec49c..c4fa126951b 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -59,6 +59,29 @@ force_roundtrip(struct wl_display *display) wl_display_iterate(display, WL_DISPLAY_READABLE); } +static void +wl_buffer_release(void *data, struct wl_buffer *buffer) +{ + struct dri2_egl_surface *dri2_surf = data; + int i; + + for (i = 0; i < WL_BUFFER_COUNT; ++i) + if (dri2_surf->wl_drm_buffer[i] == buffer) + break; + + assert(i <= WL_BUFFER_COUNT); + + /* not found? */ + if (i == WL_BUFFER_COUNT) + return; + + dri2_surf->wl_buffer_lock[i] = 0; + +} + +static struct wl_buffer_listener wl_buffer_listener = { + wl_buffer_release +}; /** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). @@ -85,13 +108,16 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; - for (i = 0; i < WL_BUFFER_COUNT; ++i) + for (i = 0; i < WL_BUFFER_COUNT; ++i) { dri2_surf->wl_drm_buffer[i] = NULL; + dri2_surf->wl_buffer_lock[i] = 0; + } for (i = 0; i < __DRI_BUFFER_COUNT; ++i) dri2_surf->dri_buffers[i] = NULL; dri2_surf->pending_buffer = NULL; + dri2_surf->third_buffer = NULL; dri2_surf->block_swap_buffers = EGL_FALSE; switch (type) { @@ -187,6 +213,11 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, dri2_surf->dri_buffers[i]); + if (dri2_surf->third_buffer) { + dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, + dri2_surf->third_buffer); + } + free(surf); return EGL_TRUE; @@ -215,10 +246,14 @@ wayland_create_buffer(struct dri2_egl_surface *dri2_surf, { struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); + struct wl_buffer *buf; - return wl_drm_create_buffer(dri2_dpy->wl_drm, buffer->name, - dri2_surf->base.Width, dri2_surf->base.Height, - buffer->pitch, visual); + buf = wl_drm_create_buffer(dri2_dpy->wl_drm, buffer->name, + dri2_surf->base.Width, dri2_surf->base.Height, + buffer->pitch, visual); + wl_buffer_add_listener(buf, &wl_buffer_listener, dri2_surf); + + return buf; } static void @@ -232,6 +267,8 @@ dri2_process_back_buffer(struct dri2_egl_surface *dri2_surf, unsigned format) switch (dri2_surf->type) { case DRI2_WINDOW_SURFACE: /* allocate a front buffer for our double-buffered window*/ + if (dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] != NULL) + break; dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] = dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen, __DRI_BUFFER_FRONT_LEFT, format, @@ -289,6 +326,12 @@ dri2_release_buffers(struct dri2_egl_surface *dri2_surf) dri2_egl_display(dri2_surf->base.Resource.Display); int i; + if (dri2_surf->third_buffer) { + dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, + dri2_surf->third_buffer); + dri2_surf->third_buffer = NULL; + } + for (i = 0; i < __DRI_BUFFER_COUNT; ++i) { if (dri2_surf->dri_buffers[i]) { switch (i) { @@ -309,6 +352,76 @@ dri2_release_buffers(struct dri2_egl_surface *dri2_surf) } } +static inline void +pointer_swap(const void **p1, const void **p2) +{ + const void *tmp = *p1; + *p1 = *p2; + *p2 = tmp; +} + +static void +destroy_third_buffer(struct dri2_egl_surface *dri2_surf) +{ + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); + + if (dri2_surf->third_buffer == NULL) + return; + + dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, + dri2_surf->third_buffer); + dri2_surf->third_buffer = NULL; + + if (dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD]) + wl_buffer_destroy(dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD]); + dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD] = NULL; + dri2_surf->wl_buffer_lock[WL_BUFFER_THIRD] = 0; +} + +static void +swap_wl_buffers(struct dri2_egl_surface *dri2_surf, + enum wayland_buffer_type a, enum wayland_buffer_type b) +{ + int tmp; + + tmp = dri2_surf->wl_buffer_lock[a]; + dri2_surf->wl_buffer_lock[a] = dri2_surf->wl_buffer_lock[b]; + dri2_surf->wl_buffer_lock[b] = tmp; + + pointer_swap((const void **) &dri2_surf->wl_drm_buffer[a], + (const void **) &dri2_surf->wl_drm_buffer[b]); +} + +static void +swap_back_and_third(struct dri2_egl_surface *dri2_surf) +{ + if (dri2_surf->wl_buffer_lock[WL_BUFFER_THIRD]) + destroy_third_buffer(dri2_surf); + + pointer_swap((const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT], + (const void **) &dri2_surf->third_buffer); + + swap_wl_buffers(dri2_surf, WL_BUFFER_BACK, WL_BUFFER_THIRD); +} + +static void +dri2_prior_buffer_creation(struct dri2_egl_surface *dri2_surf, + unsigned int type) +{ + switch (type) { + case __DRI_BUFFER_BACK_LEFT: + if (dri2_surf->wl_buffer_lock[WL_BUFFER_BACK]) + swap_back_and_third(dri2_surf); + else if (dri2_surf->third_buffer) + destroy_third_buffer(dri2_surf); + break; + default: + break; + + } +} + static __DRIbuffer * dri2_get_buffers_with_format(__DRIdrawable * driDrawable, int *width, int *height, @@ -335,6 +448,7 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable, if (dri2_surf->wl_drm_buffer[i]) wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]); dri2_surf->wl_drm_buffer[i] = NULL; + dri2_surf->wl_buffer_lock[i] = 0; } } @@ -343,6 +457,8 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable, assert(attachments[i] < __DRI_BUFFER_COUNT); assert(dri2_surf->buffer_count < 5); + dri2_prior_buffer_creation(dri2_surf, attachments[i]); + if (dri2_surf->dri_buffers[attachments[i]] == NULL) { dri2_surf->dri_buffers[attachments[i]] = @@ -443,14 +559,6 @@ wayland_frame_callback(struct wl_surface *surface, void *data, uint32_t time) dri2_surf->block_swap_buffers = EGL_FALSE; } -static inline void -pointer_swap(const void **p1, const void **p2) -{ - const void *tmp = *p1; - *p1 = *p2; - *p2 = tmp; -} - /** * Called via eglSwapBuffers(), drv->API.SwapBuffers(). */ @@ -466,8 +574,8 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) dri2_surf->block_swap_buffers = EGL_TRUE; wl_display_frame_callback(dri2_dpy->wl_dpy, - dri2_surf->wl_win->surface, - wayland_frame_callback, dri2_surf); + dri2_surf->wl_win->surface, + wayland_frame_callback, dri2_surf); if (dri2_surf->type == DRI2_WINDOW_SURFACE) { pointer_swap( @@ -479,8 +587,7 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment = __DRI_BUFFER_BACK_LEFT; - pointer_swap((const void **) &dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT], - (const void **) &dri2_surf->wl_drm_buffer[WL_BUFFER_BACK]); + swap_wl_buffers(dri2_surf, WL_BUFFER_FRONT, WL_BUFFER_BACK); if (!dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT]) dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT] = @@ -493,6 +600,7 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) wl_surface_attach(dri2_surf->wl_win->surface, dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT], dri2_surf->dx, dri2_surf->dy); + dri2_surf->wl_buffer_lock[WL_BUFFER_FRONT] = 1; dri2_surf->wl_win->attached_width = dri2_surf->base.Width; dri2_surf->wl_win->attached_height = dri2_surf->base.Height; @@ -676,7 +784,13 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) memset(dri2_dpy, 0, sizeof *dri2_dpy); disp->DriverData = (void *) dri2_dpy; - dri2_dpy->wl_dpy = disp->PlatformDisplay; + if (disp->PlatformDisplay == NULL) { + dri2_dpy->wl_dpy = wl_display_connect(NULL); + if (dri2_dpy->wl_dpy == NULL) + goto cleanup_dpy; + } else { + dri2_dpy->wl_dpy = disp->PlatformDisplay; + } id = wl_display_get_global(dri2_dpy->wl_dpy, "wl_drm", 1); if (id == 0) @@ -714,7 +828,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base; dri2_dpy->extensions[1] = &image_lookup_extension.base; - dri2_dpy->extensions[2] = NULL; + dri2_dpy->extensions[2] = &use_invalidate.base; + dri2_dpy->extensions[3] = NULL; if (!dri2_create_screen(disp)) goto cleanup_driver; diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c index 2e26ff00b67..4e00c958cbd 100644 --- a/src/egl/drivers/dri2/platform_x11.c +++ b/src/egl/drivers/dri2/platform_x11.c @@ -479,10 +479,19 @@ dri2_connect(struct dri2_egl_display *dri2_dpy) xcb_generic_error_t *error; xcb_screen_iterator_t s; char *driver_name, *device_name; + const xcb_query_extension_reply_t *extension; xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_xfixes_id); xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri2_id); + extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_xfixes_id); + if (!(extension && extension->present)) + return EGL_FALSE; + + extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_dri2_id); + if (!(extension && extension->present)) + return EGL_FALSE; + xfixes_query_cookie = xcb_xfixes_query_version(dri2_dpy->conn, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION); @@ -906,9 +915,7 @@ dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp) goto cleanup_dpy; } - dri2_dpy->driver_name = dri2_strndup("swrast", strlen("swrast")); - - if (!dri2_load_driver(disp)) + if (!dri2_load_driver_swrast(disp)) goto cleanup_conn; dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER; diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index c3c11c7b6eb..7cf8f4d5514 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -1,8 +1,10 @@ /************************************************************************** - * + * * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. * 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 @@ -10,19 +12,19 @@ * 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * + * THE 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. + * **************************************************************************/ diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile index 6c4a392760f..775fbbe178b 100644 --- a/src/egl/main/Makefile +++ b/src/egl/main/Makefile @@ -61,9 +61,13 @@ LOCAL_LIBS += $(TOP)/src/egl/drivers/dri2/libegl_dri2.a ifneq ($(findstring x11, $(EGL_PLATFORMS)),) EGL_LIB_DEPS += $(XCB_DRI2_LIBS) endif +ifneq ($(findstring drm, $(EGL_PLATFORMS)),) +EGL_LIB_DEPS += -lgbm +endif EGL_LIB_DEPS += $(LIBUDEV_LIBS) $(DLOPEN_LIBS) $(LIBDRM_LIB) $(WAYLAND_LIBS) endif + ifneq ($(findstring wayland, $(EGL_PLATFORMS)),) LOCAL_LIBS += $(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a endif diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index bdfdcb3817d..0ba7794e2c9 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + /** * Public EGL API entrypoints * diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index c9913f10a10..4fcbe40cd4c 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLAPI_INCLUDED #define EGLAPI_INCLUDED diff --git a/src/egl/main/eglarray.c b/src/egl/main/eglarray.c index fe2f1a7f32f..3ccc8a649f0 100644 --- a/src/egl/main/eglarray.c +++ b/src/egl/main/eglarray.c @@ -1,3 +1,31 @@ +/************************************************************************** + * + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #include <stdlib.h> #include <string.h> diff --git a/src/egl/main/eglarray.h b/src/egl/main/eglarray.h index a88189a6252..d07f301f242 100644 --- a/src/egl/main/eglarray.h +++ b/src/egl/main/eglarray.h @@ -1,3 +1,31 @@ +/************************************************************************** + * + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLARRAY_INCLUDED #define EGLARRAY_INCLUDED diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h index 90c75e84b29..1bc8cc89fa4 100644 --- a/src/egl/main/eglcompiler.h +++ b/src/egl/main/eglcompiler.h @@ -1,3 +1,32 @@ +/************************************************************************** + * + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLCOMPILER_INCLUDED #define EGLCOMPILER_INCLUDED diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c index 5b377b7f610..483d9807cf0 100644 --- a/src/egl/main/eglconfig.c +++ b/src/egl/main/eglconfig.c @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + /** * EGL Configuration (pixel format) functions. */ @@ -305,6 +335,7 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) break; default: assert(0); + mask = 0; break; } if (val & ~mask) @@ -456,8 +487,6 @@ _eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr) return EGL_FALSE; switch (attr) { - case EGL_MATCH_NATIVE_PIXMAP: - return EGL_FALSE; case EGL_Y_INVERTED_NOK: return conf->Display->Extensions.NOK_texture_from_pixmap; default: @@ -634,7 +663,7 @@ void _eglSwapConfigs(const _EGLConfig **conf1, const _EGLConfig **conf2) * qsort() in that the compare function accepts an additional * argument. */ -void +static void _eglSortConfigs(const _EGLConfig **configs, EGLint count, EGLint (*compare)(const _EGLConfig *, const _EGLConfig *, void *), @@ -672,34 +701,27 @@ _eglSortConfigs(const _EGLConfig **configs, EGLint count, } -static int -_eglFallbackCompare(const _EGLConfig *conf1, const _EGLConfig *conf2, - void *priv_data) -{ - const _EGLConfig *criteria = (const _EGLConfig *) priv_data; - return _eglCompareConfigs(conf1, conf2, criteria, EGL_TRUE); -} - - /** - * Typical fallback routine for eglChooseConfig + * A helper function for implementing eglChooseConfig. See _eglFilterArray and + * _eglSortConfigs for the meanings of match and compare. */ EGLBoolean -_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list, - EGLConfig *configs, EGLint config_size, EGLint *num_configs) +_eglFilterConfigArray(_EGLArray *array, EGLConfig *configs, + EGLint config_size, EGLint *num_configs, + EGLBoolean (*match)(const _EGLConfig *, void *), + EGLint (*compare)(const _EGLConfig *, const _EGLConfig *, + void *), + void *priv_data) { - _EGLConfig **configList, criteria; + _EGLConfig **configList; EGLint i, count; if (!num_configs) return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs"); - if (!_eglParseConfigAttribList(&criteria, disp, attrib_list)) - return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig"); - /* get the number of matched configs */ - count = _eglFilterArray(disp->Configs, NULL, 0, - (_EGLArrayForEach) _eglMatchConfig, (void *) &criteria); + count = _eglFilterArray(array, NULL, 0, + (_EGLArrayForEach) match, priv_data); if (!count) { *num_configs = count; return EGL_TRUE; @@ -710,13 +732,13 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list, return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)"); /* get the matched configs */ - _eglFilterArray(disp->Configs, (void **) configList, count, - (_EGLArrayForEach) _eglMatchConfig, (void *) &criteria); + _eglFilterArray(array, (void **) configList, count, + (_EGLArrayForEach) match, priv_data); /* perform sorting of configs */ if (configs && count) { _eglSortConfigs((const _EGLConfig **) configList, count, - _eglFallbackCompare, (void *) &criteria); + compare, priv_data); count = MIN2(count, config_size); for (i = 0; i < count; i++) configs[i] = _eglGetConfigHandle(configList[i]); @@ -730,6 +752,41 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list, } +static EGLBoolean +_eglFallbackMatch(const _EGLConfig *conf, void *priv_data) +{ + return _eglMatchConfig(conf, (const _EGLConfig *) priv_data); +} + + +static EGLint +_eglFallbackCompare(const _EGLConfig *conf1, const _EGLConfig *conf2, + void *priv_data) +{ + return _eglCompareConfigs(conf1, conf2, + (const _EGLConfig *) priv_data, EGL_TRUE); +} + + +/** + * Typical fallback routine for eglChooseConfig + */ +EGLBoolean +_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list, + EGLConfig *configs, EGLint config_size, EGLint *num_configs) +{ + _EGLConfig criteria; + + if (!_eglParseConfigAttribList(&criteria, disp, attrib_list)) + return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig"); + + return _eglFilterConfigArray(disp->Configs, + configs, config_size, num_configs, + _eglFallbackMatch, _eglFallbackCompare, + (void *) &criteria); +} + + /** * Fallback for eglGetConfigAttrib. */ @@ -739,6 +796,16 @@ _eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, { if (!_eglIsConfigAttribValid(conf, attribute)) return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib"); + + /* nonqueryable attributes */ + switch (attribute) { + case EGL_MATCH_NATIVE_PIXMAP: + return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib"); + break; + default: + break; + } + if (!value) return _eglError(EGL_BAD_PARAMETER, "eglGetConfigAttrib"); diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h index 2169960fd1d..adab95cd6a3 100644 --- a/src/egl/main/eglconfig.h +++ b/src/egl/main/eglconfig.h @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLCONFIG_INCLUDED #define EGLCONFIG_INCLUDED @@ -172,11 +202,13 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2, const _EGLConfig *criteria, EGLBoolean compare_id); -PUBLIC void -_eglSortConfigs(const _EGLConfig **configs, EGLint count, - EGLint (*compare)(const _EGLConfig *, const _EGLConfig *, - void *), - void *priv_data); +PUBLIC EGLBoolean +_eglFilterConfigArray(_EGLArray *array, EGLConfig *configs, + EGLint config_size, EGLint *num_configs, + EGLBoolean (*match)(const _EGLConfig *, void *), + EGLint (*compare)(const _EGLConfig *, const _EGLConfig *, + void *), + void *filter_data); extern EGLBoolean diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index 33dcfa68756..38e195f0446 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #include <assert.h> #include <stdlib.h> #include <string.h> diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h index 8cd0df17313..0ac846219a7 100644 --- a/src/egl/main/eglcontext.h +++ b/src/egl/main/eglcontext.h @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLCONTEXT_INCLUDED #define EGLCONTEXT_INCLUDED diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c index 4221a9be3e1..54fc4f742e5 100644 --- a/src/egl/main/eglcurrent.c +++ b/src/egl/main/eglcurrent.c @@ -1,3 +1,31 @@ +/************************************************************************** + * + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * 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 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. + * + **************************************************************************/ + + #include <stdlib.h> #include <string.h> #include "egllog.h" diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h index e5c94ce60ab..a64821eb125 100644 --- a/src/egl/main/eglcurrent.h +++ b/src/egl/main/eglcurrent.h @@ -1,3 +1,31 @@ +/************************************************************************** + * + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * 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 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. + * + **************************************************************************/ + + #ifndef EGLCURRENT_INCLUDED #define EGLCURRENT_INCLUDED diff --git a/src/egl/main/egldefines.h b/src/egl/main/egldefines.h index 4ecd4c1420c..d468d7b76cc 100644 --- a/src/egl/main/egldefines.h +++ b/src/egl/main/egldefines.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2008 Tungsten Graphics, 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 @@ -10,23 +10,22 @@ * 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * + * THE 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. + * **************************************************************************/ - /** * Internal EGL defines */ diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index 30592947297..60f31777272 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + /** * Functions related to EGLDisplay. */ diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 97ae2b01ba0..9cd4dbfcc8a 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLDISPLAY_INCLUDED #define EGLDISPLAY_INCLUDED diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c index b75e8b6a2cb..ffdd1462846 100644 --- a/src/egl/main/egldriver.c +++ b/src/egl/main/egldriver.c @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + /** * Functions for choosing and opening/loading device drivers. */ diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h index 3cde102d12d..4bb9612765b 100644 --- a/src/egl/main/egldriver.h +++ b/src/egl/main/egldriver.h @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLDRIVER_INCLUDED #define EGLDRIVER_INCLUDED diff --git a/src/egl/main/eglfallbacks.c b/src/egl/main/eglfallbacks.c index 7c93adb76aa..b4f35d742ae 100644 --- a/src/egl/main/eglfallbacks.c +++ b/src/egl/main/eglfallbacks.c @@ -1,3 +1,31 @@ +/************************************************************************** + * + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #include <string.h> #include "egltypedefs.h" #include "egldriver.h" diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c index 52eebb07f6c..f53f078d710 100644 --- a/src/egl/main/eglglobals.c +++ b/src/egl/main/eglglobals.c @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #include <stdlib.h> #include <assert.h> #include "eglglobals.h" diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h index c3771a8ef10..b40e30e2251 100644 --- a/src/egl/main/eglglobals.h +++ b/src/egl/main/eglglobals.h @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLGLOBALS_INCLUDED #define EGLGLOBALS_INCLUDED diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c index 6d4ee4e08b9..458a2e424d3 100644 --- a/src/egl/main/eglimage.c +++ b/src/egl/main/eglimage.c @@ -1,3 +1,32 @@ +/************************************************************************** + * + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #include <assert.h> #include <string.h> diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h index adb939a9e02..acb36aaeb18 100644 --- a/src/egl/main/eglimage.h +++ b/src/egl/main/eglimage.h @@ -1,3 +1,32 @@ +/************************************************************************** + * + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLIMAGE_INCLUDED #define EGLIMAGE_INCLUDED diff --git a/src/egl/main/egllog.c b/src/egl/main/egllog.c index 12c55f901a5..43eed64c299 100644 --- a/src/egl/main/egllog.c +++ b/src/egl/main/egllog.c @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + /** * Logging facility for debug/info messages. * _EGL_FATAL messages are printed to stderr diff --git a/src/egl/main/egllog.h b/src/egl/main/egllog.h index 03bef2670f1..10a418447bd 100644 --- a/src/egl/main/egllog.h +++ b/src/egl/main/egllog.h @@ -1,3 +1,32 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * 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 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. + * + **************************************************************************/ + + #ifndef EGLLOG_INCLUDED #define EGLLOG_INCLUDED diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c index 6bb2498eef4..da189b689a3 100644 --- a/src/egl/main/eglmisc.c +++ b/src/egl/main/eglmisc.c @@ -1,8 +1,10 @@ /************************************************************************** - * + * * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. * 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 @@ -10,19 +12,19 @@ * 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * + * THE 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. + * **************************************************************************/ diff --git a/src/egl/main/eglmisc.h b/src/egl/main/eglmisc.h index a753307a14b..da0adbd0ee2 100644 --- a/src/egl/main/eglmisc.h +++ b/src/egl/main/eglmisc.h @@ -1,8 +1,10 @@ /************************************************************************** - * + * * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. * 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 @@ -10,19 +12,19 @@ * 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * + * THE 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. + * **************************************************************************/ diff --git a/src/egl/main/eglmode.c b/src/egl/main/eglmode.c index a9653496c32..617d4c2d60a 100644 --- a/src/egl/main/eglmode.c +++ b/src/egl/main/eglmode.c @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #include <assert.h> #include <stdlib.h> #include <string.h> diff --git a/src/egl/main/eglmode.h b/src/egl/main/eglmode.h index ed4eb2c34af..a423f026483 100644 --- a/src/egl/main/eglmode.h +++ b/src/egl/main/eglmode.h @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLMODE_INCLUDED #define EGLMODE_INCLUDED diff --git a/src/egl/main/eglmutex.h b/src/egl/main/eglmutex.h index 29faba0f241..852e25195c4 100644 --- a/src/egl/main/eglmutex.h +++ b/src/egl/main/eglmutex.h @@ -1,3 +1,31 @@ +/************************************************************************** + * + * Copyright 2009 Chia-I Wu <[email protected]> + * 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 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. + * + **************************************************************************/ + + #ifndef EGLMUTEX_INCLUDED #define EGLMUTEX_INCLUDED diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c index 3abe85ff22f..e21952094a2 100644 --- a/src/egl/main/eglscreen.c +++ b/src/egl/main/eglscreen.c @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + /* * Ideas for screen management extension to EGL. * diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h index 2a99f23c50a..5e2f6579e62 100644 --- a/src/egl/main/eglscreen.h +++ b/src/egl/main/eglscreen.h @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLSCREEN_INCLUDED #define EGLSCREEN_INCLUDED diff --git a/src/egl/main/eglstring.c b/src/egl/main/eglstring.c index e4ab19136fb..e3568cb3c20 100644 --- a/src/egl/main/eglstring.c +++ b/src/egl/main/eglstring.c @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + /** * String utils. */ diff --git a/src/egl/main/eglstring.h b/src/egl/main/eglstring.h index d4c89541362..d3ab435ab7f 100644 --- a/src/egl/main/eglstring.h +++ b/src/egl/main/eglstring.h @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010-2011 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLSTRING_INCLUDED #define EGLSTRING_INCLUDED diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c index cc505045e12..c9cfb01388e 100644 --- a/src/egl/main/eglsurface.c +++ b/src/egl/main/eglsurface.c @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + /** * Surface-related functions. */ diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h index ef01b32ede3..0541ff4e2f1 100644 --- a/src/egl/main/eglsurface.h +++ b/src/egl/main/eglsurface.h @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLSURFACE_INCLUDED #define EGLSURFACE_INCLUDED diff --git a/src/egl/main/eglsync.c b/src/egl/main/eglsync.c index 95e97c73542..d8e3ee0c3bf 100644 --- a/src/egl/main/eglsync.c +++ b/src/egl/main/eglsync.c @@ -1,3 +1,31 @@ +/************************************************************************** + * + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #include <string.h> #include "eglsync.h" diff --git a/src/egl/main/eglsync.h b/src/egl/main/eglsync.h index a0025237e7a..1a56889642e 100644 --- a/src/egl/main/eglsync.h +++ b/src/egl/main/eglsync.h @@ -1,3 +1,31 @@ +/************************************************************************** + * + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLSYNC_INCLUDED #define EGLSYNC_INCLUDED diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h index 20b67b28bc6..120a277b5fb 100644 --- a/src/egl/main/egltypedefs.h +++ b/src/egl/main/egltypedefs.h @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009-2010 Chia-I Wu <[email protected]> + * Copyright 2010 LunarG, Inc. + * 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 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. + * + **************************************************************************/ + + #ifndef EGLTYPEDEFS_INCLUDED #define EGLTYPEDEFS_INCLUDED diff --git a/src/egl/wayland/wayland-drm/Makefile b/src/egl/wayland/wayland-drm/Makefile index 789b020a592..bc010b6d9cb 100644 --- a/src/egl/wayland/wayland-drm/Makefile +++ b/src/egl/wayland/wayland-drm/Makefile @@ -34,6 +34,7 @@ depend: clean: rm -rf libwayland-drm.a $(wayland_drm_OBJECTS) \ $(GEN_SOURCES) $(GEN_HEADERS) + rm -f depend depend.bak install: @echo -n "" diff --git a/src/egl/wayland/wayland-drm/wayland-drm.c b/src/egl/wayland/wayland-drm/wayland-drm.c index 6cc442b9d53..3023cd02b07 100644 --- a/src/egl/wayland/wayland-drm/wayland-drm.c +++ b/src/egl/wayland/wayland-drm/wayland-drm.c @@ -88,17 +88,17 @@ drm_create_buffer(struct wl_client *client, struct wl_drm *drm, { struct wl_drm_buffer *buffer; - buffer = malloc(sizeof *buffer); + buffer = calloc(1, sizeof *buffer); if (buffer == NULL) { wl_client_post_no_memory(client); return; } buffer->drm = drm; - buffer->buffer.compositor = NULL; buffer->buffer.width = width; buffer->buffer.height = height; buffer->buffer.visual = visual; + buffer->buffer.client = client; if (!visual || visual->object.interface != &wl_visual_interface) { wl_client_post_error(client, &drm->object, diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 428bc31f86b..3072ee936f2 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -53,7 +53,7 @@ if env['drm']: # Needed by some state trackers SConscript('winsys/sw/null/SConscript') -if env['platform'] != 'embedded': +if not env['embedded']: SConscript('state_trackers/vega/SConscript') SConscript('state_trackers/egl/SConscript') @@ -66,8 +66,8 @@ if env['platform'] != 'embedded': if env['dri'] and env['xorg']: SConscript('state_trackers/xorg/SConscript') -if env['platform'] == 'windows': - SConscript('state_trackers/wgl/SConscript') + if env['platform'] == 'windows': + SConscript('state_trackers/wgl/SConscript') # # Winsys @@ -83,55 +83,55 @@ SConscript([ 'targets/graw-null/SConscript', ]) -if env['platform'] != 'embedded': +if not env['embedded']: SConscript([ 'targets/egl-static/SConscript' ]) -if env['x11']: - SConscript([ - 'targets/graw-xlib/SConscript', - 'targets/libgl-xlib/SConscript', - ]) + if env['x11']: + SConscript([ + 'targets/graw-xlib/SConscript', + 'targets/libgl-xlib/SConscript', + ]) -if env['platform'] == 'windows': - SConscript([ - 'targets/graw-gdi/SConscript', - 'targets/libgl-gdi/SConscript', - ]) + if env['platform'] == 'windows': + SConscript([ + 'targets/graw-gdi/SConscript', + 'targets/libgl-gdi/SConscript', + ]) -if env['dri']: - SConscript([ - 'targets/SConscript.dri', - 'targets/dri-swrast/SConscript', - 'targets/dri-vmwgfx/SConscript', - #'targets/dri-nouveau/SConscript', - ]) - if env['drm_intel']: + if env['dri']: SConscript([ - 'targets/dri-i915/SConscript', - 'targets/dri-i965/SConscript', + 'targets/SConscript.dri', + 'targets/dri-swrast/SConscript', + 'targets/dri-vmwgfx/SConscript', + #'targets/dri-nouveau/SConscript', ]) - if env['drm_radeon']: + if env['drm_intel']: + SConscript([ + 'targets/dri-i915/SConscript', + 'targets/dri-i965/SConscript', + ]) + if env['drm_radeon']: + SConscript([ + 'targets/dri-r300/SConscript', + 'targets/dri-r600/SConscript', + ]) + + if env['xorg'] and env['drm']: SConscript([ - 'targets/dri-r300/SConscript', - 'targets/dri-r600/SConscript', + #'targets/xorg-i915/SConscript', + #'targets/xorg-i965/SConscript', + #'targets/xorg-nouveau/SConscript', + #'targets/xorg-radeon/SConscript', + 'targets/xorg-vmwgfx/SConscript', ]) -if env['xorg'] and env['drm']: - SConscript([ - #'targets/xorg-i915/SConscript', - #'targets/xorg-i965/SConscript', - #'targets/xorg-nouveau/SConscript', - #'targets/xorg-radeon/SConscript', - 'targets/xorg-vmwgfx/SConscript', - ]) - # # Unit tests & tools # -if env['platform'] != 'embedded': +if not env['embedded']: SConscript('tests/unit/SConscript') SConscript('tests/graw/SConscript') diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 56c26f57cce..f33c9078c9c 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -1163,6 +1163,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) struct lp_build_loop_state lp_loop; const int max_vertices = 4; LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS]; + LLVMValueRef fetch_max; void *code; struct lp_build_sampler_soa *sampler = 0; LLVMValueRef ret, ret_ptr; @@ -1234,6 +1235,10 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) draw_llvm_variant_key_samplers(&variant->key), context_ptr); + fetch_max = LLVMBuildSub(builder, count, + lp_build_const_int32(gallivm, 1), + "fetch_max"); + #if DEBUG_STORE lp_build_printf(builder, "start = %d, end = %d, step = %d\n", start, end, step); @@ -1257,6 +1262,12 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) builder, lp_loop.counter, lp_build_const_int32(gallivm, i), ""); + + /* make sure we're not out of bounds which can happen + * if fetch_count % 4 != 0, because on the last iteration + * a few of the 4 vertex fetches will be out of bounds */ + true_index = lp_build_min(&bld, true_index, fetch_max); + for (j = 0; j < draw->pt.nr_vertex_elements; ++j) { struct pipe_vertex_element *velem = &draw->pt.vertex_element[j]; LLVMValueRef vb_index = lp_build_const_int32(gallivm, velem->vertex_buffer_index); diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 32af29ae144..458f85def2c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -784,6 +784,14 @@ aaline_destroy(struct draw_stage *stage) draw_free_temp_verts( stage ); + /* restore the old entry points */ + pipe->create_fs_state = aaline->driver_create_fs_state; + pipe->bind_fs_state = aaline->driver_bind_fs_state; + pipe->delete_fs_state = aaline->driver_delete_fs_state; + + pipe->bind_fragment_sampler_states = aaline->driver_bind_sampler_states; + pipe->set_fragment_sampler_views = aaline->driver_set_sampler_views; + FREE( stage ); } diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 60f6380c503..9265c379de8 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -768,7 +768,16 @@ aapoint_reset_stipple_counter(struct draw_stage *stage) static void aapoint_destroy(struct draw_stage *stage) { + struct aapoint_stage* aapoint = aapoint_stage(stage); + struct pipe_context *pipe = stage->draw->pipe; + draw_free_temp_verts( stage ); + + /* restore the old entry points */ + pipe->create_fs_state = aapoint->driver_create_fs_state; + pipe->bind_fs_state = aapoint->driver_bind_fs_state; + pipe->delete_fs_state = aapoint->driver_delete_fs_state; + FREE( stage ); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp index 0b724a34948..01e660ef7d9 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp +++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp @@ -207,7 +207,11 @@ lp_disassemble(const void* func) } raw_debug_ostream Out; +#if HAVE_LLVM >= 0x0300 + TargetMachine *TM = T->createTargetMachine(Triple, sys::getHostCPUName(), ""); +#else TargetMachine *TM = T->createTargetMachine(Triple, ""); +#endif #if HAVE_LLVM >= 0x0300 unsigned int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); @@ -287,7 +291,11 @@ lp_disassemble(const void* func) pc += Size; +#if HAVE_LLVM >= 0x0300 + const MCInstrDesc &TID = TII->get(Inst.getOpcode()); +#else const TargetInstrDesc &TID = TII->get(Inst.getOpcode()); +#endif /* * Keep track of forward jumps to a nearby address. diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp index d2d7eccd92f..85fabc574b2 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp @@ -83,8 +83,12 @@ lp_set_target_options(void) * to only assume a 4 bytes alignment for backwards compatibility. */ #if defined(PIPE_ARCH_X86) +#if HAVE_LLVM >= 0x0300 + llvm::StackAlignmentOverride = 4; +#else llvm::StackAlignment = 4; #endif +#endif #if defined(DEBUG) || defined(PROFILE) llvm::NoFramePointerElim = true; diff --git a/src/gallium/auxiliary/indices/u_unfilled_gen.py b/src/gallium/auxiliary/indices/u_unfilled_gen.py index 36896ce605d..085c47a114a 100644 --- a/src/gallium/auxiliary/indices/u_unfilled_gen.py +++ b/src/gallium/auxiliary/indices/u_unfilled_gen.py @@ -167,8 +167,8 @@ def trifan(intype, outtype): def polygon(intype, outtype): preamble(intype, outtype, prim='polygon') - print ' for (j = i = 0; j < nr; j+=6, i++) { ' - do_tri( intype, outtype, 'out+j', '0', 'i+1', 'i+2' ); + print ' for (j = i = 0; j < nr; j+=2, i++) { ' + line( intype, outtype, 'out+j', 'i', '(i+1)%(nr/2)' ) print ' }' postamble() diff --git a/src/gallium/auxiliary/indices/u_unfilled_indices.c b/src/gallium/auxiliary/indices/u_unfilled_indices.c index 26c5d4d4c72..c353717d656 100644 --- a/src/gallium/auxiliary/indices/u_unfilled_indices.c +++ b/src/gallium/auxiliary/indices/u_unfilled_indices.c @@ -71,6 +71,11 @@ static void generate_linear_uint( unsigned nr, } +/** + * Given a primitive type and number of vertices, return the number of vertices + * needed to draw the primitive with fill mode = PIPE_POLYGON_MODE_LINE using + * separate lines (PIPE_PRIM_LINES). + */ static unsigned nr_lines( unsigned prim, unsigned nr ) { @@ -86,7 +91,7 @@ static unsigned nr_lines( unsigned prim, case PIPE_PRIM_QUAD_STRIP: return (nr - 2) / 2 * 8; case PIPE_PRIM_POLYGON: - return (nr - 2) * 6; + return 2 * nr; /* a line (two verts) for each polygon edge */ default: assert(0); return 0; diff --git a/src/gallium/auxiliary/os/os_memory.h b/src/gallium/auxiliary/os/os_memory.h index 556662d35e1..91a84a24bc8 100644 --- a/src/gallium/auxiliary/os/os_memory.h +++ b/src/gallium/auxiliary/os/os_memory.h @@ -39,7 +39,7 @@ #include "pipe/p_compiler.h" -#if defined(PIPE_OS_EMBEDDED) +#if defined(PIPE_SUBSYSTEM_EMBEDDED) #ifdef __cplusplus extern "C" { diff --git a/src/gallium/auxiliary/os/os_misc.h b/src/gallium/auxiliary/os/os_misc.h index d59f9819fec..48522dac4d7 100644 --- a/src/gallium/auxiliary/os/os_misc.h +++ b/src/gallium/auxiliary/os/os_misc.h @@ -58,8 +58,6 @@ extern "C" { # define os_break() __debugbreak() #elif defined(PIPE_OS_UNIX) # define os_break() kill(getpid(), SIGTRAP) -#elif defined(PIPE_OS_EMBEDDED) -void os_break(void); #else # define os_break() abort() #endif @@ -70,8 +68,6 @@ void os_break(void); */ #if defined(DEBUG) || defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) # define os_abort() os_break() -#elif defined(PIPE_OS_EMBEDDED) -void os_abort(void); #else # define os_abort() abort() #endif diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h index 6b4281ad661..8f1245bff55 100644 --- a/src/gallium/auxiliary/os/os_thread.h +++ b/src/gallium/auxiliary/os/os_thread.h @@ -40,7 +40,7 @@ #include "util/u_debug.h" /* for assert */ -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) #include <pthread.h> /* POSIX threads headers */ #include <stdio.h> /* for perror() */ @@ -314,7 +314,7 @@ typedef int64_t pipe_condvar; * pipe_barrier */ -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) typedef pthread_barrier_t pipe_barrier; @@ -442,7 +442,7 @@ pipe_semaphore_wait(pipe_semaphore *sema) */ typedef struct { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) pthread_key_t key; #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) DWORD key; @@ -457,7 +457,7 @@ typedef struct { static INLINE void pipe_tsd_init(pipe_tsd *tsd) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) { perror("pthread_key_create(): failed to allocate key for thread specific data"); exit(-1); @@ -474,7 +474,7 @@ pipe_tsd_get(pipe_tsd *tsd) if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { pipe_tsd_init(tsd); } -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) return pthread_getspecific(tsd->key); #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) assert(0); @@ -491,7 +491,7 @@ pipe_tsd_set(pipe_tsd *tsd, void *value) if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { pipe_tsd_init(tsd); } -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) if (pthread_setspecific(tsd->key, value) != 0) { perror("pthread_set_specific() failed"); exit(-1); diff --git a/src/gallium/auxiliary/os/os_time.c b/src/gallium/auxiliary/os/os_time.c index 325f316784c..73d86296d91 100644 --- a/src/gallium/auxiliary/os/os_time.c +++ b/src/gallium/auxiliary/os/os_time.c @@ -35,8 +35,6 @@ #include "pipe/p_config.h" -#if !defined(PIPE_OS_EMBEDDED) - #if defined(PIPE_OS_UNIX) # include <sys/time.h> /* timeval */ #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) @@ -123,6 +121,3 @@ os_time_sleep(int64_t usecs) } #endif - - -#endif /* !PIPE_OS_EMBEDDED */ diff --git a/src/gallium/auxiliary/target-helpers/inline_debug_helper.h b/src/gallium/auxiliary/target-helpers/inline_debug_helper.h index 0433da6141d..c6630c40f5c 100644 --- a/src/gallium/auxiliary/target-helpers/inline_debug_helper.h +++ b/src/gallium/auxiliary/target-helpers/inline_debug_helper.h @@ -22,6 +22,10 @@ #include "galahad/glhd_public.h" #endif +#ifdef GALLIUM_NOOP +#include "noop/noop_public.h" +#endif + static INLINE struct pipe_screen * debug_screen_wrap(struct pipe_screen *screen) { @@ -38,6 +42,10 @@ debug_screen_wrap(struct pipe_screen *screen) screen = galahad_screen_create(screen); #endif +#if defined(GALLIUM_NOOP) + screen = noop_screen_create(screen); +#endif + return screen; } diff --git a/src/gallium/auxiliary/target-helpers/inline_noop_helper.h b/src/gallium/auxiliary/target-helpers/inline_noop_helper.h deleted file mode 100644 index 77c7cfd0c20..00000000000 --- a/src/gallium/auxiliary/target-helpers/inline_noop_helper.h +++ /dev/null @@ -1,51 +0,0 @@ - -#ifndef INLINE_DEBUG_HELPER_H -#define INLINE_DEBUG_HELPER_H - -#include "pipe/p_compiler.h" -#include "util/u_debug.h" - - -/* Helper function to wrap a screen with - * one or more debug driver: rbug, trace. - */ - -#ifdef GALLIUM_TRACE -#include "trace/tr_public.h" -#endif - -#ifdef GALLIUM_RBUG -#include "rbug/rbug_public.h" -#endif - -#ifdef GALLIUM_GALAHAD -#include "galahad/glhd_public.h" -#endif - -#ifdef GALLIUM_NOOP -#include "noop/noop_public.h" -#endif - -static INLINE struct pipe_screen * -debug_screen_wrap(struct pipe_screen *screen) -{ -#if defined(GALLIUM_RBUG) - screen = rbug_screen_create(screen); -#endif - -#if defined(GALLIUM_TRACE) - screen = trace_screen_create(screen); -#endif - -#if defined(GALLIUM_GALAHAD) - screen = galahad_screen_create(screen); -#endif - -#if defined(GALLIUM_NOOP) - screen = noop_screen_create(screen); -#endif - - return screen; -} - -#endif diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c index 36ce4b57713..004df439ff5 100644 --- a/src/gallium/auxiliary/util/u_debug.c +++ b/src/gallium/auxiliary/util/u_debug.c @@ -48,7 +48,7 @@ void _debug_vprintf(const char *format, va_list ap) { -#if defined(PIPE_OS_WINDOWS) || defined(PIPE_OS_EMBEDDED) +#if defined(PIPE_OS_WINDOWS) || defined(PIPE_SUBSYSTEM_EMBEDDED) /* We buffer until we find a newline. */ static char buf[4096] = {'\0'}; size_t len = strlen(buf); diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c index 9562acb8210..e50db6d67fe 100644 --- a/src/gallium/auxiliary/util/u_upload_mgr.c +++ b/src/gallium/auxiliary/util/u_upload_mgr.c @@ -72,6 +72,22 @@ struct u_upload_mgr *u_upload_create( struct pipe_context *pipe, return upload; } +void u_upload_unmap( struct u_upload_mgr *upload ) +{ + if (upload->transfer) { + struct pipe_box *box = &upload->transfer->box; + if (upload->offset > box->x) { + + pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer, + box->x, upload->offset - box->x); + } + pipe_transfer_unmap(upload->pipe, upload->transfer); + pipe_transfer_destroy(upload->pipe, upload->transfer); + upload->transfer = NULL; + upload->map = NULL; + } +} + /* Release old buffer. * * This must usually be called prior to firing the command stream @@ -84,15 +100,7 @@ struct u_upload_mgr *u_upload_create( struct pipe_context *pipe, void u_upload_flush( struct u_upload_mgr *upload ) { /* Unmap and unreference the upload buffer. */ - if (upload->transfer) { - if (upload->offset) { - pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer, - 0, upload->offset); - } - pipe_transfer_unmap(upload->pipe, upload->transfer); - pipe_transfer_destroy(upload->pipe, upload->transfer); - upload->transfer = NULL; - } + u_upload_unmap(upload); pipe_resource_reference( &upload->buffer, NULL ); upload->size = 0; } @@ -172,6 +180,15 @@ enum pipe_error u_upload_alloc( struct u_upload_mgr *upload, offset = MAX2(upload->offset, alloc_offset); + if (!upload->map) { + upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer, + offset, upload->size - offset, + PIPE_TRANSFER_WRITE | + PIPE_TRANSFER_FLUSH_EXPLICIT | + PIPE_TRANSFER_UNSYNCHRONIZED, + &upload->transfer); + } + assert(offset < upload->buffer->width0); assert(offset + size <= upload->buffer->width0); assert(size); @@ -223,10 +240,11 @@ enum pipe_error u_upload_buffer( struct u_upload_mgr *upload, struct pipe_transfer *transfer = NULL; const char *map = NULL; - map = (const char *)pipe_buffer_map(upload->pipe, - inbuf, - PIPE_TRANSFER_READ, - &transfer); + map = (const char *)pipe_buffer_map_range(upload->pipe, + inbuf, + offset, size, + PIPE_TRANSFER_READ, + &transfer); if (map == NULL) { ret = PIPE_ERROR_OUT_OF_MEMORY; @@ -239,7 +257,7 @@ enum pipe_error u_upload_buffer( struct u_upload_mgr *upload, ret = u_upload_data( upload, min_out_offset, size, - map + offset, + map, out_offset, outbuf, flushed ); diff --git a/src/gallium/auxiliary/util/u_upload_mgr.h b/src/gallium/auxiliary/util/u_upload_mgr.h index c9a2ffeb572..98915139801 100644 --- a/src/gallium/auxiliary/util/u_upload_mgr.h +++ b/src/gallium/auxiliary/util/u_upload_mgr.h @@ -56,15 +56,27 @@ struct u_upload_mgr *u_upload_create( struct pipe_context *pipe, */ void u_upload_destroy( struct u_upload_mgr *upload ); -/* Unmap and release old buffer. +/* Unmap and release old upload buffer. * + * This is like u_upload_unmap() except the upload buffer is released for + * recycling. This should be called on real hardware flushes on systems + * that don't support the PIPE_TRANSFER_UNSYNCHRONIZED flag, as otherwise + * the next u_upload_buffer will cause a sync on the buffer. + */ + +void u_upload_flush( struct u_upload_mgr *upload ); + +/** + * Unmap upload buffer + * + * \param upload Upload manager + * * This must usually be called prior to firing the command stream * which references the upload buffer, as many memory managers either * don't like firing a mapped buffer or cause subsequent maps of a - * fired buffer to wait. For now, it's easiest just to grab a new - * buffer. + * fired buffer to wait. */ -void u_upload_flush( struct u_upload_mgr *upload ); +void u_upload_unmap( struct u_upload_mgr *upload ); /** * Sub-allocate new memory from the upload buffer. diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.c b/src/gallium/auxiliary/util/u_vbuf_mgr.c index 04149525ea7..374fc336b83 100644 --- a/src/gallium/auxiliary/util/u_vbuf_mgr.c +++ b/src/gallium/auxiliary/util/u_vbuf_mgr.c @@ -152,9 +152,9 @@ void u_vbuf_mgr_destroy(struct u_vbuf_mgr *mgrb) } -static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr, - int min_index, int max_index, - boolean *upload_flushed) +static enum u_vbuf_return_flags +u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr, + int min_index, int max_index) { struct translate_key key; struct translate_element *te; @@ -166,6 +166,7 @@ static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr, struct pipe_resource *out_buffer = NULL; unsigned i, num_verts, out_offset; struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS]; + boolean upload_flushed = FALSE; memset(&key, 0, sizeof(key)); memset(tr_elem_index, 0xff, sizeof(tr_elem_index)); @@ -248,7 +249,7 @@ static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr, u_upload_alloc(mgr->b.uploader, key.output_stride * min_index, key.output_stride * num_verts, - &out_offset, &out_buffer, upload_flushed, + &out_offset, &out_buffer, &upload_flushed, (void**)&out_map); out_offset -= key.output_stride * min_index; @@ -308,6 +309,8 @@ static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr, } pipe_resource_reference(&out_buffer, NULL); + + return upload_flushed ? U_VBUF_UPLOAD_FLUSHED : 0; } static void u_vbuf_translate_end(struct u_vbuf_mgr_priv *mgr) @@ -510,14 +513,15 @@ void u_vbuf_mgr_set_vertex_buffers(struct u_vbuf_mgr *mgrb, mgr->b.nr_real_vertex_buffers = count; } -static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr, - int min_index, int max_index, - unsigned instance_count, - boolean *upload_flushed) +static enum u_vbuf_return_flags +u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr, + int min_index, int max_index, + unsigned instance_count) { unsigned i, nr = mgr->ve->count; unsigned count = max_index + 1 - min_index; boolean uploaded[PIPE_MAX_ATTRIBS] = {0}; + enum u_vbuf_return_flags retval = 0; for (i = 0; i < nr; i++) { unsigned index = mgr->ve->ve[i].vertex_buffer_index; @@ -537,6 +541,11 @@ static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr, } else if (vb->stride) { first = vb->stride * min_index; size = vb->stride * count; + + /* Unusual case when stride is smaller than the format size. + * XXX This won't work with interleaved arrays. */ + if (mgr->ve->native_format_size[i] > vb->stride) + size += mgr->ve->native_format_size[i] - vb->stride; } else { first = 0; size = mgr->ve->native_format_size[i]; @@ -551,11 +560,14 @@ static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr, vb->buffer_offset -= first; uploaded[index] = TRUE; - *upload_flushed = *upload_flushed || flushed; + if (flushed) + retval |= U_VBUF_UPLOAD_FLUSHED; } else { assert(mgr->b.real_vertex_buffer[index]); } } + + return retval; } static void u_vbuf_mgr_compute_max_index(struct u_vbuf_mgr_priv *mgr) @@ -597,14 +609,13 @@ static void u_vbuf_mgr_compute_max_index(struct u_vbuf_mgr_priv *mgr) } } -void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb, - const struct pipe_draw_info *info, - boolean *buffers_updated, - boolean *uploader_flushed) +enum u_vbuf_return_flags +u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb, + const struct pipe_draw_info *info) { struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb; - boolean bufs_updated = FALSE, upload_flushed = FALSE; int min_index, max_index; + enum u_vbuf_return_flags retval = 0; u_vbuf_mgr_compute_max_index(mgr); @@ -617,27 +628,20 @@ void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb, /* Translate vertices with non-native layouts or formats. */ if (mgr->incompatible_vb_layout || mgr->ve->incompatible_layout) { - u_vbuf_translate_begin(mgr, min_index, max_index, &upload_flushed); + retval |= u_vbuf_translate_begin(mgr, min_index, max_index); if (mgr->fallback_ve) { - bufs_updated = TRUE; + retval |= U_VBUF_BUFFERS_UPDATED; } } /* Upload user buffers. */ if (mgr->any_user_vbs) { - u_vbuf_upload_buffers(mgr, min_index, max_index, info->instance_count, - &upload_flushed); - bufs_updated = TRUE; - } - - /* Set the return values. */ - if (buffers_updated) { - *buffers_updated = bufs_updated; - } - if (uploader_flushed) { - *uploader_flushed = upload_flushed; + retval |= u_vbuf_upload_buffers(mgr, min_index, max_index, + info->instance_count); + retval |= U_VBUF_BUFFERS_UPDATED; } + return retval; } void u_vbuf_mgr_draw_end(struct u_vbuf_mgr *mgrb) diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.h b/src/gallium/auxiliary/util/u_vbuf_mgr.h index 9380dce4f72..4e6372435d8 100644 --- a/src/gallium/auxiliary/util/u_vbuf_mgr.h +++ b/src/gallium/auxiliary/util/u_vbuf_mgr.h @@ -78,6 +78,11 @@ enum u_fetch_alignment { U_VERTEX_FETCH_DWORD_ALIGNED }; +enum u_vbuf_return_flags { + U_VBUF_BUFFERS_UPDATED = 1, + U_VBUF_UPLOAD_FLUSHED = 2 +}; + struct u_vbuf_mgr * u_vbuf_mgr_create(struct pipe_context *pipe, @@ -105,10 +110,9 @@ void u_vbuf_mgr_set_vertex_buffers(struct u_vbuf_mgr *mgr, unsigned count, const struct pipe_vertex_buffer *bufs); -void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgr, - const struct pipe_draw_info *info, - boolean *buffers_updated, - boolean *uploader_flushed); +enum u_vbuf_return_flags +u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgr, + const struct pipe_draw_info *info); void u_vbuf_mgr_draw_end(struct u_vbuf_mgr *mgr); diff --git a/src/gallium/drivers/i915/Makefile b/src/gallium/drivers/i915/Makefile index b3f387f9335..778124728bb 100644 --- a/src/gallium/drivers/i915/Makefile +++ b/src/gallium/drivers/i915/Makefile @@ -21,6 +21,7 @@ C_SOURCES = \ i915_screen.c \ i915_prim_emit.c \ i915_prim_vbuf.c \ + i915_query.c \ i915_resource.c \ i915_resource_texture.c \ i915_resource_buffer.c \ diff --git a/src/gallium/drivers/i915/SConscript b/src/gallium/drivers/i915/SConscript index 8f5deed64a9..98370601b7f 100644 --- a/src/gallium/drivers/i915/SConscript +++ b/src/gallium/drivers/i915/SConscript @@ -16,6 +16,7 @@ i915 = env.ConvenienceLibrary( 'i915_fpc_translate.c', 'i915_prim_emit.c', 'i915_prim_vbuf.c', + 'i915_query.c', 'i915_screen.c', 'i915_state.c', 'i915_state_derived.c', diff --git a/src/gallium/drivers/i915/TODO b/src/gallium/drivers/i915/TODO index fba180064c3..c26db198d20 100644 --- a/src/gallium/drivers/i915/TODO +++ b/src/gallium/drivers/i915/TODO @@ -26,5 +26,20 @@ Random list of problems with i915g: - src/xvmc/i915_structs.h in xf86-video-intel has a few more bits of various commands defined. Scavenge them and see what's useful. +- Do smarter remapping. Right now we send everything onto tex coords 0-7. + We could also use diffuse/specular and pack two sets of 2D coords in a single + 4D. Is it a big problem though? We're more limited by the # of texture + indirections and the # of instructions. + +- Leverage draw to enable more caps: + * PIPE_CAP_TGSI_INSTANCEID + * PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS + +- Finish front/back face. We need to add face support to lp_build_system_values_array and use it in draw_llvm.c. + +- Replace constants and immediates which are 0,1,-1 or a combination of those with a swizzle. + +- i915_delete_fs_state doesn't call draw_delete_fragment_shader. Why? + Other bugs can be found here: https://bugs.freedesktop.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&component=Drivers/Gallium/i915g diff --git a/src/gallium/drivers/i915/i915_clear.c b/src/gallium/drivers/i915/i915_clear.c index 4a97746e981..fcb208d6dae 100644 --- a/src/gallium/drivers/i915/i915_clear.c +++ b/src/gallium/drivers/i915/i915_clear.c @@ -66,7 +66,7 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers, const float *rgba, else clear_color = (u_color.ui & 0xffff) | (u_color.ui << 16); - util_pack_color(rgba, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color); + util_pack_color(rgba, cbuf->format, &u_color); clear_color8888 = u_color.ui; } else clear_color = clear_color8888 = 0; diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index 7a98ef73c1f..28ff40a2328 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -29,6 +29,7 @@ #include "i915_state.h" #include "i915_screen.h" #include "i915_surface.h" +#include "i915_query.h" #include "i915_batch.h" #include "i915_resource.h" @@ -53,13 +54,11 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) struct i915_context *i915 = i915_context(pipe); struct draw_context *draw = i915->draw; void *mapped_indices = NULL; - unsigned cbuf_dirty; /* * Ack vs contants here, helps ipers a lot. */ - cbuf_dirty = i915->dirty & I915_NEW_VS_CONSTANTS; i915->dirty &= ~I915_NEW_VS_CONSTANTS; if (i915->dirty) @@ -72,15 +71,13 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) mapped_indices = i915_buffer(i915->index_buffer.buffer)->data; draw_set_mapped_index_buffer(draw, mapped_indices); - if (cbuf_dirty) { - if (i915->constants[PIPE_SHADER_VERTEX]) - draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, - i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data, - (i915->current.num_user_constants[PIPE_SHADER_VERTEX] * - 4 * sizeof(float))); - else - draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0); - } + if (i915->constants[PIPE_SHADER_VERTEX]) + draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, + i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data, + (i915->current.num_user_constants[PIPE_SHADER_VERTEX] * + 4 * sizeof(float))); + else + draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0); /* * Do the drawing @@ -106,7 +103,7 @@ static void i915_destroy(struct pipe_context *pipe) if (i915->blitter) util_blitter_destroy(i915->blitter); - + if(i915->batch) i915->iws->batchbuffer_destroy(i915->batch); @@ -150,6 +147,8 @@ i915_create_context(struct pipe_screen *screen, void *priv) /* init this before draw */ util_slab_create(&i915->transfer_pool, sizeof(struct pipe_transfer), 16, UTIL_SLAB_SINGLETHREADED); + util_slab_create(&i915->texture_transfer_pool, sizeof(struct i915_transfer), + 16, UTIL_SLAB_SINGLETHREADED); /* Batch stream debugging is a bit hacked up at the moment: */ @@ -170,9 +169,11 @@ i915_create_context(struct pipe_screen *screen, void *priv) i915_init_state_functions(i915); i915_init_flush_functions(i915); i915_init_resource_functions(i915); + i915_init_query_functions(i915); draw_install_aaline_stage(i915->draw, &i915->base); draw_install_aapoint_stage(i915->draw, &i915->base); + draw_enable_point_sprites(i915->draw, TRUE); /* augmented draw pipeline clobbers state functions */ i915_init_fixup_state_functions(i915); diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index 964948edc0e..c964208fedd 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -102,6 +102,8 @@ struct i915_fragment_shader struct tgsi_shader_info info; + struct draw_fragment_shader *draw_data; + uint *program; uint program_len; @@ -260,6 +262,7 @@ struct i915_context { int num_validation_buffers; struct util_slab_mempool transfer_pool; + struct util_slab_mempool texture_transfer_pool; /** blitter/hw-clear */ struct blitter_context* blitter; diff --git a/src/gallium/drivers/i915/i915_fpc.h b/src/gallium/drivers/i915/i915_fpc.h index 2f0f99d0468..509395cf1f5 100644 --- a/src/gallium/drivers/i915/i915_fpc.h +++ b/src/gallium/drivers/i915/i915_fpc.h @@ -37,6 +37,9 @@ #define I915_PROGRAM_SIZE 192 +/* Use those indices for pos/face routing, must be >= I915_TEX_UNITS */ +#define I915_SEMANTIC_POS 10 +#define I915_SEMANTIC_FACE 11 /** @@ -67,13 +70,13 @@ struct i915_fp_compile { uint temp_flag; /**< Tracks temporary regs which are in use */ uint utemp_flag; /**< Tracks TYPE_U temporary regs which are in use */ + uint register_phases[16]; uint nr_tex_indirect; uint nr_tex_insn; uint nr_alu_insn; uint nr_decl_insn; boolean error; /**< Set if i915_program_error() is called */ - uint wpos_tex; uint NumNativeInstructions; uint NumNativeAluInstructions; uint NumNativeTexInstructions; diff --git a/src/gallium/drivers/i915/i915_fpc_emit.c b/src/gallium/drivers/i915/i915_fpc_emit.c index 76c24d2b2fd..d28595e0fd3 100644 --- a/src/gallium/drivers/i915/i915_fpc_emit.c +++ b/src/gallium/drivers/i915/i915_fpc_emit.c @@ -67,7 +67,7 @@ i915_get_temp(struct i915_fp_compile *p) { int bit = ffs(~p->temp_flag); if (!bit) { - i915_program_error(p, "i915_get_temp: out of temporaries\n"); + i915_program_error(p, "i915_get_temp: out of temporaries"); return 0; } @@ -92,7 +92,7 @@ i915_get_utemp(struct i915_fp_compile * p) { int bit = ffs(~p->utemp_flag); if (!bit) { - i915_program_error(p, "i915_get_utemp: out of temporaries\n"); + i915_program_error(p, "i915_get_utemp: out of temporaries"); return 0; } @@ -128,9 +128,13 @@ i915_emit_decl(struct i915_fp_compile *p, else return reg; - *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags); - *(p->decl++) = D1_MBZ; - *(p->decl++) = D2_MBZ; + if (p->decl< p->declarations + I915_PROGRAM_SIZE) { + *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags); + *(p->decl++) = D1_MBZ; + *(p->decl++) = D2_MBZ; + } + else + i915_program_error(p, "Out of declarations"); p->nr_decl_insn++; return reg; @@ -187,9 +191,16 @@ i915_emit_arith(struct i915_fp_compile * p, p->utemp_flag = old_utemp_flag; /* restore */ } - *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); - *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1)); - *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2)); + if (p->csr< p->program + I915_PROGRAM_SIZE) { + *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); + *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1)); + *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2)); + } + else + i915_program_error(p, "Out of instructions"); + + if (GET_UREG_TYPE(dest) == REG_TYPE_R) + p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect; p->nr_alu_insn++; return dest; @@ -245,17 +256,31 @@ uint i915_emit_texld( struct i915_fp_compile *p, assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); assert(dest == UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest))); - /* is the sampler coord a texcoord input reg? */ - if (GET_UREG_TYPE(coord) != REG_TYPE_T) { - p->nr_tex_indirect++; - } + /* Output register being oC or oD defines a phase boundary */ + if (GET_UREG_TYPE(dest) == REG_TYPE_OC || + GET_UREG_TYPE(dest) == REG_TYPE_OD) + p->nr_tex_indirect++; - *(p->csr++) = (opcode | - T0_DEST( dest ) | - T0_SAMPLER( sampler )); + /* Reading from an r# register whose contents depend on output of the + * current phase defines a phase boundary. + */ + if (GET_UREG_TYPE(coord) == REG_TYPE_R && + p->register_phases[GET_UREG_NR(coord)] == p->nr_tex_indirect) + p->nr_tex_indirect++; + + if (p->csr< p->program + I915_PROGRAM_SIZE) { + *(p->csr++) = (opcode | + T0_DEST( dest ) | + T0_SAMPLER( sampler )); + + *(p->csr++) = T1_ADDRESS_REG( coord ); + *(p->csr++) = T2_MBZ; + } + else + i915_program_error(p, "Out of instructions"); - *(p->csr++) = T1_ADDRESS_REG( coord ); - *(p->csr++) = T2_MBZ; + if (GET_UREG_TYPE(dest) == REG_TYPE_R) + p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect; p->nr_tex_insn++; } @@ -293,7 +318,7 @@ i915_emit_const1f(struct i915_fp_compile * p, float c0) } } - i915_program_error(p, "i915_emit_const1f: out of constants\n"); + i915_program_error(p, "i915_emit_const1f: out of constants"); return 0; } @@ -313,6 +338,8 @@ i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1) if (c1 == 1.0) return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W); + // XXX emit swizzle here for 0, 1, -1 and any combination thereof + // we can use swizzle + neg for that for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { if (ifs->constant_flags[reg] == 0xf || ifs->constant_flags[reg] == I915_CONSTFLAG_USER) @@ -329,12 +356,10 @@ i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1) } } - i915_program_error(p, "i915_emit_const2f: out of constants\n"); + i915_program_error(p, "i915_emit_const2f: out of constants"); return 0; } - - uint i915_emit_const4f(struct i915_fp_compile * p, float c0, float c1, float c2, float c3) @@ -342,6 +367,9 @@ i915_emit_const4f(struct i915_fp_compile * p, struct i915_fragment_shader *ifs = p->shader; unsigned reg; + // XXX emit swizzle here for 0, 1, -1 and any combination thereof + // we can use swizzle + neg for that + printf("const %f %f %f %f\n",c0,c1,c2,c3); for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { if (ifs->constant_flags[reg] == 0xf && ifs->constants[reg][0] == c0 && @@ -363,7 +391,7 @@ i915_emit_const4f(struct i915_fp_compile * p, } } - i915_program_error(p, "i915_emit_const4f: out of constants\n"); + i915_program_error(p, "i915_emit_const4f: out of constants"); return 0; } diff --git a/src/gallium/drivers/i915/i915_fpc_translate.c b/src/gallium/drivers/i915/i915_fpc_translate.c index 27f100843bf..0cbd4f2d748 100644 --- a/src/gallium/drivers/i915/i915_fpc_translate.c +++ b/src/gallium/drivers/i915/i915_fpc_translate.c @@ -41,6 +41,9 @@ #include "draw/draw_vertex.h" +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif /** * Simple pass-through fragment shader to use when we don't have @@ -72,19 +75,33 @@ static unsigned passthrough[] = /* 1, -1/3!, 1/5!, -1/7! */ -static const float sin_constants[4] = { 1.0, +static const float scs_sin_constants[4] = { 1.0, -1.0f / (3 * 2 * 1), 1.0f / (5 * 4 * 3 * 2 * 1), -1.0f / (7 * 6 * 5 * 4 * 3 * 2 * 1) }; /* 1, -1/2!, 1/4!, -1/6! */ -static const float cos_constants[4] = { 1.0, +static const float scs_cos_constants[4] = { 1.0, -1.0f / (2 * 1), 1.0f / (4 * 3 * 2 * 1), -1.0f / (6 * 5 * 4 * 3 * 2 * 1) }; +/* 2*pi, -(2*pi)^3/3!, (2*pi)^5/5!, -(2*pi)^7/7! */ +static const float sin_constants[4] = { 2.0 * M_PI, + -8.0f * M_PI * M_PI * M_PI / (3 * 2 * 1), + 32.0f * M_PI * M_PI * M_PI * M_PI * M_PI / (5 * 4 * 3 * 2 * 1), + -128.0f * M_PI * M_PI * M_PI * M_PI * M_PI * M_PI * M_PI / (7 * 6 * 5 * 4 * 3 * 2 * 1) +}; + +/* 1, -(2*pi)^2/2!, (2*pi)^4/4!, -(2*pi)^6/6! */ +static const float cos_constants[4] = { 1.0, + -4.0f * M_PI * M_PI / (2 * 1), + 16.0f * M_PI * M_PI * M_PI * M_PI / (4 * 3 * 2 * 1), + -64.0f * M_PI * M_PI * M_PI * M_PI * M_PI * M_PI / (6 * 5 * 4 * 3 * 2 * 1) +}; + /** @@ -185,12 +202,12 @@ src_vector(struct i915_fp_compile *p, switch (sem_name) { case TGSI_SEMANTIC_POSITION: - debug_printf("SKIP SEM POS\n"); - /* - assert(p->wpos_tex != -1); - src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL); - */ - break; + { + /* for fragcoord */ + int real_tex_unit = get_mapping(fs, I915_SEMANTIC_POS); + src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_ALL); + break; + } case TGSI_SEMANTIC_COLOR: if (sem_ind == 0) { src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL); @@ -212,6 +229,13 @@ src_vector(struct i915_fp_compile *p, src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_ALL); break; } + case TGSI_SEMANTIC_FACE: + { + /* for back/front faces */ + int real_tex_unit = get_mapping(fs, I915_SEMANTIC_FACE); + src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_X); + break; + } default: i915_program_error(p, "Bad source->Index"); return 0; @@ -237,7 +261,6 @@ src_vector(struct i915_fp_compile *p, source->Register.SwizzleZ, source->Register.SwizzleW); - /* There's both negate-all-components and per-component negation. * Try to handle both here. */ @@ -252,6 +275,9 @@ src_vector(struct i915_fp_compile *p, /* XXX enable these assertions, or fix things */ assert(!source->Register.Absolute); #endif + if (source->Register.Absolute) + debug_printf("Unhandled absolute value\n"); + return src; } @@ -419,11 +445,6 @@ emit_simple_arith_swap2(struct i915_fp_compile *p, emit_simple_arith(p, &inst2, opcode, numArgs, fs); } - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - /* * Translate TGSI instruction to i915 instruction. * @@ -477,13 +498,6 @@ i915_translate_instruction(struct i915_fp_compile *p, i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); - /* By choosing different taylor constants, could get rid of this mul: - */ - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_X, 0, - tmp, i915_emit_const1f(p, (float) (M_PI * 2.0)), 0); - /* * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, 1 @@ -516,6 +530,18 @@ i915_translate_instruction(struct i915_fp_compile *p, i915_emit_const4fv(p, cos_constants), 0); break; + case TGSI_OPCODE_DDX: + case TGSI_OPCODE_DDY: + /* XXX We just output 0 here */ + debug_printf("Punting DDX/DDX\n"); + src0 = get_result_vector(p, &inst->Dst[0]); + i915_emit_arith(p, + A0_MOV, + get_result_vector(p, &inst->Dst[0]), + get_result_flags(inst), 0, + swizzle(src0, ZERO, ZERO, ZERO, ZERO), 0, 0); + break; + case TGSI_OPCODE_DP2: src0 = src_vector(p, &inst->Src[0], fs); src1 = src_vector(p, &inst->Src[1], fs); @@ -754,9 +780,9 @@ i915_translate_instruction(struct i915_fp_compile *p, * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x - * scs.x = DP4 t1, sin_constants + * scs.x = DP4 t1, scs_sin_constants * t1 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 - * scs.y = DP4 t1, cos_constants + * scs.y = DP4 t1, scs_cos_constants */ i915_emit_arith(p, A0_MUL, @@ -791,7 +817,7 @@ i915_translate_instruction(struct i915_fp_compile *p, get_result_vector(p, &inst->Dst[0]), A0_DEST_CHANNEL_Y, 0, swizzle(tmp1, W, Z, Y, X), - i915_emit_const4fv(p, sin_constants), 0); + i915_emit_const4fv(p, scs_sin_constants), 0); } if (writemask & TGSI_WRITEMASK_X) { @@ -806,7 +832,7 @@ i915_translate_instruction(struct i915_fp_compile *p, get_result_vector(p, &inst->Dst[0]), A0_DEST_CHANNEL_X, 0, swizzle(tmp, ONE, Z, Y, X), - i915_emit_const4fv(p, cos_constants), 0); + i915_emit_const4fv(p, scs_cos_constants), 0); } break; @@ -853,13 +879,6 @@ i915_translate_instruction(struct i915_fp_compile *p, i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); - /* By choosing different taylor constants, could get rid of this mul: - */ - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_X, 0, - tmp, i915_emit_const1f(p, (float) (M_PI * 2.0)), 0); - /* * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x @@ -907,7 +926,7 @@ i915_translate_instruction(struct i915_fp_compile *p, break; case TGSI_OPCODE_SNE: - /* if we're neither < nor > then we're != */ + /* if we're < or > then we're != */ src0 = src_vector(p, &inst->Src[0], fs); src1 = src_vector(p, &inst->Src[1], fs); tmp = i915_get_utemp(p); @@ -1070,9 +1089,11 @@ i915_translate_instructions(struct i915_fp_compile *p, for (i = parse.FullToken.FullDeclaration.Range.First; i <= parse.FullToken.FullDeclaration.Range.Last; i++) { - assert(i < I915_MAX_TEMPORARY); - /* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */ - p->temp_flag |= (1 << i); /* mark temp as used */ + if (i >= I915_MAX_TEMPORARY) + debug_printf("Too many temps (%d)\n",i); + else + /* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */ + p->temp_flag |= (1 << i); /* mark temp as used */ } } break; @@ -1144,6 +1165,8 @@ i915_init_compile(struct i915_context *i915, ifs->num_constants = 0; memset(ifs->constant_flags, 0, sizeof(ifs->constant_flags)); + memset(&p->register_phases, 0, sizeof(p->register_phases)); + for (i = 0; i < I915_TEX_UNITS; i++) ifs->generic_mapping[i] = -1; @@ -1161,8 +1184,6 @@ i915_init_compile(struct i915_context *i915, p->temp_flag = ~0x0 << I915_MAX_TEMPORARY; p->utemp_flag = ~0x7; - p->wpos_tex = -1; - /* initialize the first program word */ *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM; @@ -1181,7 +1202,7 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p) unsigned long decl_size = (unsigned long) (p->decl - p->declarations); if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT) - i915_program_error(p, "Exceeded max nr indirect texture lookups"); + debug_printf("Exceeded max nr indirect texture lookups\n"); if (p->nr_tex_insn > I915_MAX_TEX_INSN) i915_program_error(p, "Exceeded max TEX instructions"); @@ -1234,40 +1255,6 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p) } -/** - * Find an unused texture coordinate slot to use for fragment WPOS. - * Update p->fp->wpos_tex with the result (-1 if no used texcoord slot is found). - */ -static void -i915_find_wpos_space(struct i915_fp_compile *p) -{ -#if 0 - const uint inputs - = p->shader->inputs_read | (1 << TGSI_ATTRIB_POS); /*XXX hack*/ - uint i; - - p->wpos_tex = -1; - - if (inputs & (1 << TGSI_ATTRIB_POS)) { - for (i = 0; i < I915_TEX_UNITS; i++) { - if ((inputs & (1 << (TGSI_ATTRIB_TEX0 + i))) == 0) { - p->wpos_tex = i; - return; - } - } - - i915_program_error(p, "No free texcoord for wpos value"); - } -#else - if (p->shader->info.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) { - /* frag shader using the fragment position input */ -#if 0 - assert(0); -#endif - } -#endif -} - @@ -1314,7 +1301,6 @@ i915_translate_fragment_program( struct i915_context *i915, } p = i915_init_compile(i915, fs); - i915_find_wpos_space(p); i915_translate_instructions(p, tokens, fs); i915_fixup_depth_write(p); diff --git a/src/gallium/drivers/i915/i915_query.c b/src/gallium/drivers/i915/i915_query.c new file mode 100644 index 00000000000..c886df74bad --- /dev/null +++ b/src/gallium/drivers/i915/i915_query.c @@ -0,0 +1,86 @@ +/************************************************************************** + * + * Copyright 2011 The Chromium OS authors. + * 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 GOOGLE 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. + * + **************************************************************************/ + +/* Fake occlusion queries which return 0, it's better than crashing */ + +#include "pipe/p_compiler.h" + +#include "util/u_memory.h" + +#include "i915_context.h" +#include "i915_query.h" + +struct i915_query +{ + unsigned query; +}; + +static struct pipe_query *i915_create_query(struct pipe_context *ctx, + unsigned query_type) +{ + struct i915_query *query = CALLOC_STRUCT( i915_query ); + + return (struct pipe_query *)query; +} + +static void i915_destroy_query(struct pipe_context *ctx, + struct pipe_query *query) +{ + FREE(query); +} + +static void i915_begin_query(struct pipe_context *ctx, + struct pipe_query *query) +{ +} + +static void i915_end_query(struct pipe_context *ctx, struct pipe_query *query) +{ +} + +static boolean i915_get_query_result(struct pipe_context *ctx, + struct pipe_query *query, + boolean wait, + void *vresult) +{ + uint64_t *result = (uint64_t*)vresult; + + /* 2* viewport Max */ + *result = 512*1024*1024; + return TRUE; +} + +void +i915_init_query_functions(struct i915_context *i915) +{ + i915->base.create_query = i915_create_query; + i915->base.destroy_query = i915_destroy_query; + i915->base.begin_query = i915_begin_query; + i915->base.end_query = i915_end_query; + i915->base.get_query_result = i915_get_query_result; +} + diff --git a/src/gallium/drivers/i915/i915_query.h b/src/gallium/drivers/i915/i915_query.h new file mode 100644 index 00000000000..2c689ea6b1c --- /dev/null +++ b/src/gallium/drivers/i915/i915_query.h @@ -0,0 +1,36 @@ +/************************************************************************** + * + * Copyright 2011 The Chromium OS authors. + * 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 GOOGLE 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. + * + **************************************************************************/ + +#ifndef I915_QUERY_H +#define I915_QUERY_H + +struct i915_context; +struct pipe_context; + +void i915_init_query_functions( struct i915_context *i915 ); + +#endif /* I915_QUERY_H */ diff --git a/src/gallium/drivers/i915/i915_reg.h b/src/gallium/drivers/i915/i915_reg.h index 6fe032cdb6e..14e786d0f2a 100644 --- a/src/gallium/drivers/i915/i915_reg.h +++ b/src/gallium/drivers/i915/i915_reg.h @@ -170,6 +170,13 @@ #define COLOR_BUF_RGB555 (1<<8) #define COLOR_BUF_RGB565 (2<<8) #define COLOR_BUF_ARGB8888 (3<<8) +#define COLOR_BUF_YCRCB_SWAP (4<<8) +#define COLOR_BUF_YCRCB_NORMAL (5<<8) +#define COLOR_BUF_YCRCB_SWAPUV (6<<8) +#define COLOR_BUF_YCRCB_SWAPUVY (7<<8) +#define COLOR_BUF_ARGB4444 (8<<8) +#define COLOR_BUF_ARGB1555 (9<<8) +#define COLOR_BUF_ARGB2101010 (10<<8) #define DEPTH_FRMT_16_FIXED 0 #define DEPTH_FRMT_16_FLOAT (1<<2) #define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) diff --git a/src/gallium/drivers/i915/i915_resource.c b/src/gallium/drivers/i915/i915_resource.c index 7f52ba11d61..b4719af1fb6 100644 --- a/src/gallium/drivers/i915/i915_resource.c +++ b/src/gallium/drivers/i915/i915_resource.c @@ -7,12 +7,12 @@ static struct pipe_resource * i915_resource_create(struct pipe_screen *screen, - const struct pipe_resource *template) + const struct pipe_resource *template) { if (template->target == PIPE_BUFFER) return i915_buffer_create(screen, template); else - return i915_texture_create(screen, template); + return i915_texture_create(screen, template, FALSE); } diff --git a/src/gallium/drivers/i915/i915_resource.h b/src/gallium/drivers/i915/i915_resource.h index c15ecdfc22a..14eed2c4a79 100644 --- a/src/gallium/drivers/i915/i915_resource.h +++ b/src/gallium/drivers/i915/i915_resource.h @@ -45,6 +45,15 @@ struct i915_buffer { boolean free_on_destroy; }; + +/* Texture transfer. */ +struct i915_transfer { + /* Base class. */ + struct pipe_transfer b; + struct pipe_resource *staging_texture; +}; + + #define I915_MAX_TEXTURE_2D_LEVELS 12 /* max 2048x2048 */ #define I915_MAX_TEXTURE_3D_LEVELS 9 /* max 256x256x256 */ @@ -101,7 +110,8 @@ static INLINE struct i915_buffer *i915_buffer(struct pipe_resource *resource) struct pipe_resource * i915_texture_create(struct pipe_screen *screen, - const struct pipe_resource *template); + const struct pipe_resource *template, + boolean force_untiled); struct pipe_resource * i915_texture_from_handle(struct pipe_screen * screen, diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c index b74b19d0fe4..0b6424f8d16 100644 --- a/src/gallium/drivers/i915/i915_resource_texture.c +++ b/src/gallium/drivers/i915/i915_resource_texture.c @@ -37,6 +37,7 @@ #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_rect.h" #include "i915_context.h" #include "i915_resource.h" @@ -710,7 +711,7 @@ i915_texture_destroy(struct pipe_screen *screen, FREE(tex); } -static struct pipe_transfer * +static struct pipe_transfer * i915_texture_get_transfer(struct pipe_context *pipe, struct pipe_resource *resource, unsigned level, @@ -719,19 +720,45 @@ i915_texture_get_transfer(struct pipe_context *pipe, { struct i915_context *i915 = i915_context(pipe); struct i915_texture *tex = i915_texture(resource); - struct pipe_transfer *transfer = util_slab_alloc(&i915->transfer_pool); + struct i915_transfer *transfer = util_slab_alloc(&i915->texture_transfer_pool); + boolean use_staging_texture = FALSE; if (transfer == NULL) return NULL; - transfer->resource = resource; - transfer->level = level; - transfer->usage = usage; - transfer->box = *box; - transfer->stride = tex->stride; - /* FIXME: layer_stride */ + transfer->b.resource = resource; + transfer->b.level = level; + transfer->b.usage = usage; + transfer->b.box = *box; + transfer->b.stride = tex->stride; + transfer->staging_texture = NULL; + /* XXX: handle depth textures everyhwere*/ + transfer->b.layer_stride = 0; + transfer->b.data = NULL; + + /* if we use staging transfers, only support textures we can render to, + * because we need that for u_blitter */ + if (i915->blitter && + i915_is_format_supported(NULL, /* screen */ + transfer->b.resource->format, + 0, /* target */ + 1, /* sample count */ + PIPE_BIND_RENDER_TARGET) && + (usage & PIPE_TRANSFER_WRITE) && + !(usage & (PIPE_TRANSFER_READ | PIPE_TRANSFER_DONTBLOCK | PIPE_TRANSFER_UNSYNCHRONIZED))) + use_staging_texture = TRUE; + + use_staging_texture = FALSE; + + if (use_staging_texture) { + /* + * Allocate the untiled staging texture. + * If the alloc fails, transfer->staging_texture is NULL and we fallback to a map() + */ + transfer->staging_texture = i915_texture_create(pipe->screen, resource, TRUE); + } - return transfer; + return (struct pipe_transfer*)transfer; } static void @@ -739,17 +766,33 @@ i915_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *transfer) { struct i915_context *i915 = i915_context(pipe); - util_slab_free(&i915->transfer_pool, transfer); + struct i915_transfer *itransfer = (struct i915_transfer*)transfer; + + if ((itransfer->staging_texture) && + (transfer->usage & PIPE_TRANSFER_WRITE)) { + struct pipe_box sbox; + + u_box_origin_2d(itransfer->b.box.width, itransfer->b.box.height, &sbox); + pipe->resource_copy_region(pipe, itransfer->b.resource, itransfer->b.level, + itransfer->b.box.x, itransfer->b.box.y, itransfer->b.box.z, + itransfer->staging_texture, + 0, &sbox); + pipe->flush(pipe, NULL); + pipe_resource_reference(&itransfer->staging_texture, NULL); + } + + util_slab_free(&i915->texture_transfer_pool, itransfer); } static void * i915_texture_transfer_map(struct pipe_context *pipe, struct pipe_transfer *transfer) { - struct pipe_resource *resource = transfer->resource; - struct i915_texture *tex = i915_texture(resource); + struct i915_transfer *itransfer = (struct i915_transfer*)transfer; + struct pipe_resource *resource = itransfer->b.resource; + struct i915_texture *tex = NULL; struct i915_winsys *iws = i915_screen(pipe->screen)->iws; - struct pipe_box *box = &transfer->box; + struct pipe_box *box = &itransfer->b.box; enum pipe_format format = resource->format; unsigned offset; char *map; @@ -757,18 +800,25 @@ i915_texture_transfer_map(struct pipe_context *pipe, if (resource->target != PIPE_TEXTURE_3D && resource->target != PIPE_TEXTURE_CUBE) assert(box->z == 0); - offset = i915_texture_offset(tex, transfer->level, box->z); - /* TODO this is a sledgehammer */ - pipe->flush(pipe, NULL); + if (itransfer->staging_texture) { + tex = i915_texture(itransfer->staging_texture); + } else { + /* TODO this is a sledgehammer */ + tex = i915_texture(resource); + pipe->flush(pipe, NULL); + } + + offset = i915_texture_offset(tex, itransfer->b.level, box->z); map = iws->buffer_map(iws, tex->buffer, - (transfer->usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE); - if (map == NULL) + (itransfer->b.usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE); + if (map == NULL) { return NULL; + } return map + offset + - box->y / util_format_get_blockheight(format) * transfer->stride + + box->y / util_format_get_blockheight(format) * itransfer->b.stride + box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); } @@ -776,14 +826,106 @@ static void i915_texture_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *transfer) { - struct i915_texture *tex = i915_texture(transfer->resource); + struct i915_transfer *itransfer = (struct i915_transfer*)transfer; + struct i915_texture *tex = i915_texture(itransfer->b.resource); struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws; + + if (itransfer->staging_texture) + tex = i915_texture(itransfer->staging_texture); + iws->buffer_unmap(iws, tex->buffer); } +static void i915_transfer_inline_write( struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned layer_stride) +{ + struct pipe_transfer *transfer = NULL; + struct i915_transfer *itransfer = NULL; + const uint8_t *src_data = data; + unsigned i; + + transfer = pipe->get_transfer(pipe, + resource, + level, + usage, + box ); + if (transfer == NULL) + goto out; + + itransfer = (struct i915_transfer*)transfer; + + if (itransfer->staging_texture) { + struct i915_texture *tex = i915_texture(itransfer->staging_texture); + enum pipe_format format = tex->b.b.format; + struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws; + size_t offset; + size_t size; + + offset = i915_texture_offset(tex, transfer->level, transfer->box.z); + + for (i = 0; i < box->depth; i++) { + if (!tex->b.b.last_level && + tex->b.b.width0 == transfer->box.width) { + unsigned nby = util_format_get_nblocksy(format, transfer->box.y); + assert(!offset); + assert(!transfer->box.x); + assert(tex->stride == transfer->stride); + + offset += tex->stride * nby; + size = util_format_get_2d_size(format, transfer->stride, + transfer->box.height); + iws->buffer_write(iws, tex->buffer, offset, size, transfer->data); + + } else { + unsigned nby = util_format_get_nblocksy(format, transfer->box.y); + int i; + offset += util_format_get_stride(format, transfer->box.x); + size = transfer->stride; + + for (i = 0; i < nby; i++) { + iws->buffer_write(iws, tex->buffer, offset, size, transfer->data); + offset += tex->stride; + } + } + offset += layer_stride; + } + } else { + uint8_t *map = pipe_transfer_map(pipe, &itransfer->b); + if (map == NULL) + goto nomap; + + for (i = 0; i < box->depth; i++) { + util_copy_rect(map, + resource->format, + itransfer->b.stride, /* bytes */ + 0, 0, + box->width, + box->height, + src_data, + stride, /* bytes */ + 0, 0); + map += itransfer->b.layer_stride; + src_data += layer_stride; + } +nomap: + if (map) + pipe_transfer_unmap(pipe, &itransfer->b); + } + +out: + if (itransfer) + pipe_transfer_destroy(pipe, &itransfer->b); +} -struct u_resource_vtbl i915_texture_vtbl = + +struct u_resource_vtbl i915_texture_vtbl = { i915_texture_get_handle, /* get_handle */ i915_texture_destroy, /* resource_destroy */ @@ -792,7 +934,7 @@ struct u_resource_vtbl i915_texture_vtbl = i915_texture_transfer_map, /* transfer_map */ u_default_transfer_flush_region, /* transfer_flush_region */ i915_texture_transfer_unmap, /* transfer_unmap */ - u_default_transfer_inline_write /* transfer_inline_write */ + i915_transfer_inline_write /* transfer_inline_write */ }; @@ -800,7 +942,8 @@ struct u_resource_vtbl i915_texture_vtbl = struct pipe_resource * i915_texture_create(struct pipe_screen *screen, - const struct pipe_resource *template) + const struct pipe_resource *template, + boolean force_untiled) { struct i915_screen *is = i915_screen(screen); struct i915_winsys *iws = is->iws; @@ -815,7 +958,10 @@ i915_texture_create(struct pipe_screen *screen, pipe_reference_init(&tex->b.b.reference, 1); tex->b.b.screen = screen; - tex->tiling = i915_texture_tiling(is, tex); + if (force_untiled) + tex->tiling = I915_TILE_NONE; + else + tex->tiling = i915_texture_tiling(is, tex); if (is->is_i945) { if (!i945_texture_layout(tex)) @@ -836,7 +982,7 @@ i915_texture_create(struct pipe_screen *screen, buf_usage = I915_NEW_TEXTURE; tex->buffer = iws->buffer_create_tiled(iws, &tex->stride, tex->total_nblocksy, - &tex->tiling, buf_usage); + &tex->tiling, buf_usage); if (!tex->buffer) goto fail; diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index c86baa58b28..e743f6031eb 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -109,17 +109,17 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) case PIPE_CAP_ANISOTROPIC_FILTER: case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: case PIPE_CAP_NPOT_TEXTURES: + case PIPE_CAP_POINT_SPRITE: case PIPE_CAP_PRIMITIVE_RESTART: /* draw module */ case PIPE_CAP_TEXTURE_MIRROR_REPEAT: case PIPE_CAP_TEXTURE_SHADOW_MAP: case PIPE_CAP_TWO_SIDED_STENCIL: + case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: return 1; /* Features that should be supported (boolean caps). */ /* XXX: Just test the code */ case PIPE_CAP_BLEND_EQUATION_SEPARATE: - /* XXX: No code but hw supports it */ - case PIPE_CAP_POINT_SPRITE: /* Also lie about these when asked to (needed for GLSL / GL 2.0) */ return is->debug.lie ? 1 : 0; @@ -129,7 +129,6 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) case PIPE_CAP_INDEP_BLEND_ENABLE: case PIPE_CAP_INDEP_BLEND_FUNC: case PIPE_CAP_TGSI_INSTANCEID: - case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: case PIPE_CAP_SHADER_STENCIL_EXPORT: case PIPE_CAP_TEXTURE_MIRROR_CLAMP: case PIPE_CAP_TEXTURE_SWIZZLE: @@ -254,7 +253,7 @@ i915_get_paramf(struct pipe_screen *screen, enum pipe_cap cap) } } -static boolean +boolean i915_is_format_supported(struct pipe_screen *screen, enum pipe_format format, enum pipe_texture_target target, @@ -264,7 +263,10 @@ i915_is_format_supported(struct pipe_screen *screen, static const enum pipe_format tex_supported[] = { PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_B8G8R8X8_UNORM, + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_R8G8B8X8_UNORM, PIPE_FORMAT_B5G6R5_UNORM, + PIPE_FORMAT_B10G10R10A2_UNORM, PIPE_FORMAT_L8_UNORM, PIPE_FORMAT_A8_UNORM, PIPE_FORMAT_I8_UNORM, @@ -283,7 +285,12 @@ i915_is_format_supported(struct pipe_screen *screen, }; static const enum pipe_format render_supported[] = { PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_R8G8B8A8_UNORM, PIPE_FORMAT_B5G6R5_UNORM, + PIPE_FORMAT_B10G10R10A2_UNORM, + PIPE_FORMAT_L8_UNORM, + PIPE_FORMAT_A8_UNORM, + PIPE_FORMAT_I8_UNORM, PIPE_FORMAT_NONE /* list terminator */ }; static const enum pipe_format depth_supported[] = { diff --git a/src/gallium/drivers/i915/i915_screen.h b/src/gallium/drivers/i915/i915_screen.h index cfc585b5350..9f2004eb942 100644 --- a/src/gallium/drivers/i915/i915_screen.h +++ b/src/gallium/drivers/i915/i915_screen.h @@ -65,5 +65,11 @@ i915_screen(struct pipe_screen *pscreen) return (struct i915_screen *) pscreen; } +boolean +i915_is_format_supported(struct pipe_screen *screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned sample_count, + unsigned tex_usage); #endif /* I915_SCREEN_H */ diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 1b57c5776f2..f412626955d 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -146,6 +146,7 @@ i915_create_blend_state(struct pipe_context *pipe, if (blend->dither) cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE; + /* XXX here take the target fixup into account */ if ((blend->rt[0].colormask & PIPE_MASK_R) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_RED; @@ -246,7 +247,7 @@ i915_create_sampler_state(struct pipe_context *pipe, if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { cso->state[0] |= (SS2_SHADOW_ENABLE | - i915_translate_compare_func(sampler->compare_func)); + i915_translate_shadow_compare_func(sampler->compare_func)); minFilt = FILTER_4X4_FLAT; magFilt = FILTER_4X4_FLAT; @@ -466,6 +467,7 @@ i915_create_fs_state(struct pipe_context *pipe, if (!ifs) return NULL; + ifs->draw_data = draw_create_fragment_shader(i915->draw, templ); ifs->state.tokens = tgsi_dup_tokens(templ->tokens); tgsi_scan_shader(templ->tokens, &ifs->info); @@ -495,6 +497,8 @@ i915_bind_fs_state(struct pipe_context *pipe, void *shader) i915->fs = (struct i915_fragment_shader*) shader; + draw_bind_fragment_shader(i915->draw, (i915->fs ? i915->fs->draw_data : NULL)); + i915->dirty |= I915_NEW_FS; } @@ -503,12 +507,14 @@ void i915_delete_fs_state(struct pipe_context *pipe, void *shader) { struct i915_fragment_shader *ifs = (struct i915_fragment_shader *) shader; - if (ifs->program) + if (ifs->program) { FREE(ifs->program); + ifs->program = NULL; + FREE((struct tgsi_token *)ifs->state.tokens); + ifs->state.tokens = NULL; + } ifs->program_len = 0; - FREE((struct tgsi_token *)ifs->state.tokens); - FREE(ifs); } diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c index bf6b30a4530..e01f16e715c 100644 --- a/src/gallium/drivers/i915/i915_state_derived.c +++ b/src/gallium/drivers/i915/i915_state_derived.c @@ -33,9 +33,10 @@ #include "i915_context.h" #include "i915_state.h" #include "i915_debug.h" +#include "i915_fpc.h" #include "i915_reg.h" -static uint find_mapping(struct i915_fragment_shader* fs, int unit) +static uint find_mapping(const struct i915_fragment_shader* fs, int unit) { int i; for (i = 0; i < I915_TEX_UNITS ; i++) @@ -58,12 +59,12 @@ static void calculate_vertex_layout(struct i915_context *i915) const struct i915_fragment_shader *fs = i915->fs; const enum interp_mode colorInterp = i915->rasterizer->color_interp; struct vertex_info vinfo; - boolean texCoords[I915_TEX_UNITS], colors[2], fog, needW; + boolean texCoords[I915_TEX_UNITS], colors[2], fog, needW, face; uint i; int src; memset(texCoords, 0, sizeof(texCoords)); - colors[0] = colors[1] = fog = needW = FALSE; + colors[0] = colors[1] = fog = needW = face = FALSE; memset(&vinfo, 0, sizeof(vinfo)); /* Determine which fragment program inputs are needed. Setup HW vertex @@ -72,6 +73,10 @@ static void calculate_vertex_layout(struct i915_context *i915) for (i = 0; i < fs->info.num_inputs; i++) { switch (fs->info.input_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: + { + uint unit = I915_SEMANTIC_POS; + texCoords[find_mapping(fs, unit)] = TRUE; + } break; case TGSI_SEMANTIC_COLOR: assert(fs->info.input_semantic_index[i] < 2); @@ -80,7 +85,6 @@ static void calculate_vertex_layout(struct i915_context *i915) case TGSI_SEMANTIC_GENERIC: { /* texcoords/varyings/other generic */ - /* XXX handle back/front face and point size */ uint unit = fs->info.input_semantic_index[i]; texCoords[find_mapping(fs, unit)] = TRUE; @@ -90,7 +94,11 @@ static void calculate_vertex_layout(struct i915_context *i915) case TGSI_SEMANTIC_FOG: fog = TRUE; break; + case TGSI_SEMANTIC_FACE: + face = TRUE; + break; default: + debug_printf("Unknown input type %d\n", fs->info.input_semantic_name[i]); assert(0); } } @@ -147,6 +155,20 @@ static void calculate_vertex_layout(struct i915_context *i915) vinfo.hwfmt[1] |= hwtc << (i * 4); } + /* front/back face */ + if (face) { + uint slot = find_mapping(fs, I915_SEMANTIC_FACE); + debug_printf("Front/back face is broken\n"); + /* XXX Because of limitations in the draw module, currently src will be 0 + * for SEMANTIC_FACE, so this aliases to POS. We need to fix in the draw + * module by adding an extra shader output. + */ + src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FACE, 0); + draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_CONSTANT, src); + vinfo.hwfmt[1] &= ~(TEXCOORDFMT_NOT_PRESENT << (slot * 4)); + vinfo.hwfmt[1] |= TEXCOORDFMT_1D << (slot * 4); + } + draw_compute_vertex_size(&vinfo); if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) { diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index 0155cd83510..39fb13aec7e 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -34,7 +34,9 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" +#include "pipe/p_format.h" +#include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -128,7 +130,7 @@ validate_immediate(struct i915_context *i915, unsigned *batch_space) static void emit_immediate(struct i915_context *i915) { - /* remove unwatned bits and S7 */ + /* remove unwanted bits and S7 */ unsigned dirty = (1 << I915_IMMEDIATE_S0 | 1 << I915_IMMEDIATE_S1 | 1 << I915_IMMEDIATE_S2 | 1 << I915_IMMEDIATE_S3 | 1 << I915_IMMEDIATE_S3 | 1 << I915_IMMEDIATE_S4 | @@ -341,6 +343,59 @@ emit_constants(struct i915_context *i915) } } +static const struct +{ + enum pipe_format format; + uint hw_shift_R; + uint hw_shift_G; + uint hw_shift_B; + uint hw_shift_A; +} fixup_formats[] = { + { PIPE_FORMAT_R8G8B8A8_UNORM, 20, 24, 28, 16 /* BGRA */}, + { PIPE_FORMAT_L8_UNORM, 28, 28, 28, 16 /* RRRA */}, + { PIPE_FORMAT_I8_UNORM, 28, 28, 28, 16 /* RRRA */}, + { PIPE_FORMAT_A8_UNORM, 16, 16, 16, 16 /* AAAA */}, + { PIPE_FORMAT_NONE, 0, 0, 0, 0}, +}; + +static boolean need_fixup(struct pipe_surface* p) +{ + enum pipe_format f; + + /* if we don't have a surface bound yet, we don't need to fixup the shader */ + if (!p) + return FALSE; + + f = p->format; + for(int i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++) + if (fixup_formats[i].format == f) + return TRUE; + + return FALSE; +} + +static uint fixup_swizzle(enum pipe_format f, uint v) +{ + int i; + + for(i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++) + if (fixup_formats[i].format == f) + break; + + if (fixup_formats[i].format == PIPE_FORMAT_NONE) + return v; + + uint rgba = v & 0xFFFF0000; + + v &= 0xFFFF; + v |= ((rgba >> fixup_formats[i].hw_shift_R) & 0xF) << 28; + v |= ((rgba >> fixup_formats[i].hw_shift_G) & 0xF) << 24; + v |= ((rgba >> fixup_formats[i].hw_shift_B) & 0xF) << 20; + v |= ((rgba >> fixup_formats[i].hw_shift_A) & 0xF) << 16; + + return v; +} + static void validate_program(struct i915_context *i915, unsigned *batch_space) { @@ -350,12 +405,39 @@ validate_program(struct i915_context *i915, unsigned *batch_space) static void emit_program(struct i915_context *i915) { - uint i; - /* we should always have, at least, a pass-through program */ - assert(i915->fs->program_len > 0); - for (i = 0; i < i915->fs->program_len; i++) { - OUT_BATCH(i915->fs->program[i]); + struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; + boolean need_format_fixup = need_fixup(cbuf_surface); + int i; + int fixup_offset = -1; + + /* we should always have, at least, a pass-through program */ + assert(i915->fs->program_len > 0); + + if (need_format_fixup) { + /* Find where we emit the output color */ + for (i = i915->fs->program_len - 3; i>0; i-=3) { + uint instr = i915->fs->program[i]; + if ((instr & (REG_NR_MASK << A0_DEST_TYPE_SHIFT)) == + (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) ) { + /* Found it! */ + fixup_offset = i + 1; + break; + } + } + if (fixup_offset == -1) { + need_format_fixup = FALSE; + debug_printf("couldn't find fixup offset\n"); } + } + + /* emit the program to the hw */ + for (i = 0; i < i915->fs->program_len; i++) { + if (need_format_fixup && (i == fixup_offset) ) { + uint v = fixup_swizzle(cbuf_surface->format, i915->fs->program[i]); + OUT_BATCH(v); + } else + OUT_BATCH(i915->fs->program[i]); + } } static void diff --git a/src/gallium/drivers/i915/i915_state_inlines.h b/src/gallium/drivers/i915/i915_state_inlines.h index b589117fbfe..aa992f75c51 100644 --- a/src/gallium/drivers/i915/i915_state_inlines.h +++ b/src/gallium/drivers/i915/i915_state_inlines.h @@ -60,6 +60,31 @@ i915_translate_compare_func(unsigned func) } static INLINE unsigned +i915_translate_shadow_compare_func(unsigned func) +{ + switch (func) { + case PIPE_FUNC_NEVER: + return COMPAREFUNC_ALWAYS; + case PIPE_FUNC_LESS: + return COMPAREFUNC_LEQUAL; + case PIPE_FUNC_LEQUAL: + return COMPAREFUNC_LESS; + case PIPE_FUNC_GREATER: + return COMPAREFUNC_GEQUAL; + case PIPE_FUNC_GEQUAL: + return COMPAREFUNC_GREATER; + case PIPE_FUNC_NOTEQUAL: + return COMPAREFUNC_EQUAL; + case PIPE_FUNC_EQUAL: + return COMPAREFUNC_NOTEQUAL; + case PIPE_FUNC_ALWAYS: + return COMPAREFUNC_NEVER; + default: + return COMPAREFUNC_NEVER; + } +} + +static INLINE unsigned i915_translate_stencil_op(unsigned op) { switch (op) { diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c index be70e7a92c9..0103f7c3530 100644 --- a/src/gallium/drivers/i915/i915_state_sampler.c +++ b/src/gallium/drivers/i915/i915_state_sampler.c @@ -62,6 +62,7 @@ static void update_map(struct i915_context *i915, uint unit, const struct i915_texture *tex, const struct i915_sampler_state *sampler, + const struct pipe_sampler_view* view, uint state[2]); @@ -161,9 +162,10 @@ static void update_samplers(struct i915_context *i915) i915->current.sampler[unit]); /* the result */ update_map(i915, unit, - texture, /* texture */ - i915->sampler[unit], /* sampler state */ - i915->current.texbuffer[unit]); /* the result */ + texture, /* texture */ + i915->sampler[unit], /* sampler state */ + i915->fragment_sampler_views[unit], /* sampler view */ + i915->current.texbuffer[unit]); /* the result */ i915->current.sampler_enable_nr++; i915->current.sampler_enable_flags |= (1 << unit); @@ -180,13 +182,21 @@ struct i915_tracked_state i915_hw_samplers = { }; - /*********************************************************************** * Sampler views */ -static uint translate_texture_format(enum pipe_format pipeFormat) +static uint translate_texture_format(enum pipe_format pipeFormat, + const struct pipe_sampler_view* view) { + if ( (view->swizzle_r != PIPE_SWIZZLE_RED || + view->swizzle_g != PIPE_SWIZZLE_GREEN || + view->swizzle_b != PIPE_SWIZZLE_BLUE || + view->swizzle_a != PIPE_SWIZZLE_ALPHA ) && + pipeFormat != PIPE_FORMAT_Z24_UNORM_S8_USCALED && + pipeFormat != PIPE_FORMAT_Z24X8_UNORM ) + debug_printf("i915: unsupported texture swizzle for format %d\n", pipeFormat); + switch (pipeFormat) { case PIPE_FORMAT_L8_UNORM: return MAPSURF_8BIT | MT_8BIT_L8; @@ -202,16 +212,16 @@ static uint translate_texture_format(enum pipe_format pipeFormat) return MAPSURF_16BIT | MT_16BIT_ARGB1555; case PIPE_FORMAT_B4G4R4A4_UNORM: return MAPSURF_16BIT | MT_16BIT_ARGB4444; + case PIPE_FORMAT_B10G10R10A2_UNORM: + return MAPSURF_32BIT | MT_32BIT_ARGB2101010; case PIPE_FORMAT_B8G8R8A8_UNORM: return MAPSURF_32BIT | MT_32BIT_ARGB8888; case PIPE_FORMAT_B8G8R8X8_UNORM: return MAPSURF_32BIT | MT_32BIT_XRGB8888; case PIPE_FORMAT_R8G8B8A8_UNORM: return MAPSURF_32BIT | MT_32BIT_ABGR8888; -#if 0 case PIPE_FORMAT_R8G8B8X8_UNORM: return MAPSURF_32BIT | MT_32BIT_XBGR8888; -#endif case PIPE_FORMAT_YUYV: return (MAPSURF_422 | MT_422_YCRCB_NORMAL); case PIPE_FORMAT_UYVY: @@ -232,7 +242,25 @@ static uint translate_texture_format(enum pipe_format pipeFormat) return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); case PIPE_FORMAT_Z24_UNORM_S8_USCALED: case PIPE_FORMAT_Z24X8_UNORM: - return (MAPSURF_32BIT | MT_32BIT_xI824); + { + if ( view->swizzle_r == PIPE_SWIZZLE_RED && + view->swizzle_g == PIPE_SWIZZLE_RED && + view->swizzle_b == PIPE_SWIZZLE_RED && + view->swizzle_a == PIPE_SWIZZLE_ONE) + return (MAPSURF_32BIT | MT_32BIT_xA824); + if ( view->swizzle_r == PIPE_SWIZZLE_RED && + view->swizzle_g == PIPE_SWIZZLE_RED && + view->swizzle_b == PIPE_SWIZZLE_RED && + view->swizzle_a == PIPE_SWIZZLE_RED) + return (MAPSURF_32BIT | MT_32BIT_xI824); + if ( view->swizzle_r == PIPE_SWIZZLE_ZERO && + view->swizzle_g == PIPE_SWIZZLE_ZERO && + view->swizzle_b == PIPE_SWIZZLE_ZERO && + view->swizzle_a == PIPE_SWIZZLE_RED) + return (MAPSURF_32BIT | MT_32BIT_xL824); + debug_printf("i915: unsupported depth swizzle\n"); + return (MAPSURF_32BIT | MT_32BIT_xL824); + } default: debug_printf("i915: translate_texture_format() bad image format %x\n", pipeFormat); @@ -262,6 +290,7 @@ static void update_map(struct i915_context *i915, uint unit, const struct i915_texture *tex, const struct i915_sampler_state *sampler, + const struct pipe_sampler_view* view, uint state[2]) { const struct pipe_resource *pt = &tex->b.b; @@ -275,7 +304,7 @@ static void update_map(struct i915_context *i915, assert(height); assert(depth); - format = translate_texture_format(pt->format); + format = translate_texture_format(pt->format, view); pitch = tex->stride; assert(format); @@ -318,8 +347,9 @@ static void update_maps(struct i915_context *i915) update_map(i915, unit, - texture, /* texture */ - i915->sampler[unit], /* sampler state */ + texture, /* texture */ + i915->sampler[unit], /* sampler state */ + i915->fragment_sampler_views[unit], /* sampler view */ i915->current.texbuffer[unit]); } } diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c index 2865298318c..0e4000bc2ab 100644 --- a/src/gallium/drivers/i915/i915_state_static.c +++ b/src/gallium/drivers/i915/i915_state_static.c @@ -42,6 +42,18 @@ static unsigned translate_format(enum pipe_format format) return COLOR_BUF_ARGB8888; case PIPE_FORMAT_B5G6R5_UNORM: return COLOR_BUF_RGB565; + case PIPE_FORMAT_B5G5R5A1_UNORM: + return COLOR_BUF_ARGB1555; + case PIPE_FORMAT_R8G8B8A8_UNORM: + return COLOR_BUF_ARGB8888; + case PIPE_FORMAT_B4G4R4A4_UNORM: + return COLOR_BUF_ARGB4444; + case PIPE_FORMAT_B10G10R10A2_UNORM: + return COLOR_BUF_ARGB2101010; + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_I8_UNORM: + return COLOR_BUF_8BIT; default: assert(0); return 0; @@ -137,7 +149,8 @@ static void update_framebuffer(struct i915_context *i915) i915->static_dirty |= I915_DST_RECT; } - i915->hardware_dirty |= I915_HW_STATIC; + /* we also send a new program to make sure the fixup for RGBA surfaces happens */ + i915->hardware_dirty |= I915_HW_STATIC | I915_HW_PROGRAM; /* flush the cache in case we sample from the old renderbuffers */ i915_set_flush_dirty(i915, I915_FLUSH_CACHE); diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index c10a8cbc12c..d6b20ceb5ce 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -79,7 +79,7 @@ llvmpipe = env.ConvenienceLibrary( env.Alias('llvmpipe', llvmpipe) -if env['platform'] != 'embedded': +if not env['embedded']: env = env.Clone() env.Prepend(LIBS = [llvmpipe] + gallium) diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 036a6e0c379..4b2ae1436ea 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -423,7 +423,7 @@ llvmpipe_create_screen(struct sw_winsys *winsys) lp_jit_screen_init(screen); screen->num_threads = util_cpu_caps.nr_cpus > 1 ? util_cpu_caps.nr_cpus : 0; -#ifdef PIPE_OS_EMBEDDED +#ifdef PIPE_SUBSYSTEM_EMBEDDED screen->num_threads = 0; #endif screen->num_threads = debug_get_num_option("LP_NUM_THREADS", screen->num_threads); diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.py b/src/gallium/drivers/llvmpipe/lp_tile_soa.py index 8df7b236fe0..f4324e69971 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_soa.py +++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.py @@ -423,6 +423,70 @@ lp_tile_b8g8r8a8_unorm_unswizzle_4ub_sse2(const uint8_t * restrict src, } } +static void +lp_tile_b8g8r8x8_unorm_swizzle_4ub_sse2(uint8_t * restrict dst, + const uint8_t * restrict src, unsigned src_stride, + unsigned x0, unsigned y0) +{ + __m128i *dst128 = (__m128i *) dst; + unsigned x, y; + + src += y0 * src_stride; + src += x0 * sizeof(uint32_t); + + for (y = 0; y < TILE_SIZE; y += 4) { + const uint8_t *src_row = src; + + for (x = 0; x < TILE_SIZE; x += 4) { + swz4((const __m128i *) (src_row + 0 * src_stride), + (const __m128i *) (src_row + 1 * src_stride), + (const __m128i *) (src_row + 2 * src_stride), + (const __m128i *) (src_row + 3 * src_stride), + dst128 + 2, /* b */ + dst128 + 1, /* g */ + dst128 + 0, /* r */ + dst128 + 3); /* a */ + + dst128 += 4; + src_row += sizeof(__m128i); + } + + src += 4 * src_stride; + } +} + +static void +lp_tile_b8g8r8x8_unorm_unswizzle_4ub_sse2(const uint8_t * restrict src, + uint8_t * restrict dst, unsigned dst_stride, + unsigned x0, unsigned y0) +{ + unsigned int x, y; + const __m128i *src128 = (const __m128i *) src; + + dst += y0 * dst_stride; + dst += x0 * sizeof(uint32_t); + + for (y = 0; y < TILE_SIZE; y += 4) { + const uint8_t *dst_row = dst; + + for (x = 0; x < TILE_SIZE; x += 4) { + unswz4( &src128[2], /* b */ + &src128[1], /* g */ + &src128[0], /* r */ + &src128[3], /* a */ + (__m128i *) (dst_row + 0 * dst_stride), + (__m128i *) (dst_row + 1 * dst_stride), + (__m128i *) (dst_row + 2 * dst_stride), + (__m128i *) (dst_row + 3 * dst_stride)); + + src128 += 4; + dst_row += sizeof(__m128i);; + } + + dst += 4 * dst_stride; + } +} + #endif /* PIPE_ARCH_SSE */ ''' @@ -446,7 +510,7 @@ def generate_swizzle(formats, dst_channel, dst_native_type, dst_suffix): if is_format_supported(format): print ' case %s:' % format.name func_name = 'lp_tile_%s_swizzle_%s' % (format.short_name(), dst_suffix) - if format.name == 'PIPE_FORMAT_B8G8R8A8_UNORM': + if format.name == 'PIPE_FORMAT_B8G8R8A8_UNORM' or format.name == 'PIPE_FORMAT_B8G8R8X8_UNORM': print '#ifdef PIPE_ARCH_SSE' print ' func = util_cpu_caps.has_sse2 ? %s_sse2 : %s;' % (func_name, func_name) print '#else' @@ -484,7 +548,7 @@ def generate_unswizzle(formats, src_channel, src_native_type, src_suffix): if is_format_supported(format): print ' case %s:' % format.name func_name = 'lp_tile_%s_unswizzle_%s' % (format.short_name(), src_suffix) - if format.name == 'PIPE_FORMAT_B8G8R8A8_UNORM': + if format.name == 'PIPE_FORMAT_B8G8R8A8_UNORM' or format.name == 'PIPE_FORMAT_B8G8R8X8_UNORM': print '#ifdef PIPE_ARCH_SSE' print ' func = util_cpu_caps.has_sse2 ? %s_sse2 : %s;' % (func_name, func_name) print '#else' diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index 401155bba6e..223e7682ccd 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -81,20 +81,6 @@ nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment, return bo; } -struct nouveau_bo * -nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes) -{ - struct nouveau_device *dev = nouveau_screen(pscreen)->device; - struct nouveau_bo *bo = NULL; - int ret; - - ret = nouveau_bo_user(dev, ptr, bytes, &bo); - if (ret) - return NULL; - - return bo; -} - void * nouveau_screen_bo_map(struct pipe_screen *pscreen, struct nouveau_bo *bo, diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index 186ada39677..d910809a0ec 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -47,8 +47,6 @@ nouveau_screen(struct pipe_screen *pscreen) struct nouveau_bo * nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment, unsigned usage, unsigned bind, unsigned size); -struct nouveau_bo * -nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes); void * nouveau_screen_bo_map(struct pipe_screen *pscreen, struct nouveau_bo *pb, diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 632ca4daf74..ceb83f6e684 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -168,6 +168,7 @@ nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx, if (!resource->bo) return; + nv50->residents_size += sizeof(struct resident); /* We don't need to reference the resource here, it will be referenced * in the context/state, and bufctx will be reset when state changes. @@ -189,6 +190,7 @@ nv50_bufctx_del_resident(struct nv50_context *nv50, int ctx, top = util_dynarray_pop_ptr(&nv50->residents[ctx], struct resident); if (rsd != top) *rsd = *top; + nv50->residents_size -= sizeof(struct resident); break; } } @@ -201,11 +203,15 @@ nv50_bufctx_emit_relocs(struct nv50_context *nv50) struct util_dynarray *array; unsigned ctx, i, n; + n = nv50->residents_size / sizeof(struct resident); + n += NV50_SCREEN_RESIDENT_BO_COUNT; + + MARK_RING(nv50->screen->base.channel, n, n); + for (ctx = 0; ctx < NV50_BUFCTX_COUNT; ++ctx) { array = &nv50->residents[ctx]; n = array->size / sizeof(struct resident); - MARK_RING(nv50->screen->base.channel, n, n); for (i = 0; i < n; ++i) { rsd = util_dynarray_element(array, struct resident, i); diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 3f031994f0a..b4af24f6bce 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -64,6 +64,7 @@ struct nv50_context { struct nv50_screen *screen; struct util_dynarray residents[NV50_BUFCTX_COUNT]; + unsigned residents_size; uint32_t dirty; @@ -156,6 +157,7 @@ void nv50_bufctx_del_resident(struct nv50_context *, int ctx, static INLINE void nv50_bufctx_reset(struct nv50_context *nv50, int ctx) { + nv50->residents_size -= nv50->residents[ctx].size; util_dynarray_resize(&nv50->residents[ctx], 0); } diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index aea434b8679..64ad209a728 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -19,6 +19,8 @@ struct nv50_context; #define NV50_SCRATCH_SIZE (2 << 20) #define NV50_SCRATCH_NR_BUFFERS 2 +#define NV50_SCREEN_RESIDENT_BO_COUNT 5 + struct nv50_screen { struct nouveau_screen base; struct nouveau_winsys *nvws; diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index 5d3f52c38c1..e5b10c37bef 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -215,10 +215,12 @@ void nv50_gmtyprog_validate(struct nv50_context *nv50) { struct nouveau_channel *chan = nv50->screen->base.channel; - struct nv50_program *gp = nv50->vertprog; + struct nv50_program *gp = nv50->gmtyprog; + if (!gp) /* GP_ENABLE is updated in linkage validation */ + return; if (!nv50_program_validate(nv50, gp)) - return; + return; BEGIN_RING(chan, RING_3D(GP_REG_ALLOC_TEMP), 1); OUT_RING (chan, gp->max_gpr); diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index abdb9ce2f93..bb08941c243 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -404,9 +404,6 @@ nv50_draw_arrays(struct nv50_context *nv50, struct nouveau_channel *chan = nv50->screen->base.channel; unsigned prim; - chan->flush_notify = nv50_draw_vbo_flush_notify; - chan->user_private = nv50; - prim = nv50_prim_gl(mode); while (instance_count--) { @@ -420,8 +417,6 @@ nv50_draw_arrays(struct nv50_context *nv50, prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } - - chan->flush_notify = nv50_default_flush_notify; } static void @@ -523,9 +518,6 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, unsigned prim; const unsigned index_size = nv50->idxbuf.index_size; - chan->flush_notify = nv50_draw_vbo_flush_notify; - chan->user_private = nv50; - prim = nv50_prim_gl(mode); if (index_bias != nv50->state.index_bias) { @@ -631,8 +623,6 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } - - chan->flush_notify = nv50_default_flush_notify; } void @@ -659,8 +649,12 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) nv50_state_validate(nv50); + chan->flush_notify = nv50_draw_vbo_flush_notify; + chan->user_private = nv50; + if (nv50->vbo_fifo) { nv50_push_vbo(nv50, info); + chan->flush_notify = nv50_default_flush_notify; return; } @@ -712,6 +706,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) info->mode, info->start, info->count, info->instance_count, info->index_bias); } + chan->flush_notify = nv50_default_flush_notify; nv50_release_user_vbufs(nv50); } diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c index 2f2a3da7c44..2679b7f86aa 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nvc0/nvc0_context.c @@ -169,6 +169,7 @@ nvc0_bufctx_add_resident(struct nvc0_context *nvc0, int ctx, if (!resource->bo) return; + nvc0->residents_size += sizeof(struct resident); /* We don't need to reference the resource here, it will be referenced * in the context/state, and bufctx will be reset when state changes. @@ -190,6 +191,7 @@ nvc0_bufctx_del_resident(struct nvc0_context *nvc0, int ctx, top = util_dynarray_pop_ptr(&nvc0->residents[ctx], struct resident); if (rsd != top) *rsd = *top; + nvc0->residents_size -= sizeof(struct resident); break; } } @@ -202,11 +204,15 @@ nvc0_bufctx_emit_relocs(struct nvc0_context *nvc0) struct util_dynarray *array; unsigned ctx, i, n; + n = nvc0->residents_size / sizeof(struct resident); + n += NVC0_SCREEN_RESIDENT_BO_COUNT; + + MARK_RING(nvc0->screen->base.channel, n, n); + for (ctx = 0; ctx < NVC0_BUFCTX_COUNT; ++ctx) { array = &nvc0->residents[ctx]; n = array->size / sizeof(struct resident); - MARK_RING(nvc0->screen->base.channel, n, n); for (i = 0; i < n; ++i) { rsd = util_dynarray_element(array, struct resident, i); diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index f97141dd46e..b05cc337d5d 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -62,6 +62,7 @@ struct nvc0_context { struct nvc0_screen *screen; struct util_dynarray residents[NVC0_BUFCTX_COUNT]; + unsigned residents_size; uint32_t dirty; @@ -163,6 +164,7 @@ void nvc0_bufctx_del_resident(struct nvc0_context *, int ctx, static INLINE void nvc0_bufctx_reset(struct nvc0_context *nvc0, int ctx) { + nvc0->residents_size -= nvc0->residents[ctx].size; util_dynarray_resize(&nvc0->residents[ctx], 0); } diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h index 94bf0cf3481..015807e2f5d 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.h +++ b/src/gallium/drivers/nvc0/nvc0_screen.h @@ -16,6 +16,8 @@ struct nvc0_context; #define NVC0_SCRATCH_SIZE (2 << 20) #define NVC0_SCRATCH_NR_BUFFERS 2 +#define NVC0_SCREEN_RESIDENT_BO_COUNT 5 + struct nvc0_screen { struct nouveau_screen base; struct nouveau_winsys *nvws; diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c index 6bbcf2447ec..41079104b39 100644 --- a/src/gallium/drivers/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nvc0/nvc0_vbo.c @@ -382,9 +382,6 @@ nvc0_draw_arrays(struct nvc0_context *nvc0, struct nouveau_channel *chan = nvc0->screen->base.channel; unsigned prim; - chan->flush_notify = nvc0_draw_vbo_flush_notify; - chan->user_private = nvc0; - prim = nvc0_prim_gl(mode); while (instance_count--) { @@ -397,8 +394,6 @@ nvc0_draw_arrays(struct nvc0_context *nvc0, prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } - - chan->flush_notify = nvc0_default_flush_notify; } static void @@ -500,9 +495,6 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, unsigned prim; const unsigned index_size = nvc0->idxbuf.index_size; - chan->flush_notify = nvc0_draw_vbo_flush_notify; - chan->user_private = nvc0; - prim = nvc0_prim_gl(mode); if (index_bias != nvc0->state.index_bias) { @@ -568,8 +560,6 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } - - chan->flush_notify = nvc0_default_flush_notify; } void @@ -596,8 +586,12 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) nvc0_state_validate(nvc0); + chan->flush_notify = nvc0_draw_vbo_flush_notify; + chan->user_private = nvc0; + if (nvc0->vbo_fifo) { nvc0_push_vbo(nvc0, info); + chan->flush_notify = nvc0_default_flush_notify; return; } @@ -648,6 +642,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) info->mode, info->start, info->count, info->instance_count, info->index_bias); } + chan->flush_notify = nvc0_default_flush_notify; nvc0_release_user_vbufs(nvc0); } diff --git a/src/gallium/drivers/nvfx/nvfx_context.c b/src/gallium/drivers/nvfx/nvfx_context.c index 2b1510264a1..98603bedde1 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.c +++ b/src/gallium/drivers/nvfx/nvfx_context.c @@ -24,9 +24,21 @@ nvfx_flush(struct pipe_context *pipe, OUT_RING(chan, 1); }*/ - FIRE_RING(chan); - if (fence) + if (fence) { + /* horrific hack to make glFinish() work in the absence of + * having proper fences in nvfx. a pending rewrite will + * fix this properly, but may be a while off. + */ + MARK_RING(chan, 1, 1); + OUT_RELOC(chan, screen->fence, 0, NOUVEAU_BO_WR | + NOUVEAU_BO_DUMMY, 0, 0); + FIRE_RING(chan); + nouveau_bo_map(screen->fence, NOUVEAU_BO_RDWR); + nouveau_bo_unmap(screen->fence); *fence = NULL; + } else { + FIRE_RING(chan); + } } static void diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c index 78212029534..0140470d576 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.c +++ b/src/gallium/drivers/nvfx/nvfx_screen.c @@ -305,6 +305,7 @@ nvfx_screen_destroy(struct pipe_screen *pscreen) nouveau_notifier_free(&screen->sync); nouveau_grobj_free(&screen->eng3d); nvfx_screen_surface_takedown(pscreen); + nouveau_bo_ref(NULL, &screen->fence); nouveau_screen_fini(&screen->base); @@ -470,6 +471,12 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) pscreen->context_create = nvfx_create; pscreen->video_context_create = nvfx_video_create; + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 4096, &screen->fence); + if (ret) { + nvfx_screen_destroy(pscreen); + return NULL; + } + switch (dev->chipset & 0xf0) { case 0x30: if (NV30_3D_CHIPSET_3X_MASK & (1 << (dev->chipset & 0x0f))) diff --git a/src/gallium/drivers/nvfx/nvfx_screen.h b/src/gallium/drivers/nvfx/nvfx_screen.h index b1f07187c78..02e7c5d1cad 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.h +++ b/src/gallium/drivers/nvfx/nvfx_screen.h @@ -11,6 +11,7 @@ struct nvfx_screen { struct nouveau_screen base; struct nouveau_winsys *nvws; + struct nouveau_bo *fence; struct nvfx_context *cur_ctx; diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index b24e7faa644..b31141a518e 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -46,30 +46,26 @@ static uint32_t r300_translate_primitive(unsigned prim) { - switch (prim) { - case PIPE_PRIM_POINTS: - return R300_VAP_VF_CNTL__PRIM_POINTS; - case PIPE_PRIM_LINES: - return R300_VAP_VF_CNTL__PRIM_LINES; - case PIPE_PRIM_LINE_LOOP: - return R300_VAP_VF_CNTL__PRIM_LINE_LOOP; - case PIPE_PRIM_LINE_STRIP: - return R300_VAP_VF_CNTL__PRIM_LINE_STRIP; - case PIPE_PRIM_TRIANGLES: - return R300_VAP_VF_CNTL__PRIM_TRIANGLES; - case PIPE_PRIM_TRIANGLE_STRIP: - return R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP; - case PIPE_PRIM_TRIANGLE_FAN: - return R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN; - case PIPE_PRIM_QUADS: - return R300_VAP_VF_CNTL__PRIM_QUADS; - case PIPE_PRIM_QUAD_STRIP: - return R300_VAP_VF_CNTL__PRIM_QUAD_STRIP; - case PIPE_PRIM_POLYGON: - return R300_VAP_VF_CNTL__PRIM_POLYGON; - default: - return 0; - } + static const int prim_conv[] = { + R300_VAP_VF_CNTL__PRIM_POINTS, + R300_VAP_VF_CNTL__PRIM_LINES, + R300_VAP_VF_CNTL__PRIM_LINE_LOOP, + R300_VAP_VF_CNTL__PRIM_LINE_STRIP, + R300_VAP_VF_CNTL__PRIM_TRIANGLES, + R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP, + R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN, + R300_VAP_VF_CNTL__PRIM_QUADS, + R300_VAP_VF_CNTL__PRIM_QUAD_STRIP, + R300_VAP_VF_CNTL__PRIM_POLYGON, + -1, + -1, + -1, + -1 + }; + unsigned hwprim = prim_conv[prim]; + + assert(hwprim != -1); + return hwprim; } static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300, @@ -179,8 +175,8 @@ static void r300_split_index_bias(struct r300_context *r300, int index_bias, enum r300_prepare_flags { PREP_EMIT_STATES = (1 << 0), /* call emit_dirty_state and friends? */ PREP_VALIDATE_VBOS = (1 << 1), /* validate VBOs? */ - PREP_EMIT_AOS = (1 << 2), /* call emit_vertex_arrays? */ - PREP_EMIT_AOS_SWTCL = (1 << 3), /* call emit_vertex_arrays_swtcl? */ + PREP_EMIT_VARRAYS = (1 << 2), /* call emit_vertex_arrays? */ + PREP_EMIT_VARRAYS_SWTCL = (1 << 3), /* call emit_vertex_arrays_swtcl? */ PREP_INDEXED = (1 << 4) /* is this draw_elements? */ }; @@ -197,23 +193,22 @@ static boolean r300_reserve_cs_dwords(struct r300_context *r300, unsigned cs_dwords) { boolean flushed = FALSE; - boolean first_draw = flags & PREP_EMIT_STATES; - boolean emit_vertex_arrays = flags & PREP_EMIT_AOS; - boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL; + boolean emit_states = flags & PREP_EMIT_STATES; + boolean emit_vertex_arrays = flags & PREP_EMIT_VARRAYS; + boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_VARRAYS_SWTCL; /* Add dirty state, index offset, and AOS. */ - if (first_draw) { + if (emit_states) cs_dwords += r300_get_num_dirty_dwords(r300); - if (r300->screen->caps.is_r500) - cs_dwords += 2; /* emit_index_offset */ + if (r300->screen->caps.is_r500) + cs_dwords += 2; /* emit_index_offset */ - if (emit_vertex_arrays) - cs_dwords += 55; /* emit_vertex_arrays */ + if (emit_vertex_arrays) + cs_dwords += 55; /* emit_vertex_arrays */ - if (emit_vertex_arrays_swtcl) - cs_dwords += 7; /* emit_vertex_arrays_swtcl */ - } + if (emit_vertex_arrays_swtcl) + cs_dwords += 7; /* emit_vertex_arrays_swtcl */ cs_dwords += r300_get_num_cs_end_dwords(r300); @@ -242,46 +237,48 @@ static boolean r300_emit_states(struct r300_context *r300, int buffer_offset, int index_bias, int instance_id) { - boolean first_draw = flags & PREP_EMIT_STATES; - boolean emit_vertex_arrays = flags & PREP_EMIT_AOS; - boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL; + boolean emit_states = flags & PREP_EMIT_STATES; + boolean emit_vertex_arrays = flags & PREP_EMIT_VARRAYS; + boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_VARRAYS_SWTCL; boolean indexed = flags & PREP_INDEXED; boolean validate_vbos = flags & PREP_VALIDATE_VBOS; /* Validate buffers and emit dirty state if needed. */ - if (first_draw) { + if (emit_states || (emit_vertex_arrays && validate_vbos)) { if (!r300_emit_buffer_validate(r300, validate_vbos, index_buffer)) { fprintf(stderr, "r300: CS space validation failed. " "(not enough memory?) Skipping rendering.\n"); return FALSE; } + } + if (emit_states) r300_emit_dirty_state(r300); - if (r300->screen->caps.is_r500) { - if (r300->screen->caps.has_tcl) - r500_emit_index_bias(r300, index_bias); - else - r500_emit_index_bias(r300, 0); - } - if (emit_vertex_arrays && - (r300->vertex_arrays_dirty || - r300->vertex_arrays_indexed != indexed || - r300->vertex_arrays_offset != buffer_offset || - r300->vertex_arrays_instance_id != instance_id)) { - r300_emit_vertex_arrays(r300, buffer_offset, indexed, instance_id); - - r300->vertex_arrays_dirty = FALSE; - r300->vertex_arrays_indexed = indexed; - r300->vertex_arrays_offset = buffer_offset; - r300->vertex_arrays_instance_id = instance_id; - } + if (r300->screen->caps.is_r500) { + if (r300->screen->caps.has_tcl) + r500_emit_index_bias(r300, index_bias); + else + r500_emit_index_bias(r300, 0); + } - if (emit_vertex_arrays_swtcl) - r300_emit_vertex_arrays_swtcl(r300, indexed); + if (emit_vertex_arrays && + (r300->vertex_arrays_dirty || + r300->vertex_arrays_indexed != indexed || + r300->vertex_arrays_offset != buffer_offset || + r300->vertex_arrays_instance_id != instance_id)) { + r300_emit_vertex_arrays(r300, buffer_offset, indexed, instance_id); + + r300->vertex_arrays_dirty = FALSE; + r300->vertex_arrays_indexed = indexed; + r300->vertex_arrays_offset = buffer_offset; + r300->vertex_arrays_instance_id = instance_id; } + if (emit_vertex_arrays_swtcl) + r300_emit_vertex_arrays_swtcl(r300, indexed); + return TRUE; } @@ -544,7 +541,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300, /* 19 dwords for r300_draw_elements_immediate. Give up if the function fails. */ if (!r300_prepare_for_rendering(r300, - PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | + PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS | PREP_INDEXED, NULL, 2+count_dwords, 0, info->index_bias, -1)) return; @@ -666,7 +663,7 @@ static void r300_draw_elements(struct r300_context *r300, /* 19 dwords for emit_draw_elements. Give up if the function fails. */ if (!r300_prepare_for_rendering(r300, - PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | + PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS | PREP_INDEXED, indexBuffer, 19, buffer_offset, info->index_bias, instance_id)) goto done; @@ -677,10 +674,11 @@ static void r300_draw_elements(struct r300_context *r300, indices3); } else { do { - if (indexSize == 2 && (start & 1)) - short_count = MIN2(count, 65535); - else - short_count = MIN2(count, 65534); + /* The maximum must be divisible by 4 and 3, + * so that quad and triangle lists are split correctly. + * + * Strips, loops, and fans won't work. */ + short_count = MIN2(count, 65532); r300_emit_draw_elements(r300, indexBuffer, indexSize, info->min_index, info->max_index, @@ -692,7 +690,7 @@ static void r300_draw_elements(struct r300_context *r300, /* 15 dwords for emit_draw_elements */ if (count) { if (!r300_prepare_for_rendering(r300, - PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED, + PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS | PREP_INDEXED, indexBuffer, 19, buffer_offset, info->index_bias, instance_id)) goto done; @@ -718,7 +716,7 @@ static void r300_draw_arrays(struct r300_context *r300, /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */ if (!r300_prepare_for_rendering(r300, - PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS, + PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS, NULL, 9, start, 0, instance_id)) return; @@ -726,7 +724,11 @@ static void r300_draw_arrays(struct r300_context *r300, r300_emit_draw_arrays(r300, info->mode, count); } else { do { - short_count = MIN2(count, 65535); + /* The maximum must be divisible by 4 and 3, + * so that quad and triangle lists are split correctly. + * + * Strips, loops, and fans won't work. */ + short_count = MIN2(count, 65532); r300_emit_draw_arrays(r300, info->mode, short_count); start += short_count; @@ -735,7 +737,7 @@ static void r300_draw_arrays(struct r300_context *r300, /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */ if (count) { if (!r300_prepare_for_rendering(r300, - PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9, + PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS, NULL, 9, start, 0, instance_id)) return; } @@ -766,7 +768,6 @@ static void r300_draw_vbo(struct pipe_context* pipe, { struct r300_context* r300 = r300_context(pipe); struct pipe_draw_info info = *dinfo; - boolean buffers_updated, uploader_flushed; info.indexed = info.indexed && r300->index_buffer.buffer; @@ -778,9 +779,7 @@ static void r300_draw_vbo(struct pipe_context* pipe, r300_update_derived_state(r300); /* Start the vbuf manager and update buffers if needed. */ - u_vbuf_mgr_draw_begin(r300->vbuf_mgr, &info, - &buffers_updated, &uploader_flushed); - if (buffers_updated) { + if (u_vbuf_mgr_draw_begin(r300->vbuf_mgr, &info) & U_VBUF_BUFFERS_UPDATED) { r300->vertex_arrays_dirty = TRUE; } @@ -842,7 +841,7 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, r300_update_derived_state(r300); r300_reserve_cs_dwords(r300, - PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | + PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL | (indexed ? PREP_INDEXED : 0), indexed ? 256 : 6); @@ -1024,12 +1023,12 @@ static void r300_render_draw_arrays(struct vbuf_render* render, if (r300->draw_first_emitted) { if (!r300_prepare_for_rendering(r300, - PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL, + PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL, NULL, dwords, 0, 0, -1)) return; } else { if (!r300_emit_states(r300, - PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL, + PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL, NULL, 0, 0, -1)) return; } @@ -1064,12 +1063,12 @@ static void r300_render_draw_elements(struct vbuf_render* render, if (r300->draw_first_emitted) { if (!r300_prepare_for_rendering(r300, - PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | PREP_INDEXED, + PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED, NULL, 256, 0, 0, -1)) return; } else { if (!r300_emit_states(r300, - PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | PREP_INDEXED, + PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED, NULL, 0, 0, -1)) return; } @@ -1106,7 +1105,7 @@ static void r300_render_draw_elements(struct vbuf_render* render, if (count) { if (!r300_prepare_for_rendering(r300, - PREP_EMIT_AOS_SWTCL | PREP_INDEXED, + PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED, NULL, 256, 0, 0, -1)) return; diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 7127ea1ac16..057cd9faf03 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1307,7 +1307,7 @@ static void* sampler->filter0 |= r300_translate_tex_filters(state->min_img_filter, state->mag_img_filter, state->min_mip_filter, - state->max_anisotropy > 0); + state->max_anisotropy > 1); sampler->filter0 |= r300_anisotropy(state->max_anisotropy); diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 121409b2260..f63114e7eb7 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -854,6 +854,12 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) texstate->filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE); } + /* The hardware doesn't like CLAMP and CLAMP_TO_BORDER + * for the 3rd coordinate if the texture isn't 3D. */ + if (tex->b.b.b.target != PIPE_TEXTURE_3D) { + texstate->filter0 &= ~R300_TX_WRAP_R_MASK; + } + if (tex->tex.is_npot) { /* NPOT textures don't support mip filter, unfortunately. * This prevents incorrect rendering. */ diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index 54dae1acd98..62c03b3909b 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -261,51 +261,49 @@ static INLINE uint32_t r300_translate_wrap(int wrap) } static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip, - int is_anisotropic) + boolean is_anisotropic) { uint32_t retval = 0; - if (is_anisotropic) - retval |= R300_TX_MIN_FILTER_ANISO | R300_TX_MAG_FILTER_ANISO; - else { - switch (min) { - case PIPE_TEX_FILTER_NEAREST: - retval |= R300_TX_MIN_FILTER_NEAREST; - break; - case PIPE_TEX_FILTER_LINEAR: - retval |= R300_TX_MIN_FILTER_LINEAR; - break; - default: - fprintf(stderr, "r300: Unknown texture filter %d\n", min); - assert(0); - break; - } - switch (mag) { - case PIPE_TEX_FILTER_NEAREST: - retval |= R300_TX_MAG_FILTER_NEAREST; - break; - case PIPE_TEX_FILTER_LINEAR: - retval |= R300_TX_MAG_FILTER_LINEAR; - break; - default: - fprintf(stderr, "r300: Unknown texture filter %d\n", mag); - assert(0); - break; - } + + switch (min) { + case PIPE_TEX_FILTER_NEAREST: + retval |= R300_TX_MIN_FILTER_NEAREST; + break; + case PIPE_TEX_FILTER_LINEAR: + retval |= is_anisotropic ? R300_TX_MIN_FILTER_ANISO : + R300_TX_MIN_FILTER_LINEAR; + break; + default: + fprintf(stderr, "r300: Unknown texture filter %d\n", min); + assert(0); } + + switch (mag) { + case PIPE_TEX_FILTER_NEAREST: + retval |= R300_TX_MAG_FILTER_NEAREST; + break; + case PIPE_TEX_FILTER_LINEAR: + retval |= is_anisotropic ? R300_TX_MAG_FILTER_ANISO : + R300_TX_MAG_FILTER_LINEAR; + break; + default: + fprintf(stderr, "r300: Unknown texture filter %d\n", mag); + assert(0); + } + switch (mip) { - case PIPE_TEX_MIPFILTER_NONE: - retval |= R300_TX_MIN_FILTER_MIP_NONE; - break; - case PIPE_TEX_MIPFILTER_NEAREST: - retval |= R300_TX_MIN_FILTER_MIP_NEAREST; - break; - case PIPE_TEX_MIPFILTER_LINEAR: - retval |= R300_TX_MIN_FILTER_MIP_LINEAR; - break; - default: - fprintf(stderr, "r300: Unknown texture filter %d\n", mip); - assert(0); - break; + case PIPE_TEX_MIPFILTER_NONE: + retval |= R300_TX_MIN_FILTER_MIP_NONE; + break; + case PIPE_TEX_MIPFILTER_NEAREST: + retval |= R300_TX_MIN_FILTER_MIP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + retval |= R300_TX_MIN_FILTER_MIP_LINEAR; + break; + default: + fprintf(stderr, "r300: Unknown texture filter %d\n", mip); + assert(0); } return retval; diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 38ca9a24e45..62c2f1fff6c 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -447,16 +447,8 @@ static uint32_t r300_translate_colorformat(enum pipe_format format) /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/ case PIPE_FORMAT_B8G8R8X8_UNORM: /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/ - case PIPE_FORMAT_A8R8G8B8_UNORM: - /*case PIPE_FORMAT_A8R8G8B8_SNORM:*/ - case PIPE_FORMAT_X8R8G8B8_UNORM: - /*case PIPE_FORMAT_X8R8G8B8_SNORM:*/ - case PIPE_FORMAT_A8B8G8R8_UNORM: - /*case PIPE_FORMAT_A8B8G8R8_SNORM:*/ case PIPE_FORMAT_R8G8B8A8_UNORM: case PIPE_FORMAT_R8G8B8A8_SNORM: - case PIPE_FORMAT_X8B8G8R8_UNORM: - /*case PIPE_FORMAT_X8B8G8R8_SNORM:*/ case PIPE_FORMAT_R8G8B8X8_UNORM: /*case PIPE_FORMAT_R8G8B8X8_SNORM:*/ /* These formats work fine with ARGB8888 if US_OUT_FMT is set @@ -662,10 +654,6 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format) R300_C2_SEL_R | R300_C3_SEL_A; /* ARGB outputs. */ - case PIPE_FORMAT_A8R8G8B8_UNORM: - /*case PIPE_FORMAT_A8R8G8B8_SNORM:*/ - case PIPE_FORMAT_X8R8G8B8_UNORM: - /*case PIPE_FORMAT_X8R8G8B8_SNORM:*/ case PIPE_FORMAT_A16_UNORM: case PIPE_FORMAT_A16_SNORM: case PIPE_FORMAT_A16_FLOAT: @@ -674,15 +662,6 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format) R300_C0_SEL_A | R300_C1_SEL_R | R300_C2_SEL_G | R300_C3_SEL_B; - /* ABGR outputs. */ - case PIPE_FORMAT_A8B8G8R8_UNORM: - /*case PIPE_FORMAT_A8B8G8R8_SNORM:*/ - case PIPE_FORMAT_X8B8G8R8_UNORM: - /*case PIPE_FORMAT_X8B8G8R8_SNORM:*/ - return modifier | - R300_C0_SEL_A | R300_C1_SEL_B | - R300_C2_SEL_G | R300_C3_SEL_R; - /* RGBA outputs. */ case PIPE_FORMAT_R8G8B8X8_UNORM: /*case PIPE_FORMAT_R8G8B8X8_SNORM:*/ diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript index 0135808f10a..19f07b2bef8 100644 --- a/src/gallium/drivers/r600/SConscript +++ b/src/gallium/drivers/r600/SConscript @@ -2,11 +2,7 @@ Import('*') env = env.Clone() -try: - env.ParseConfig('pkg-config --cflags libdrm_radeon') -except OSError: - print 'warning: not building r600' - Return() +env.PkgUseModules('DRM_RADEON') env.Append(CPPPATH = [ '#/include', diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h index b780dba3e33..b5590116e8f 100644 --- a/src/gallium/drivers/r600/eg_state_inlines.h +++ b/src/gallium/drivers/r600/eg_state_inlines.h @@ -292,7 +292,7 @@ static inline uint32_t r600_translate_stencilformat(enum pipe_format format) static inline uint32_t r600_translate_colorswap(enum pipe_format format) { switch (format) { - /* 8-bit buffers. */ + /* 8-bit buffers. */ case PIPE_FORMAT_L4A4_UNORM: return V_028C70_SWAP_ALT; @@ -305,7 +305,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_R8_SNORM: return V_028C70_SWAP_STD; - /* 16-bit buffers. */ + /* 16-bit buffers. */ case PIPE_FORMAT_B5G6R5_UNORM: return V_028C70_SWAP_STD_REV; @@ -327,9 +327,10 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) return V_028C70_SWAP_STD; case PIPE_FORMAT_R16_UNORM: + case PIPE_FORMAT_R16_FLOAT: return V_028C70_SWAP_STD; - /* 32-bit buffers. */ + /* 32-bit buffers. */ case PIPE_FORMAT_A8B8G8R8_SRGB: return V_028C70_SWAP_STD_REV; case PIPE_FORMAT_B8G8R8A8_SRGB: @@ -343,6 +344,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_X8R8G8B8_UNORM: return V_028C70_SWAP_ALT_REV; case PIPE_FORMAT_R8G8B8A8_SNORM: + case PIPE_FORMAT_R8G8B8A8_UNORM: case PIPE_FORMAT_R8G8B8X8_UNORM: return V_028C70_SWAP_STD; @@ -373,13 +375,13 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_R16G16_UNORM: return V_028C70_SWAP_STD; - /* 64-bit buffers. */ + /* 64-bit buffers. */ case PIPE_FORMAT_R32G32_FLOAT: case PIPE_FORMAT_R16G16B16A16_UNORM: case PIPE_FORMAT_R16G16B16A16_SNORM: case PIPE_FORMAT_R16G16B16A16_FLOAT: - /* 128-bit buffers. */ + /* 128-bit buffers. */ case PIPE_FORMAT_R32G32B32A32_FLOAT: case PIPE_FORMAT_R32G32B32A32_SNORM: case PIPE_FORMAT_R32G32B32A32_UNORM: @@ -394,7 +396,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) { switch (format) { - /* 8-bit buffers. */ + /* 8-bit buffers. */ case PIPE_FORMAT_L4A4_UNORM: return V_028C70_COLOR_4_4; @@ -406,7 +408,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R8_SNORM: return V_028C70_COLOR_8; - /* 16-bit buffers. */ + /* 16-bit buffers. */ case PIPE_FORMAT_B5G6R5_UNORM: return V_028C70_COLOR_5_6_5; @@ -429,7 +431,10 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R16_UNORM: return V_028C70_COLOR_16; - /* 32-bit buffers. */ + case PIPE_FORMAT_R16_FLOAT: + return V_028C70_COLOR_16_FLOAT; + + /* 32-bit buffers. */ case PIPE_FORMAT_A8B8G8R8_SRGB: case PIPE_FORMAT_A8B8G8R8_UNORM: case PIPE_FORMAT_A8R8G8B8_UNORM: @@ -472,7 +477,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R11G11B10_FLOAT: return V_028C70_COLOR_10_11_11_FLOAT; - /* 64-bit buffers. */ + /* 64-bit buffers. */ case PIPE_FORMAT_R16G16B16_USCALED: case PIPE_FORMAT_R16G16B16A16_USCALED: case PIPE_FORMAT_R16G16B16_SSCALED: @@ -492,20 +497,21 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R32G32_SSCALED: return V_028C70_COLOR_32_32; - /* 128-bit buffers. */ + /* 96-bit buffers. */ + case PIPE_FORMAT_R32G32B32_FLOAT: + return V_028C70_COLOR_32_32_32_FLOAT; + + /* 128-bit buffers. */ case PIPE_FORMAT_R32G32B32A32_SNORM: case PIPE_FORMAT_R32G32B32A32_UNORM: return V_028C70_COLOR_32_32_32_32; - case PIPE_FORMAT_R32G32B32_FLOAT: - return V_028C70_COLOR_32_32_32_FLOAT; case PIPE_FORMAT_R32G32B32A32_FLOAT: return V_028C70_COLOR_32_32_32_32_FLOAT; - /* YUV buffers. */ + /* YUV buffers. */ case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: default: - /* R600_ERR("unsupported color format %d\n", format); */ return ~0; /* Unsupported. */ } } @@ -517,11 +523,11 @@ static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) case V_028C70_COLOR_4_4: return(ENDIAN_NONE); - /* 8-bit buffers. */ + /* 8-bit buffers. */ case V_028C70_COLOR_8: return(ENDIAN_NONE); - /* 16-bit buffers. */ + /* 16-bit buffers. */ case V_028C70_COLOR_5_6_5: case V_028C70_COLOR_1_5_5_5: case V_028C70_COLOR_4_4_4_4: @@ -529,7 +535,7 @@ static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) case V_028C70_COLOR_8_8: return(ENDIAN_8IN16); - /* 32-bit buffers. */ + /* 32-bit buffers. */ case V_028C70_COLOR_8_8_8_8: case V_028C70_COLOR_2_10_10_10: case V_028C70_COLOR_8_24: @@ -539,7 +545,7 @@ static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) case V_028C70_COLOR_16_16: return(ENDIAN_8IN32); - /* 64-bit buffers. */ + /* 64-bit buffers. */ case V_028C70_COLOR_16_16_16_16: case V_028C70_COLOR_16_16_16_16_FLOAT: return(ENDIAN_8IN16); @@ -548,8 +554,9 @@ static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) case V_028C70_COLOR_32_32: return(ENDIAN_8IN32); - /* 128-bit buffers. */ + /* 96-bit buffers. */ case V_028C70_COLOR_32_32_32_FLOAT: + /* 128-bit buffers. */ case V_028C70_COLOR_32_32_32_32_FLOAT: case V_028C70_COLOR_32_32_32_32: return(ENDIAN_8IN32); diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 9ebfe54c76d..dc182611482 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -256,6 +256,8 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, } rstate = &rs->rstate; + rs->clamp_vertex_color = state->clamp_vertex_color; + rs->clamp_fragment_color = state->clamp_fragment_color; rs->flatshade = state->flatshade; rs->sprite_coord_enable = state->sprite_coord_enable; @@ -482,19 +484,27 @@ static void evergreen_set_ps_sampler_view(struct pipe_context *ctx, unsigned cou struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_pipe_sampler_view **resource = (struct r600_pipe_sampler_view **)views; int i; + int has_depth = 0; for (i = 0; i < count; i++) { if (&rctx->ps_samplers.views[i]->base != views[i]) { - if (resource[i]) + if (resource[i]) { + if (((struct r600_resource_texture *)resource[i]->base.texture)->depth) + has_depth = 1; evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, &resource[i]->state, i + R600_MAX_CONST_BUFFERS); - else + } else evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, NULL, i + R600_MAX_CONST_BUFFERS); pipe_sampler_view_reference( (struct pipe_sampler_view **)&rctx->ps_samplers.views[i], views[i]); + } else { + if (resource[i]) { + if (((struct r600_resource_texture *)resource[i]->base.texture)->depth) + has_depth = 1; + } } } for (i = count; i < NUM_TEX_UNITS; i++) { @@ -504,6 +514,7 @@ static void evergreen_set_ps_sampler_view(struct pipe_context *ctx, unsigned cou pipe_sampler_view_reference((struct pipe_sampler_view **)&rctx->ps_samplers.views[i], NULL); } } + rctx->have_depth_texture = has_depth; rctx->ps_samplers.n_views = count; } @@ -689,6 +700,9 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state surf = (struct r600_surface *)state->cbufs[cb]; rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture; + if (rtex->depth) + rctx->have_depth_fb = TRUE; + if (rtex->depth && !rtex->is_flushing_texture) { r600_texture_depth_flush(&rctx->context, state->cbufs[cb]->texture, TRUE); rtex = rtex->flushed_depth_texture; @@ -870,6 +884,8 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx, util_copy_framebuffer_state(&rctx->framebuffer, state); /* build states */ + rctx->have_depth_fb = 0; + rctx->nr_cbufs = state->nr_cbufs; for (int i = 0; i < state->nr_cbufs; i++) { evergreen_cb(rctx, rstate, state, i); } @@ -1616,7 +1632,10 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader rshader->output[i].name == TGSI_SEMANTIC_STENCIL) exports_ps |= 1; else if (rshader->output[i].name == TGSI_SEMANTIC_COLOR) { - num_cout++; + if (rshader->fs_write_all) + num_cout = rshader->nr_cbufs; + else + num_cout++; } } exports_ps |= S_02884C_EXPORT_COLORS(num_cout); diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index bf7138d9e4e..151e831e5c6 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -245,6 +245,7 @@ struct r600_context { unsigned pm4_cdwords; unsigned pm4_dirty_cdwords; unsigned ctx_pm4_ndwords; + unsigned init_dwords; unsigned nreloc; unsigned creloc; struct r600_reloc *reloc; @@ -261,6 +262,7 @@ struct r600_context { struct r600_range vs_resources; struct r600_range fs_resources; int num_ps_resources, num_vs_resources, num_fs_resources; + boolean have_depth_texture, have_depth_fb; }; struct r600_draw { diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 3196d97dbbb..065f955ebcb 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -1383,6 +1383,9 @@ int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex) break; } } + /* slight hack to make gradients always go into same cf */ + if (ntex->inst == SQ_TEX_INST_SET_GRADIENTS_H) + bc->force_add_cf = 1; } /* cf can contains only alu or only vtx or only tex */ @@ -1860,6 +1863,8 @@ void r600_bc_dump(struct r600_bc *bc) break; case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: + case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: + case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]); fprintf(stderr, "GPR:%X ", cf->output.gpr); fprintf(stderr, "ELEM_SIZE:%X ", cf->output.elem_size); @@ -2258,7 +2263,7 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru ve->fs_size = bc.ndw*4; /* use PIPE_BIND_VERTEX_BUFFER so we use the cache buffer manager */ - ve->fetch_shader = r600_bo(rctx->radeon, ve->fs_size, 256, PIPE_BIND_VERTEX_BUFFER, 0); + ve->fetch_shader = r600_bo(rctx->radeon, ve->fs_size, 256, PIPE_BIND_VERTEX_BUFFER, PIPE_USAGE_IMMUTABLE); if (ve->fetch_shader == NULL) { r600_bc_clear(&bc); return -ENOMEM; diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 151f48a8bf8..6171d285bb9 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -27,9 +27,18 @@ enum r600_blitter_op /* bitmask */ { - R600_CLEAR = 1, - R600_CLEAR_SURFACE = 2, - R600_COPY = 4 + R600_SAVE_TEXTURES = 1, + R600_SAVE_FRAMEBUFFER = 2, + R600_DISABLE_RENDER_COND = 4, + + R600_CLEAR = 0, + + R600_CLEAR_SURFACE = R600_SAVE_FRAMEBUFFER, + + R600_COPY = R600_SAVE_FRAMEBUFFER | R600_SAVE_TEXTURES | + R600_DISABLE_RENDER_COND, + + R600_DECOMPRESS = R600_SAVE_FRAMEBUFFER | R600_DISABLE_RENDER_COND, }; static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op) @@ -58,10 +67,10 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op rctx->vbuf_mgr->nr_vertex_buffers, rctx->vbuf_mgr->vertex_buffer); - if (op & (R600_CLEAR_SURFACE | R600_COPY)) + if (op & R600_SAVE_FRAMEBUFFER) util_blitter_save_framebuffer(rctx->blitter, &rctx->framebuffer); - if (op & R600_COPY) { + if (op & R600_SAVE_TEXTURES) { util_blitter_save_fragment_sampler_states( rctx->blitter, rctx->ps_samplers.n_samplers, (void**)rctx->ps_samplers.samplers); @@ -71,11 +80,23 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op (struct pipe_sampler_view**)rctx->ps_samplers.views); } + if ((op & R600_DISABLE_RENDER_COND) && rctx->current_render_cond) { + rctx->saved_render_cond = rctx->current_render_cond; + rctx->saved_render_cond_mode = rctx->current_render_cond_mode; + rctx->context.render_condition(&rctx->context, NULL, 0); + } + } static void r600_blitter_end(struct pipe_context *ctx) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + if (rctx->saved_render_cond) { + rctx->context.render_condition(&rctx->context, + rctx->saved_render_cond, + rctx->saved_render_cond_mode); + rctx->saved_render_cond = NULL; + } r600_context_queries_resume(&rctx->ctx); rctx->blit = false; } @@ -107,7 +128,7 @@ void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_t rctx->family == CHIP_RV620 || rctx->family == CHIP_RV635) depth = 0.0f; - r600_blitter_begin(ctx, R600_CLEAR_SURFACE); + r600_blitter_begin(ctx, R600_DECOMPRESS); util_blitter_custom_depth_stencil(rctx->blitter, zsurf, cbsurf, rctx->custom_dsa_flush, depth); r600_blitter_end(ctx); @@ -121,8 +142,6 @@ void r600_flush_depth_textures(struct r600_pipe_context *rctx) { unsigned int i; - if (rctx->blit) return; - /* FIXME: This handles fragment shader textures only. */ for (i = 0; i < rctx->ps_samplers.n_views; ++i) { @@ -275,6 +294,8 @@ static void r600_resource_copy_region(struct pipe_context *ctx, { struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src; struct texture_orig_info orig_info[2]; + struct pipe_box sbox; + const struct pipe_box *psbox; boolean restore_orig[2]; /* Fallback for buffers. */ @@ -292,7 +313,15 @@ static void r600_resource_copy_region(struct pipe_context *ctx, if (util_format_is_compressed(src->format)) { r600_compressed_to_blittable(src, src_level, &orig_info[0]); restore_orig[0] = TRUE; - } + sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x); + sbox.y = util_format_get_nblocksy(orig_info[0].format, src_box->y); + sbox.z = src_box->z; + sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); + sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height); + sbox.depth = src_box->depth; + psbox=&sbox; + } else + psbox=src_box; if (util_format_is_compressed(dst->format)) { r600_compressed_to_blittable(dst, dst_level, &orig_info[1]); @@ -303,7 +332,7 @@ static void r600_resource_copy_region(struct pipe_context *ctx, } r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, - src, src_level, src_box); + src, src_level, psbox); if (restore_orig[0]) r600_reset_blittable_to_compressed(src, src_level, &orig_info[0]); diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 70e3619de4b..049a4daae66 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -127,9 +127,6 @@ static void r600_flush(struct pipe_context *ctx, if (rfence) *rfence = r600_create_fence(rctx); - if (!rctx->ctx.pm4_cdwords) - return; - #if 0 sprintf(dname, "gallium-%08d.bof", dc); if (dc < 20) { @@ -139,11 +136,6 @@ static void r600_flush(struct pipe_context *ctx, dc++; #endif r600_context_flush(&rctx->ctx); - - /* XXX This shouldn't be really necessary, but removing it breaks some tests. - * Needless buffer reallocations may significantly increase memory consumption, - * so getting rid of this call is important. */ - u_upload_flush(rctx->vbuf_mgr->uploader); } static void r600_update_num_contexts(struct r600_screen *rscreen, int diff) @@ -373,7 +365,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_MIRROR_CLAMP: case PIPE_CAP_TEXTURE_MIRROR_REPEAT: case PIPE_CAP_BLEND_EQUATION_SEPARATE: - case PIPE_CAP_SM3: case PIPE_CAP_TEXTURE_SWIZZLE: case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: case PIPE_CAP_DEPTH_CLAMP: @@ -382,6 +373,9 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + case PIPE_CAP_SM3: + case PIPE_CAP_SEAMLESS_CUBE_MAP: + case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: return 1; /* Supported except the original R600. */ @@ -391,14 +385,12 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) return family == CHIP_R600 ? 0 : 1; /* Supported on Evergreen. */ - case PIPE_CAP_SEAMLESS_CUBE_MAP: case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: return family >= CHIP_CEDAR ? 1 : 0; /* Unsupported features. */ case PIPE_CAP_STREAM_OUTPUT: case PIPE_CAP_PRIMITIVE_RESTART: - case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: case PIPE_CAP_TGSI_INSTANCEID: case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: @@ -487,9 +479,9 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e return 8; /* FIXME */ case PIPE_SHADER_CAP_MAX_INPUTS: if(shader == PIPE_SHADER_FRAGMENT) - return 10; + return 34; else - return 16; + return 32; case PIPE_SHADER_CAP_MAX_TEMPS: return 256; /* Max native temporaries. */ case PIPE_SHADER_CAP_MAX_ADDRS: diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index d92b74ebc4e..2667c80bcef 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -50,6 +50,7 @@ enum r600_pipe_state_id { R600_PIPE_STATE_BLEND = 0, R600_PIPE_STATE_BLEND_COLOR, R600_PIPE_STATE_CONFIG, + R600_PIPE_STATE_SEAMLESS_CUBEMAP, R600_PIPE_STATE_CLIP, R600_PIPE_STATE_SCISSOR, R600_PIPE_STATE_VIEWPORT, @@ -87,6 +88,8 @@ struct r600_pipe_sampler_view { struct r600_pipe_rasterizer { struct r600_pipe_state rstate; + boolean clamp_vertex_color; + boolean clamp_fragment_color; boolean flatshade; unsigned sprite_coord_enable; float offset_units; @@ -124,6 +127,12 @@ struct r600_pipe_shader { struct r600_bo *bo; struct r600_bo *bo_fetch; struct r600_vertex_element vertex_elements; + struct tgsi_token *tokens; +}; + +struct r600_pipe_sampler_state { + struct r600_pipe_state rstate; + boolean seamless_cube_map; }; /* needed for blitter save */ @@ -191,12 +200,20 @@ struct r600_pipe_context { struct r600_pipe_rasterizer *rasterizer; struct r600_pipe_state vgt; struct r600_pipe_state spi; + struct pipe_query *current_render_cond; + unsigned current_render_cond_mode; + struct pipe_query *saved_render_cond; + unsigned saved_render_cond_mode; /* shader information */ + boolean clamp_vertex_color; + boolean clamp_fragment_color; + boolean spi_dirty; unsigned sprite_coord_enable; boolean flatshade; boolean export_16bpc; unsigned alpha_ref; boolean alpha_ref_dirty; + unsigned nr_cbufs; struct r600_textures_info ps_samplers; struct r600_pipe_fences fences; @@ -204,7 +221,9 @@ struct r600_pipe_context { struct u_vbuf_mgr *vbuf_mgr; struct util_slab_mempool pool_transfers; boolean blit; + boolean have_depth_texture, have_depth_fb; + unsigned default_ps_gprs, default_vs_gprs; }; struct r600_drawl { @@ -252,7 +271,7 @@ void r600_init_query_functions(struct r600_pipe_context *rctx); void r600_init_context_resource_functions(struct r600_pipe_context *r600); /* r600_shader.c */ -int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader, const struct tgsi_token *tokens); +int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader); void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *shader); int r600_find_vs_semantic_index(struct r600_shader *vs, struct r600_shader *ps, int id); @@ -270,6 +289,7 @@ void r600_pipe_init_buffer_resource(struct r600_pipe_context *rctx, void r600_pipe_mod_buffer_resource(struct r600_pipe_resource_state *rstate, struct r600_resource *rbuffer, unsigned offset, unsigned stride); +void r600_adjust_gprs(struct r600_pipe_context *rctx); /* r600_texture.c */ void r600_init_screen_texture_functions(struct pipe_screen *screen); diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c index 181ea3f9e49..bedb48b6031 100644 --- a/src/gallium/drivers/r600/r600_query.c +++ b/src/gallium/drivers/r600/r600_query.c @@ -75,6 +75,9 @@ static void r600_render_condition(struct pipe_context *ctx, struct r600_query *rquery = (struct r600_query *)query; int wait_flag = 0; + rctx->current_render_cond = query; + rctx->current_render_cond_mode = mode; + if (!query) { rctx->ctx.predicate_drawing = false; r600_query_predication(&rctx->ctx, NULL, PREDICATION_OP_CLEAR, 1); diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 39e6d85d7b4..f83d7079b29 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -63,10 +63,6 @@ int r600_find_vs_semantic_index(struct r600_shader *vs, { struct r600_shader_io *input = &ps->input[id]; - /* position/face doesn't get/need a semantic index */ - if (input->name == TGSI_SEMANTIC_POSITION || input->name == TGSI_SEMANTIC_FACE) - return 0; - for (int i = 0; i < vs->noutput; i++) { if (input->name == vs->output[i].name && input->sid == vs->output[i].sid) { @@ -85,7 +81,8 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s /* copy new shader */ if (shader->bo == NULL) { - shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, 0, 0); + /* use PIPE_BIND_VERTEX_BUFFER so we use the cache buffer manager */ + shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, PIPE_BIND_VERTEX_BUFFER, PIPE_USAGE_IMMUTABLE); if (shader->bo == NULL) { return -ENOMEM; } @@ -121,9 +118,9 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s return 0; } -static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader); +static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pipe_shader *pipeshader); -int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader, const struct tgsi_token *tokens) +int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader) { static int dump_shaders = -1; struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; @@ -136,10 +133,10 @@ int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *s if (dump_shaders) { fprintf(stderr, "--------------------------------------------------------------\n"); - tgsi_dump(tokens, 0); + tgsi_dump(shader->tokens, 0); } shader->shader.family = r600_get_family(rctx->radeon); - r = r600_shader_from_tgsi(tokens, &shader->shader); + r = r600_shader_from_tgsi(rctx, shader); if (r) { R600_ERR("translation from TGSI failed !\n"); return r; @@ -162,6 +159,8 @@ void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader r600_bo_reference(rctx->radeon, &shader->bo, NULL); r600_bc_clear(&shader->shader.bc); + + memset(&shader->shader,0,sizeof(struct r600_shader)); } /* @@ -189,7 +188,7 @@ struct r600_shader_ctx { struct r600_shader_tgsi_instruction *inst_info; struct r600_bc *bc; struct r600_shader *shader; - struct r600_shader_src src[3]; + struct r600_shader_src src[4]; u32 *literals; u32 nliterals; u32 max_driver_temp_used; @@ -597,15 +596,17 @@ static int tgsi_split_literal_constant(struct r600_shader_ctx *ctx) return 0; } -static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader) +static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pipe_shader *pipeshader) { + struct r600_shader *shader = &pipeshader->shader; + struct tgsi_token *tokens = pipeshader->tokens; struct tgsi_full_immediate *immediate; struct tgsi_full_property *property; struct r600_shader_ctx ctx; struct r600_bc_output output[32]; unsigned output_done, noutput; unsigned opcode; - int i, r = 0, pos0; + int i, j, r = 0, pos0; ctx.bc = &shader->bc; ctx.shader = shader; @@ -619,6 +620,11 @@ static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_sh shader->processor_type = ctx.type; ctx.bc->type = shader->processor_type; + shader->clamp_color = (((ctx.type == TGSI_PROCESSOR_FRAGMENT) && rctx->clamp_fragment_color) || + ((ctx.type == TGSI_PROCESSOR_VERTEX) && rctx->clamp_vertex_color)); + + shader->nr_cbufs = rctx->nr_cbufs; + /* register allocations */ /* Values [0,127] correspond to GPR[0..127]. * Values [128,159] correspond to constant buffer bank 0 @@ -728,52 +734,103 @@ static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_sh goto out_err; } } - /* export output */ + noutput = shader->noutput; + + /* clamp color outputs */ + if (shader->clamp_color) { + for (i = 0; i < noutput; i++) { + if (shader->output[i].name == TGSI_SEMANTIC_COLOR || + shader->output[i].name == TGSI_SEMANTIC_BCOLOR) { + + int j; + for (j = 0; j < 4; j++) { + struct r600_bc_alu alu; + memset(&alu, 0, sizeof(struct r600_bc_alu)); + + /* MOV_SAT R, R */ + alu.inst = BC_INST(ctx.bc, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV); + alu.dst.sel = shader->output[i].gpr; + alu.dst.chan = j; + alu.dst.write = 1; + alu.dst.clamp = 1; + alu.src[0].sel = alu.dst.sel; + alu.src[0].chan = j; + + if (j == 3) { + alu.last = 1; + } + r = r600_bc_add_alu(ctx.bc, &alu); + if (r) + return r; + } + } + } + } + + /* export output */ + j = 0; for (i = 0, pos0 = 0; i < noutput; i++) { memset(&output[i], 0, sizeof(struct r600_bc_output)); - output[i].gpr = shader->output[i].gpr; - output[i].elem_size = 3; - output[i].swizzle_x = 0; - output[i].swizzle_y = 1; - output[i].swizzle_z = 2; - output[i].swizzle_w = 3; - output[i].burst_count = 1; - output[i].barrier = 1; - output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM; - output[i].array_base = i - pos0; - output[i].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT); + output[i + j].gpr = shader->output[i].gpr; + output[i + j].elem_size = 3; + output[i + j].swizzle_x = 0; + output[i + j].swizzle_y = 1; + output[i + j].swizzle_z = 2; + output[i + j].swizzle_w = 3; + output[i + j].burst_count = 1; + output[i + j].barrier = 1; + output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM; + output[i + j].array_base = i - pos0; + output[i + j].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT); switch (ctx.type) { case TGSI_PROCESSOR_VERTEX: if (shader->output[i].name == TGSI_SEMANTIC_POSITION) { - output[i].array_base = 60; - output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS; + output[i + j].array_base = 60; + output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS; /* position doesn't count in array_base */ pos0++; } if (shader->output[i].name == TGSI_SEMANTIC_PSIZE) { - output[i].array_base = 61; - output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS; + output[i + j].array_base = 61; + output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS; /* position doesn't count in array_base */ pos0++; } break; case TGSI_PROCESSOR_FRAGMENT: if (shader->output[i].name == TGSI_SEMANTIC_COLOR) { - output[i].array_base = shader->output[i].sid; - output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; + output[i + j].array_base = shader->output[i].sid; + output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; + if (shader->fs_write_all && (shader->family >= CHIP_CEDAR)) { + for (j = 1; j < shader->nr_cbufs; j++) { + memset(&output[i + j], 0, sizeof(struct r600_bc_output)); + output[i + j].gpr = shader->output[i].gpr; + output[i + j].elem_size = 3; + output[i + j].swizzle_x = 0; + output[i + j].swizzle_y = 1; + output[i + j].swizzle_z = 2; + output[i + j].swizzle_w = 3; + output[i + j].burst_count = 1; + output[i + j].barrier = 1; + output[i + j].array_base = shader->output[i].sid + j; + output[i + j].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT); + output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; + } + j--; + } } else if (shader->output[i].name == TGSI_SEMANTIC_POSITION) { - output[i].array_base = 61; - output[i].swizzle_x = 2; - output[i].swizzle_y = 7; - output[i].swizzle_z = output[i].swizzle_w = 7; - output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; + output[i + j].array_base = 61; + output[i + j].swizzle_x = 2; + output[i + j].swizzle_y = 7; + output[i + j].swizzle_z = output[i + j].swizzle_w = 7; + output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; } else if (shader->output[i].name == TGSI_SEMANTIC_STENCIL) { - output[i].array_base = 61; - output[i].swizzle_x = 7; - output[i].swizzle_y = 1; - output[i].swizzle_z = output[i].swizzle_w = 7; - output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; + output[i + j].array_base = 61; + output[i + j].swizzle_x = 7; + output[i + j].swizzle_y = 1; + output[i + j].swizzle_z = output[i + j].swizzle_w = 7; + output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; } else { R600_ERR("unsupported fragment output name %d\n", shader->output[i].name); r = -EINVAL; @@ -786,6 +843,7 @@ static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_sh goto out_err; } } + noutput += j; /* add fake param output for vertex shader if no param is exported */ if (ctx.type == TGSI_PROCESSOR_VERTEX) { for (i = 0, pos0 = 0; i < noutput; i++) { @@ -1306,41 +1364,6 @@ static int tgsi_lit(struct r600_shader_ctx *ctx) struct r600_bc_alu alu; int r; - /* dst.x, <- 1.0 */ - memset(&alu, 0, sizeof(struct r600_bc_alu)); - alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV); - alu.src[0].sel = V_SQ_ALU_SRC_1; /*1.0*/ - alu.src[0].chan = 0; - tgsi_dst(ctx, &inst->Dst[0], 0, &alu.dst); - alu.dst.write = (inst->Dst[0].Register.WriteMask >> 0) & 1; - r = r600_bc_add_alu(ctx->bc, &alu); - if (r) - return r; - - /* dst.y = max(src.x, 0.0) */ - memset(&alu, 0, sizeof(struct r600_bc_alu)); - alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX); - r600_bc_src(&alu.src[0], &ctx->src[0], 0); - alu.src[1].sel = V_SQ_ALU_SRC_0; /*0.0*/ - alu.src[1].chan = 0; - tgsi_dst(ctx, &inst->Dst[0], 1, &alu.dst); - alu.dst.write = (inst->Dst[0].Register.WriteMask >> 1) & 1; - r = r600_bc_add_alu(ctx->bc, &alu); - if (r) - return r; - - /* dst.w, <- 1.0 */ - memset(&alu, 0, sizeof(struct r600_bc_alu)); - alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV); - alu.src[0].sel = V_SQ_ALU_SRC_1; - alu.src[0].chan = 0; - tgsi_dst(ctx, &inst->Dst[0], 3, &alu.dst); - alu.dst.write = (inst->Dst[0].Register.WriteMask >> 3) & 1; - alu.last = 1; - r = r600_bc_add_alu(ctx->bc, &alu); - if (r) - return r; - if (inst->Dst[0].Register.WriteMask & (1 << 2)) { int chan; @@ -1369,7 +1392,9 @@ static int tgsi_lit(struct r600_shader_ctx *ctx) memset(&alu, 0, sizeof(struct r600_bc_alu)); alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED); r600_bc_src(&alu.src[0], &ctx->src[0], 1); - tgsi_dst(ctx, &inst->Dst[0], 2, &alu.dst); + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 2; + alu.dst.write = 1; alu.last = 1; r = r600_bc_add_alu(ctx->bc, &alu); if (r) @@ -1426,6 +1451,42 @@ static int tgsi_lit(struct r600_shader_ctx *ctx) return r; } } + + /* dst.x, <- 1.0 */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV); + alu.src[0].sel = V_SQ_ALU_SRC_1; /*1.0*/ + alu.src[0].chan = 0; + tgsi_dst(ctx, &inst->Dst[0], 0, &alu.dst); + alu.dst.write = (inst->Dst[0].Register.WriteMask >> 0) & 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + + /* dst.y = max(src.x, 0.0) */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX); + r600_bc_src(&alu.src[0], &ctx->src[0], 0); + alu.src[1].sel = V_SQ_ALU_SRC_0; /*0.0*/ + alu.src[1].chan = 0; + tgsi_dst(ctx, &inst->Dst[0], 1, &alu.dst); + alu.dst.write = (inst->Dst[0].Register.WriteMask >> 1) & 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + + /* dst.w, <- 1.0 */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV); + alu.src[0].sel = V_SQ_ALU_SRC_1; + alu.src[0].chan = 0; + tgsi_dst(ctx, &inst->Dst[0], 3, &alu.dst); + alu.dst.write = (inst->Dst[0].Register.WriteMask >> 3) & 1; + alu.last = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + return 0; } @@ -1748,6 +1809,22 @@ static int tgsi_dp(struct r600_shader_ctx *ctx) return 0; } +static inline boolean tgsi_tex_src_requires_loading(struct r600_shader_ctx *ctx, + unsigned index) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + return (inst->Src[index].Register.File != TGSI_FILE_TEMPORARY && + inst->Src[index].Register.File != TGSI_FILE_INPUT) || + ctx->src[index].neg || ctx->src[index].abs; +} + +static inline unsigned tgsi_tex_get_src_gpr(struct r600_shader_ctx *ctx, + unsigned index) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + return ctx->file_offset[inst->Src[index].Register.File] + inst->Src[index].Register.Index; +} + static int tgsi_tex(struct r600_shader_ctx *ctx) { static float one_point_five = 1.5f; @@ -1755,19 +1832,70 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) struct r600_bc_tex tex; struct r600_bc_alu alu; unsigned src_gpr; - int r, i; + int r, i, j; int opcode; /* Texture fetch instructions can only use gprs as source. * Also they cannot negate the source or take the absolute value */ - const boolean src_requires_loading = - (inst->Src[0].Register.File != TGSI_FILE_TEMPORARY && - inst->Src[0].Register.File != TGSI_FILE_INPUT) || - ctx->src[0].neg || ctx->src[0].abs; + const boolean src_requires_loading = tgsi_tex_src_requires_loading(ctx, 0); boolean src_loaded = FALSE; + unsigned sampler_src_reg = 1; + + src_gpr = tgsi_tex_get_src_gpr(ctx, 0); + + if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) { + /* TGSI moves the sampler to src reg 3 for TXD */ + sampler_src_reg = 3; + + for (i = 1; i < 3; i++) { + /* set gradients h/v */ + memset(&tex, 0, sizeof(struct r600_bc_tex)); + tex.inst = (i == 1) ? SQ_TEX_INST_SET_GRADIENTS_H : + SQ_TEX_INST_SET_GRADIENTS_V; + tex.sampler_id = tgsi_tex_get_src_gpr(ctx, sampler_src_reg); + tex.resource_id = tex.sampler_id + R600_MAX_CONST_BUFFERS; + + if (tgsi_tex_src_requires_loading(ctx, i)) { + tex.src_gpr = r600_get_temp(ctx); + tex.src_sel_x = 0; + tex.src_sel_y = 1; + tex.src_sel_z = 2; + tex.src_sel_w = 3; + + for (j = 0; j < 4; j++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV); + r600_bc_src(&alu.src[0], &ctx->src[i], j); + alu.dst.sel = tex.src_gpr; + alu.dst.chan = j; + if (j == 3) + alu.last = 1; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } - src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index; - - if (inst->Instruction.Opcode == TGSI_OPCODE_TXP) { + } else { + tex.src_gpr = tgsi_tex_get_src_gpr(ctx, i); + tex.src_sel_x = ctx->src[i].swizzle[0]; + tex.src_sel_y = ctx->src[i].swizzle[1]; + tex.src_sel_z = ctx->src[i].swizzle[2]; + tex.src_sel_w = ctx->src[i].swizzle[3]; + tex.src_rel = ctx->src[i].rel; + } + tex.dst_gpr = ctx->temp_reg; /* just to avoid confusing the asm scheduler */ + tex.dst_sel_x = tex.dst_sel_y = tex.dst_sel_z = tex.dst_sel_w = 7; + if (inst->Texture.Texture != TGSI_TEXTURE_RECT) { + tex.coord_type_x = 1; + tex.coord_type_y = 1; + tex.coord_type_z = 1; + tex.coord_type_w = 1; + } + r = r600_bc_add_tex(ctx->bc, &tex); + if (r) + return r; + } + } else if (inst->Instruction.Opcode == TGSI_OPCODE_TXP) { int out_chan; /* Add perspective divide */ if (ctx->bc->chiprev == CHIPREV_CAYMAN) { @@ -1954,13 +2082,24 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) } opcode = ctx->inst_info->r600_opcode; - if (opcode == SQ_TEX_INST_SAMPLE && - (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D || inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D)) - opcode = SQ_TEX_INST_SAMPLE_C; + if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D || inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D) { + switch (opcode) { + case SQ_TEX_INST_SAMPLE: + opcode = SQ_TEX_INST_SAMPLE_C; + break; + case SQ_TEX_INST_SAMPLE_L: + opcode = SQ_TEX_INST_SAMPLE_C_L; + break; + case SQ_TEX_INST_SAMPLE_G: + opcode = SQ_TEX_INST_SAMPLE_C_G; + break; + } + } memset(&tex, 0, sizeof(struct r600_bc_tex)); tex.inst = opcode; - tex.sampler_id = ctx->file_offset[inst->Src[1].Register.File] + inst->Src[1].Register.Index; + + tex.sampler_id = tgsi_tex_get_src_gpr(ctx, sampler_src_reg); tex.resource_id = tex.sampler_id + R600_MAX_CONST_BUFFERS; tex.src_gpr = src_gpr; tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Dst[0].Register.Index; @@ -3085,7 +3224,7 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = { {TGSI_OPCODE_SNE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE, tgsi_op2}, {TGSI_OPCODE_STR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_TEX, 0, SQ_TEX_INST_SAMPLE, tgsi_tex}, - {TGSI_OPCODE_TXD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TXD, 0, SQ_TEX_INST_SAMPLE_G, tgsi_tex}, {TGSI_OPCODE_TXP, 0, SQ_TEX_INST_SAMPLE, tgsi_tex}, {TGSI_OPCODE_UP2H, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_UP2US, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, @@ -3191,7 +3330,7 @@ static struct r600_shader_tgsi_instruction eg_shader_tgsi_instruction[] = { {TGSI_OPCODE_MOV, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, tgsi_op2}, {TGSI_OPCODE_LIT, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_lit}, {TGSI_OPCODE_RCP, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE, tgsi_trans_srcx_replicate}, - {TGSI_OPCODE_RSQ, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_trans_srcx_replicate}, + {TGSI_OPCODE_RSQ, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_rsq}, {TGSI_OPCODE_EXP, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_exp}, {TGSI_OPCODE_LOG, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_log}, {TGSI_OPCODE_MUL, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, tgsi_op2}, @@ -3243,7 +3382,7 @@ static struct r600_shader_tgsi_instruction eg_shader_tgsi_instruction[] = { {TGSI_OPCODE_SNE, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE, tgsi_op2}, {TGSI_OPCODE_STR, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_TEX, 0, SQ_TEX_INST_SAMPLE, tgsi_tex}, - {TGSI_OPCODE_TXD, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TXD, 0, SQ_TEX_INST_SAMPLE_G, tgsi_tex}, {TGSI_OPCODE_TXP, 0, SQ_TEX_INST_SAMPLE, tgsi_tex}, {TGSI_OPCODE_UP2H, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_UP2US, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, @@ -3401,7 +3540,7 @@ static struct r600_shader_tgsi_instruction cm_shader_tgsi_instruction[] = { {TGSI_OPCODE_SNE, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE, tgsi_op2}, {TGSI_OPCODE_STR, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_TEX, 0, SQ_TEX_INST_SAMPLE, tgsi_tex}, - {TGSI_OPCODE_TXD, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TXD, 0, SQ_TEX_INST_SAMPLE_G, tgsi_tex}, {TGSI_OPCODE_TXP, 0, SQ_TEX_INST_SAMPLE, tgsi_tex}, {TGSI_OPCODE_UP2H, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_UP2US, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h index 8f96ce5085c..76aebf2b1ea 100644 --- a/src/gallium/drivers/r600/r600_shader.h +++ b/src/gallium/drivers/r600/r600_shader.h @@ -46,6 +46,8 @@ struct r600_shader { enum radeon_family family; boolean uses_kill; boolean fs_write_all; + boolean clamp_color; + unsigned nr_cbufs; }; #endif diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index a6cfa704ca5..7c1976f12e0 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -299,6 +299,8 @@ static void *r600_create_rs_state(struct pipe_context *ctx, } rstate = &rs->rstate; + rs->clamp_vertex_color = state->clamp_vertex_color; + rs->clamp_fragment_color = state->clamp_fragment_color; rs->flatshade = state->flatshade; rs->sprite_coord_enable = state->sprite_coord_enable; @@ -374,14 +376,17 @@ static void *r600_create_rs_state(struct pipe_context *ctx, static void *r600_create_sampler_state(struct pipe_context *ctx, const struct pipe_sampler_state *state) { - struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); + struct r600_pipe_sampler_state *ss = CALLOC_STRUCT(r600_pipe_sampler_state); + struct r600_pipe_state *rstate; union util_color uc; unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 4 : 0; - if (rstate == NULL) { + if (ss == NULL) { return NULL; } + ss->seamless_cube_map = state->seamless_cube_map; + rstate = &ss->rstate; rstate->id = R600_PIPE_STATE_SAMPLER; util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); r600_pipe_state_add_reg_noblock(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0, @@ -412,7 +417,6 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c struct pipe_resource *texture, const struct pipe_sampler_view *state) { - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_pipe_sampler_view *resource = CALLOC_STRUCT(r600_pipe_sampler_view); struct r600_pipe_resource_state *rstate; const struct util_format_description *desc; @@ -422,7 +426,7 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c uint32_t word4 = 0, yuv_format = 0, pitch = 0; unsigned char swizzle[4], array_mode = 0, tile_type = 0; struct r600_bo *bo[2]; - unsigned height, depth; + unsigned width, height, depth, offset_level, last_level; if (resource == NULL) return NULL; @@ -448,7 +452,7 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c } desc = util_format_description(state->format); if (desc == NULL) { - R600_ERR("unknow format %d\n", state->format); + R600_ERR("unknown format %d\n", state->format); } tmp = (struct r600_resource_texture *)texture; if (tmp->depth && !tmp->is_flushing_texture) { @@ -464,12 +468,18 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c rbuffer = &tmp->resource; bo[0] = rbuffer->bo; bo[1] = rbuffer->bo; - pitch = align(tmp->pitch_in_blocks[0] * util_format_get_blockwidth(state->format), 8); - array_mode = tmp->array_mode[0]; + + offset_level = state->u.tex.first_level; + last_level = state->u.tex.last_level - offset_level; + width = u_minify(texture->width0, offset_level); + height = u_minify(texture->height0, offset_level); + depth = u_minify(texture->depth0, offset_level); + + pitch = align(tmp->pitch_in_blocks[offset_level] * + util_format_get_blockwidth(state->format), 8); + array_mode = tmp->array_mode[offset_level]; tile_type = tmp->tile_type; - height = texture->height0; - depth = texture->depth0; if (texture->target == PIPE_TEXTURE_1D_ARRAY) { height = 1; depth = texture->array_size; @@ -484,18 +494,18 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c S_038000_TILE_MODE(array_mode) | S_038000_TILE_TYPE(tile_type) | S_038000_PITCH((pitch / 8) - 1) | - S_038000_TEX_WIDTH(texture->width0 - 1)); + S_038000_TEX_WIDTH(width - 1)); rstate->val[1] = (S_038004_TEX_HEIGHT(height - 1) | S_038004_TEX_DEPTH(depth - 1) | S_038004_DATA_FORMAT(format)); - rstate->val[2] = (tmp->offset[0] + r600_bo_offset(bo[0])) >> 8; - rstate->val[3] = (tmp->offset[1] + r600_bo_offset(bo[1])) >> 8; + rstate->val[2] = (tmp->offset[offset_level] + r600_bo_offset(bo[0])) >> 8; + rstate->val[3] = (tmp->offset[offset_level+1] + r600_bo_offset(bo[1])) >> 8; rstate->val[4] = (word4 | S_038010_SRF_MODE_ALL(V_038010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) | S_038010_REQUEST_SIZE(1) | S_038010_ENDIAN_SWAP(endian) | - S_038010_BASE_LEVEL(state->u.tex.first_level)); - rstate->val[5] = (S_038014_LAST_LEVEL(state->u.tex.last_level) | + S_038010_BASE_LEVEL(0)); + rstate->val[5] = (S_038014_LAST_LEVEL(last_level) | S_038014_BASE_ARRAY(state->u.tex.first_layer) | S_038014_LAST_ARRAY(state->u.tex.last_layer)); rstate->val[6] = (S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE) | @@ -524,13 +534,16 @@ static void r600_set_ps_sampler_view(struct pipe_context *ctx, unsigned count, struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_pipe_sampler_view **resource = (struct r600_pipe_sampler_view **)views; int i; + int has_depth = 0; for (i = 0; i < count; i++) { if (&rctx->ps_samplers.views[i]->base != views[i]) { - if (resource[i]) + if (resource[i]) { + if (((struct r600_resource_texture *)resource[i]->base.texture)->depth) + has_depth = 1; r600_context_pipe_state_set_ps_resource(&rctx->ctx, &resource[i]->state, i + R600_MAX_CONST_BUFFERS); - else + } else r600_context_pipe_state_set_ps_resource(&rctx->ctx, NULL, i + R600_MAX_CONST_BUFFERS); @@ -538,6 +551,11 @@ static void r600_set_ps_sampler_view(struct pipe_context *ctx, unsigned count, (struct pipe_sampler_view **)&rctx->ps_samplers.views[i], views[i]); + } else { + if (resource[i]) { + if (((struct r600_resource_texture *)resource[i]->base.texture)->depth) + has_depth = 1; + } } } for (i = count; i < NUM_TEX_UNITS; i++) { @@ -547,30 +565,61 @@ static void r600_set_ps_sampler_view(struct pipe_context *ctx, unsigned count, pipe_sampler_view_reference((struct pipe_sampler_view **)&rctx->ps_samplers.views[i], NULL); } } + rctx->have_depth_texture = has_depth; rctx->ps_samplers.n_views = count; } +static void r600_set_seamless_cubemap(struct r600_pipe_context *rctx, boolean enable) +{ + struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); + if (rstate == NULL) + return; + + rstate->id = R600_PIPE_STATE_SEAMLESS_CUBEMAP; + r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX, + (enable ? 0 : S_009508_DISABLE_CUBE_WRAP(1)), + 1, NULL); + + free(rctx->states[R600_PIPE_STATE_SEAMLESS_CUBEMAP]); + rctx->states[R600_PIPE_STATE_SEAMLESS_CUBEMAP] = rstate; + r600_context_pipe_state_set(&rctx->ctx, rstate); +} + static void r600_bind_ps_sampler(struct pipe_context *ctx, unsigned count, void **states) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_state **rstates = (struct r600_pipe_state **)states; + struct r600_pipe_sampler_state **sstates = (struct r600_pipe_sampler_state **)states; + int seamless = -1; memcpy(rctx->ps_samplers.samplers, states, sizeof(void*) * count); rctx->ps_samplers.n_samplers = count; for (int i = 0; i < count; i++) { - r600_context_pipe_state_set_ps_sampler(&rctx->ctx, rstates[i], i); + r600_context_pipe_state_set_ps_sampler(&rctx->ctx, &sstates[i]->rstate, i); + + if (sstates[i]) + seamless = sstates[i]->seamless_cube_map; } + + if (seamless != -1) + r600_set_seamless_cubemap(rctx, seamless); } static void r600_bind_vs_sampler(struct pipe_context *ctx, unsigned count, void **states) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_state **rstates = (struct r600_pipe_state **)states; + struct r600_pipe_sampler_state **sstates = (struct r600_pipe_sampler_state **)states; + int seamless = -1; for (int i = 0; i < count; i++) { - r600_context_pipe_state_set_vs_sampler(&rctx->ctx, rstates[i], i); + r600_context_pipe_state_set_vs_sampler(&rctx->ctx, &sstates[i]->rstate, i); + + if (sstates[i]) + seamless = sstates[i]->seamless_cube_map; } + + if (seamless != -1) + r600_set_seamless_cubemap(rctx, seamless); } static void r600_set_clip_state(struct pipe_context *ctx, @@ -730,6 +779,9 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta surf = (struct r600_surface *)state->cbufs[cb]; rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture; + if (rtex->depth) + rctx->have_depth_fb = TRUE; + if (rtex->depth && !rtex->is_flushing_texture) { r600_texture_depth_flush(&rctx->context, state->cbufs[cb]->texture, TRUE); rtex = rtex->flushed_depth_texture; @@ -892,6 +944,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, util_copy_framebuffer_state(&rctx->framebuffer, state); /* build states */ + rctx->have_depth_fb = 0; for (int i = 0; i < state->nr_cbufs; i++) { r600_cb(rctx, rstate, state, i); } @@ -1031,6 +1084,46 @@ void r600_init_state_functions(struct r600_pipe_context *rctx) rctx->context.texture_barrier = r600_texture_barrier; } +void r600_adjust_gprs(struct r600_pipe_context *rctx) +{ + enum radeon_family family; + struct r600_pipe_state rstate; + unsigned num_ps_gprs = rctx->default_ps_gprs; + unsigned num_vs_gprs = rctx->default_vs_gprs; + unsigned tmp; + int diff; + + family = r600_get_family(rctx->radeon); + + if (family >= CHIP_CEDAR) + return; + + if (!rctx->ps_shader && !rctx->vs_shader) + return; + + if (rctx->ps_shader->shader.bc.ngpr > rctx->default_ps_gprs) + { + diff = rctx->ps_shader->shader.bc.ngpr - rctx->default_ps_gprs; + num_vs_gprs -= diff; + num_ps_gprs += diff; + } + + if (rctx->vs_shader->shader.bc.ngpr > rctx->default_vs_gprs) + { + diff = rctx->vs_shader->shader.bc.ngpr - rctx->default_vs_gprs; + num_ps_gprs -= diff; + num_vs_gprs += diff; + } + + tmp = 0; + tmp |= S_008C04_NUM_PS_GPRS(num_ps_gprs); + tmp |= S_008C04_NUM_VS_GPRS(num_vs_gprs); + rstate.nregs = 0; + r600_pipe_state_add_reg(&rstate, R_008C04_SQ_GPR_RESOURCE_MGMT_1, tmp, 0x0FFFFFFF, NULL); + + r600_context_pipe_state_set(&rctx->ctx, &rstate); +} + void r600_init_config(struct r600_pipe_context *rctx) { int ps_prio; @@ -1173,6 +1266,9 @@ void r600_init_config(struct r600_pipe_context *rctx) break; } + rctx->default_ps_gprs = num_ps_gprs; + rctx->default_vs_gprs = num_vs_gprs; + rstate->id = R600_PIPE_STATE_CONFIG; /* SQ_CONFIG */ @@ -1206,7 +1302,7 @@ void r600_init_config(struct r600_pipe_context *rctx) /* SQ_GPR_RESOURCE_MGMT_2 */ tmp = 0; tmp |= S_008C08_NUM_GS_GPRS(num_gs_gprs); - tmp |= S_008C08_NUM_GS_GPRS(num_es_gprs); + tmp |= S_008C08_NUM_ES_GPRS(num_es_gprs); r600_pipe_state_add_reg(rstate, R_008C08_SQ_GPR_RESOURCE_MGMT_2, tmp, 0xFFFFFFFF, NULL); /* SQ_THREAD_RESOURCE_MGMT */ @@ -1234,14 +1330,22 @@ void r600_init_config(struct r600_pipe_context *rctx) if (family >= CHIP_RV770) { r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x00004000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX, 0x07000002, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX, + S_009508_DISABLE_CUBE_ANISO(1) | + S_009508_SYNC_GRADIENT(1) | + S_009508_SYNC_WALKER(1) | + S_009508_SYNC_ALIGNER(1), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_009830_DB_DEBUG, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_009838_DB_WATERMARKS, 0x00420204, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286C8_SPI_THREAD_GROUPING, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL, 0x00514002, 0xFFFFFFFF, NULL); } else { r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX, 0x07000003, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX, + S_009508_DISABLE_CUBE_ANISO(1) | + S_009508_SYNC_GRADIENT(1) | + S_009508_SYNC_WALKER(1) | + S_009508_SYNC_ALIGNER(1), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_009830_DB_DEBUG, 0x82000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_009838_DB_WATERMARKS, 0x01020204, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286C8_SPI_THREAD_GROUPING, 0x00000001, 0xFFFFFFFF, NULL); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index a670ac02be2..d9140403e5a 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -28,6 +28,7 @@ #include <util/u_format.h> #include <pipebuffer/pb_buffer.h> #include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_parse.h" #include "r600_formats.h" #include "r600_pipe.h" #include "r600d.h" @@ -99,6 +100,8 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state) if (state == NULL) return; + rctx->clamp_vertex_color = rs->clamp_vertex_color; + rctx->clamp_fragment_color = rs->clamp_fragment_color; rctx->flatshade = rs->flatshade; rctx->sprite_coord_enable = rs->sprite_coord_enable; rctx->rasterizer = rs; @@ -112,7 +115,7 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state) r600_polygon_offset_update(rctx); } if (rctx->ps_shader && rctx->vs_shader) - r600_spi_update(rctx); + rctx->spi_dirty = true; } void r600_delete_rs_state(struct pipe_context *ctx, void *state) @@ -257,7 +260,9 @@ void *r600_create_shader_state(struct pipe_context *ctx, struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader); int r; - r = r600_pipe_shader_create(ctx, shader, state->tokens); + shader->tokens = tgsi_dup_tokens(state->tokens); + + r = r600_pipe_shader_create(ctx, shader); if (r) { return NULL; } @@ -273,8 +278,10 @@ void r600_bind_ps_shader(struct pipe_context *ctx, void *state) if (state) { r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_shader->rstate); } - if (rctx->ps_shader && rctx->vs_shader) - r600_spi_update(rctx); + if (rctx->ps_shader && rctx->vs_shader) { + rctx->spi_dirty = true; + r600_adjust_gprs(rctx); + } } void r600_bind_vs_shader(struct pipe_context *ctx, void *state) @@ -286,8 +293,10 @@ void r600_bind_vs_shader(struct pipe_context *ctx, void *state) if (state) { r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_shader->rstate); } - if (rctx->ps_shader && rctx->vs_shader) - r600_spi_update(rctx); + if (rctx->ps_shader && rctx->vs_shader) { + rctx->spi_dirty = true; + r600_adjust_gprs(rctx); + } } void r600_delete_ps_shader(struct pipe_context *ctx, void *state) @@ -299,6 +308,7 @@ void r600_delete_ps_shader(struct pipe_context *ctx, void *state) rctx->ps_shader = NULL; } + free(shader->tokens); r600_pipe_shader_destroy(ctx, shader); free(shader); } @@ -312,6 +322,7 @@ void r600_delete_vs_shader(struct pipe_context *ctx, void *state) rctx->vs_shader = NULL; } + free(shader->tokens); r600_pipe_shader_destroy(ctx, shader); free(shader); } @@ -347,14 +358,23 @@ static void r600_spi_update(struct r600_pipe_context *rctx) struct r600_pipe_shader *shader = rctx->ps_shader; struct r600_pipe_state *rstate = &rctx->spi; struct r600_shader *rshader = &shader->shader; - unsigned i, tmp; + unsigned i, tmp, sid; if (rctx->spi.id == 0) r600_spi_block_init(rctx, &rctx->spi); rstate->nregs = 0; for (i = 0; i < rshader->ninput; i++) { - tmp = S_028644_SEMANTIC(r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i)); + if (rshader->input[i].name == TGSI_SEMANTIC_POSITION || + rshader->input[i].name == TGSI_SEMANTIC_FACE) + if (rctx->family >= CHIP_CEDAR) + continue; + else + sid=0; + else + sid=r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i); + + tmp = S_028644_SEMANTIC(sid); if (rshader->input[i].name == TGSI_SEMANTIC_COLOR || rshader->input[i].name == TGSI_SEMANTIC_BCOLOR || @@ -378,6 +398,7 @@ static void r600_spi_update(struct r600_pipe_context *rctx) r600_pipe_state_mod_reg(rstate, tmp); } + rctx->spi_dirty = false; r600_context_pipe_state_set(&rctx->ctx, rstate); } @@ -517,21 +538,39 @@ static void r600_vertex_buffer_update(struct r600_pipe_context *rctx) } } +static int r600_shader_rebuild(struct pipe_context * ctx, struct r600_pipe_shader * shader) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + int r; + + r600_pipe_shader_destroy(ctx, shader); + r = r600_pipe_shader_create(ctx, shader); + if (r) { + return r; + } + r600_context_pipe_state_set(&rctx->ctx, &shader->rstate); + + return 0; +} + void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_resource *rbuffer; - u32 vgt_dma_index_type, vgt_dma_swap_mode, vgt_draw_initiator, mask; struct r600_draw rdraw; - struct r600_drawl draw = {}; - unsigned prim; + struct r600_drawl draw; + unsigned prim, mask; - r600_flush_depth_textures(rctx); - u_vbuf_mgr_draw_begin(rctx->vbuf_mgr, info, NULL, NULL); + if (!rctx->blit) { + if (rctx->have_depth_fb || rctx->have_depth_texture) + r600_flush_depth_textures(rctx); + } + u_vbuf_mgr_draw_begin(rctx->vbuf_mgr, info); r600_vertex_buffer_update(rctx); draw.info = *info; draw.ctx = ctx; + draw.index_buffer = NULL; if (info->indexed && rctx->index_buffer.buffer) { draw.info.start += rctx->index_buffer.offset / rctx->index_buffer.index_size; pipe_resource_reference(&draw.index_buffer, rctx->index_buffer.buffer); @@ -549,57 +588,29 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) r600_upload_index_buffer(rctx, &draw); } } else { + draw.index_size = 0; + draw.index_buffer_offset = 0; draw.info.index_bias = info->start; } - vgt_dma_swap_mode = 0; - switch (draw.index_size) { - case 2: - vgt_draw_initiator = 0; - vgt_dma_index_type = 0; - if (R600_BIG_ENDIAN) { - vgt_dma_swap_mode = ENDIAN_8IN16; - } - break; - case 4: - vgt_draw_initiator = 0; - vgt_dma_index_type = 1; - if (R600_BIG_ENDIAN) { - vgt_dma_swap_mode = ENDIAN_8IN32; - } - break; - case 0: - vgt_draw_initiator = 2; - vgt_dma_index_type = 0; - break; - default: - R600_ERR("unsupported index size %d\n", draw.index_size); - return; - } if (r600_conv_pipe_prim(draw.info.mode, &prim)) return; - if (unlikely(rctx->ps_shader == NULL)) { - R600_ERR("missing vertex shader\n"); - return; - } - if (unlikely(rctx->vs_shader == NULL)) { - R600_ERR("missing vertex shader\n"); - return; - } - /* there should be enough input */ - if (rctx->vertex_elements->count < rctx->vs_shader->shader.bc.nresource) { - R600_ERR("%d resources provided, expecting %d\n", - rctx->vertex_elements->count, rctx->vs_shader->shader.bc.nresource); - return; - } + + if (rctx->vs_shader->shader.clamp_color != rctx->clamp_vertex_color) + r600_shader_rebuild(ctx, rctx->vs_shader); + + if ((rctx->ps_shader->shader.clamp_color != rctx->clamp_fragment_color) || + ((rctx->family >= CHIP_CEDAR) && rctx->ps_shader->shader.fs_write_all && + (rctx->ps_shader->shader.nr_cbufs != rctx->nr_cbufs))) + r600_shader_rebuild(ctx, rctx->ps_shader); + + if (rctx->spi_dirty) + r600_spi_update(rctx); if (rctx->alpha_ref_dirty) r600_update_alpha_ref(rctx); - mask = 0; - for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) { - mask |= (0xF << (i * 4)); - } + mask = (1ULL << ((unsigned)rctx->framebuffer.nr_cbufs * 4)) - 1; if (rctx->vgt.id != R600_PIPE_STATE_VGT) { rctx->vgt.id = R600_PIPE_STATE_VGT; @@ -633,8 +644,10 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) rdraw.vgt_num_indices = draw.info.count; rdraw.vgt_num_instances = draw.info.instance_count; - rdraw.vgt_index_type = vgt_dma_index_type | (vgt_dma_swap_mode << 2); - rdraw.vgt_draw_initiator = vgt_draw_initiator; + rdraw.vgt_index_type = ((draw.index_size == 4) ? 1 : 0); + if (R600_BIG_ENDIAN) + rdraw.vgt_index_type |= (draw.index_size >> 1) << 2; + rdraw.vgt_draw_initiator = draw.index_size ? 0 : 2; rdraw.indices = NULL; if (draw.index_buffer) { rbuffer = (struct r600_resource*)draw.index_buffer; diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h index acd41a21214..8711dbf1720 100644 --- a/src/gallium/drivers/r600/r600_state_inlines.h +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -284,7 +284,7 @@ static inline uint32_t r600_translate_dbformat(enum pipe_format format) static inline uint32_t r600_translate_colorswap(enum pipe_format format) { switch (format) { - /* 8-bit buffers. */ + /* 8-bit buffers. */ case PIPE_FORMAT_A8_UNORM: return V_0280A0_SWAP_ALT_REV; case PIPE_FORMAT_I8_UNORM: @@ -297,7 +297,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_L4A4_UNORM: return V_0280A0_SWAP_ALT; - /* 16-bit buffers. */ + /* 16-bit buffers. */ case PIPE_FORMAT_B5G6R5_UNORM: return V_0280A0_SWAP_STD_REV; @@ -320,9 +320,10 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_R16_UNORM: case PIPE_FORMAT_R16_SNORM: + case PIPE_FORMAT_R16_FLOAT: return V_0280A0_SWAP_STD; - /* 32-bit buffers. */ + /* 32-bit buffers. */ case PIPE_FORMAT_A8B8G8R8_SRGB: return V_0280A0_SWAP_STD_REV; @@ -368,13 +369,13 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_R32_FLOAT: return V_0280A0_SWAP_STD; - /* 64-bit buffers. */ + /* 64-bit buffers. */ case PIPE_FORMAT_R32G32_FLOAT: case PIPE_FORMAT_R16G16B16A16_UNORM: case PIPE_FORMAT_R16G16B16A16_SNORM: case PIPE_FORMAT_R16G16B16A16_FLOAT: - /* 128-bit buffers. */ + /* 128-bit buffers. */ case PIPE_FORMAT_R32G32B32A32_FLOAT: case PIPE_FORMAT_R32G32B32A32_SNORM: case PIPE_FORMAT_R32G32B32A32_UNORM: @@ -392,7 +393,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_L4A4_UNORM: return V_0280A0_COLOR_4_4; - /* 8-bit buffers. */ + /* 8-bit buffers. */ case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: case PIPE_FORMAT_L8_UNORM: @@ -401,7 +402,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R8_SNORM: return V_0280A0_COLOR_8; - /* 16-bit buffers. */ + /* 16-bit buffers. */ case PIPE_FORMAT_B5G6R5_UNORM: return V_0280A0_COLOR_5_6_5; @@ -425,7 +426,10 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R16_SNORM: return V_0280A0_COLOR_16; - /* 32-bit buffers. */ + case PIPE_FORMAT_R16_FLOAT: + return V_0280A0_COLOR_16_FLOAT; + + /* 32-bit buffers. */ case PIPE_FORMAT_A8B8G8R8_SRGB: case PIPE_FORMAT_A8B8G8R8_UNORM: case PIPE_FORMAT_A8R8G8B8_UNORM: @@ -468,7 +472,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R11G11B10_FLOAT: return V_0280A0_COLOR_10_11_11_FLOAT; - /* 64-bit buffers. */ + /* 64-bit buffers. */ case PIPE_FORMAT_R16G16B16_USCALED: case PIPE_FORMAT_R16G16B16A16_USCALED: case PIPE_FORMAT_R16G16B16_SSCALED: @@ -488,20 +492,21 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R32G32_SSCALED: return V_0280A0_COLOR_32_32; - /* 128-bit buffers. */ + /* 96-bit buffers. */ case PIPE_FORMAT_R32G32B32_FLOAT: return V_0280A0_COLOR_32_32_32_FLOAT; + + /* 128-bit buffers. */ case PIPE_FORMAT_R32G32B32A32_FLOAT: return V_0280A0_COLOR_32_32_32_32_FLOAT; case PIPE_FORMAT_R32G32B32A32_SNORM: case PIPE_FORMAT_R32G32B32A32_UNORM: return V_0280A0_COLOR_32_32_32_32; - /* YUV buffers. */ + /* YUV buffers. */ case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: default: - /* R600_ERR("unsupported color format %d %s\n", format, util_format_name(format)); */ return ~0; /* Unsupported. */ } } @@ -513,11 +518,11 @@ static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) case V_0280A0_COLOR_4_4: return(ENDIAN_NONE); - /* 8-bit buffers. */ + /* 8-bit buffers. */ case V_0280A0_COLOR_8: return(ENDIAN_NONE); - /* 16-bit buffers. */ + /* 16-bit buffers. */ case V_0280A0_COLOR_5_6_5: case V_0280A0_COLOR_1_5_5_5: case V_0280A0_COLOR_4_4_4_4: @@ -525,7 +530,7 @@ static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) case V_0280A0_COLOR_8_8: return(ENDIAN_8IN16); - /* 32-bit buffers. */ + /* 32-bit buffers. */ case V_0280A0_COLOR_8_8_8_8: case V_0280A0_COLOR_2_10_10_10: case V_0280A0_COLOR_8_24: @@ -535,7 +540,7 @@ static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) case V_0280A0_COLOR_16_16: return(ENDIAN_8IN32); - /* 64-bit buffers. */ + /* 64-bit buffers. */ case V_0280A0_COLOR_16_16_16_16: case V_0280A0_COLOR_16_16_16_16_FLOAT: return(ENDIAN_8IN16); @@ -544,7 +549,7 @@ static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) case V_0280A0_COLOR_32_32: return(ENDIAN_8IN32); - /* 128-bit buffers. */ + /* 128-bit buffers. */ case V_0280A0_COLOR_32_32_32_FLOAT: case V_0280A0_COLOR_32_32_32_32_FLOAT: case V_0280A0_COLOR_32_32_32_32: @@ -565,7 +570,7 @@ static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *scree static INLINE boolean r600_is_colorbuffer_format_supported(enum pipe_format format) { return r600_translate_colorformat(format) != ~0 && - r600_translate_colorswap(format) != ~0; + r600_translate_colorswap(format) != ~0; } static INLINE boolean r600_is_zs_format_supported(enum pipe_format format) diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 77cdd8dc33d..854761d17cb 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -243,10 +243,11 @@ static void r600_setup_miptree(struct pipe_screen *screen, struct radeon *radeon = (struct radeon *)screen->winsys; enum chip_class chipc = r600_get_family_class(radeon); unsigned size, layer_size, i, offset; - unsigned nblocksx, nblocksy; + unsigned nblocksx, nblocksy, extra_size = 0; for (i = 0, offset = 0; i <= ptex->last_level; i++) { unsigned blocksize = util_format_get_blocksize(ptex->format); + unsigned base_align = r600_get_base_alignment(screen, ptex->format, array_mode); r600_texture_set_array_mode(screen, rtex, i, array_mode); @@ -265,9 +266,13 @@ static void r600_setup_miptree(struct pipe_screen *screen, else size = layer_size * ptex->array_size; + /* evergreen stores depth and stencil separately */ + if ((chipc >= EVERGREEN) && util_format_is_depth_or_stencil(ptex->format)) + extra_size = align(extra_size + (nblocksx * nblocksy * 1), base_align); + /* align base image and start of miptree */ if ((i == 0) || (i == 1)) - offset = align(offset, r600_get_base_alignment(screen, ptex->format, array_mode)); + offset = align(offset, base_align); rtex->offset[i] = offset; rtex->layer_size[i] = layer_size; rtex->pitch_in_blocks[i] = nblocksx; /* CB talks in elements */ @@ -275,7 +280,7 @@ static void r600_setup_miptree(struct pipe_screen *screen, offset += size; } - rtex->size = offset; + rtex->size = offset + extra_size; } /* Figure out whether u_blitter will fallback to a transfer operation. @@ -1091,8 +1096,9 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, goto out_word4; } } - + goto out_unknown; } + out_word4: if (word4_p) *word4_p = word4; diff --git a/src/gallium/drivers/r600/r600_translate.c b/src/gallium/drivers/r600/r600_translate.c index 7482d15e12f..307fd57e21a 100644 --- a/src/gallium/drivers/r600/r600_translate.c +++ b/src/gallium/drivers/r600/r600_translate.c @@ -48,6 +48,7 @@ void r600_translate_index_buffer(struct r600_pipe_context *r600, &r600->context, *index_buffer, 0, *start, count, ptr); pipe_resource_reference(index_buffer, out_buffer); + pipe_resource_reference(&out_buffer, NULL); *index_size = 2; *start = out_offset / 2; break; diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index 9281b08bd82..f6eec24cc05 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -2556,6 +2556,9 @@ #define S_009508_DISABLE_CUBE_WRAP(x) (((x) & 0x1) << 0) #define G_009508_DISABLE_CUBE_WRAP(x) (((x) >> 0) & 0x1) #define C_009508_DISABLE_CUBE_WRAP 0xFFFFFFFE +#define S_009508_DISABLE_CUBE_ANISO(x) (((x) & 0x1) << 1) +#define G_009508_DISABLE_CUBE_ANISO(x) (((x) >> 1) & 0x1) +#define C_009508_DISABLE_CUBE_ANISO (~(1 << 1)) #define S_009508_SYNC_GRADIENT(x) (((x) & 0x1) << 24) #define G_009508_SYNC_GRADIENT(x) (((x) >> 24) & 0x1) #define C_009508_SYNC_GRADIENT 0xFEFFFFFF @@ -3465,9 +3468,14 @@ #define SQ_TEX_INST_LD 0x03 #define SQ_TEX_INST_GET_GRADIENTS_H 0x7 #define SQ_TEX_INST_GET_GRADIENTS_V 0x8 +#define SQ_TEX_INST_SET_GRADIENTS_H 0xB +#define SQ_TEX_INST_SET_GRADIENTS_V 0xC #define SQ_TEX_INST_SAMPLE 0x10 #define SQ_TEX_INST_SAMPLE_L 0x11 +#define SQ_TEX_INST_SAMPLE_G 0x14 #define SQ_TEX_INST_SAMPLE_C 0x18 +#define SQ_TEX_INST_SAMPLE_C_L 0x19 +#define SQ_TEX_INST_SAMPLE_C_G 0x1C #endif diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c index dbbc249258d..cfb1b9d8d0d 100644 --- a/src/gallium/drivers/svga/svga_context.c +++ b/src/gallium/drivers/svga/svga_context.c @@ -207,6 +207,14 @@ void svga_context_flush( struct svga_context *svga, svga->curr.nr_fbs = 0; + /* Flush the upload managers to ensure recycling of upload buffers + * without throttling. This should really be conditioned on + * pipe_buffer_map_range not supporting PIPE_TRANSFER_UNSYNCHRONIZED. + */ + + u_upload_flush(svga->upload_vb); + u_upload_flush(svga->upload_ib); + /* Ensure that texture dma uploads are processed * before submitting commands. */ diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index eca529d262e..34b9e85c1a3 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -372,9 +372,6 @@ struct svga_context /** List of buffers with queued transfers */ struct list_head dirty_buffers; - - /** Was the previous draw done with the SW path? */ - boolean prev_draw_swtnl; }; /* A flag for each state_tracker state object: diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c index d8af615ede1..aa096692888 100644 --- a/src/gallium/drivers/svga/svga_draw.c +++ b/src/gallium/drivers/svga/svga_draw.c @@ -145,7 +145,7 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl ) unsigned i; /* Unmap upload manager vertex buffers */ - u_upload_flush(svga->upload_vb); + u_upload_unmap(svga->upload_vb); for (i = 0; i < hwtnl->cmd.vdecl_count; i++) { handle = svga_buffer_handle(svga, hwtnl->cmd.vdecl_vb[i]); @@ -156,7 +156,7 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl ) } /* Unmap upload manager index buffers */ - u_upload_flush(svga->upload_ib); + u_upload_unmap(svga->upload_ib); for (i = 0; i < hwtnl->cmd.prim_count; i++) { if (hwtnl->cmd.prim_ib[i]) { @@ -242,6 +242,11 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl ) } +void svga_hwtnl_set_index_bias( struct svga_hwtnl *hwtnl, + int index_bias) +{ + hwtnl->index_bias = index_bias; +} @@ -265,15 +270,16 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl, unsigned size = vb ? vb->width0 : 0; unsigned offset = hwtnl->cmd.vdecl[i].array.offset; unsigned stride = hwtnl->cmd.vdecl[i].array.stride; - unsigned index_bias = range->indexBias; + int index_bias = (int) range->indexBias + hwtnl->index_bias; unsigned width; assert(vb); assert(size); assert(offset < size); - assert(index_bias >= 0); assert(min_index <= max_index); - assert(offset + index_bias*stride < size); + if (index_bias >= 0) { + assert(offset + index_bias*stride < size); + } if (min_index != ~0) { assert(offset + (index_bias + min_index) * stride < size); } @@ -394,6 +400,7 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl, hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index; hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range; + hwtnl->cmd.prim[hwtnl->cmd.prim_count].indexBias += hwtnl->index_bias; pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib); hwtnl->cmd.prim_count++; diff --git a/src/gallium/drivers/svga/svga_draw.h b/src/gallium/drivers/svga/svga_draw.h index a2403d802be..1dac17421e1 100644 --- a/src/gallium/drivers/svga/svga_draw.h +++ b/src/gallium/drivers/svga/svga_draw.h @@ -79,5 +79,8 @@ svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl, enum pipe_error svga_hwtnl_flush( struct svga_hwtnl *hwtnl ); +void svga_hwtnl_set_index_bias( struct svga_hwtnl *hwtnl, + int index_bias); + #endif /* SVGA_DRAW_H_ */ diff --git a/src/gallium/drivers/svga/svga_draw_private.h b/src/gallium/drivers/svga/svga_draw_private.h index ca658ac6745..8126f7ee23c 100644 --- a/src/gallium/drivers/svga/svga_draw_private.h +++ b/src/gallium/drivers/svga/svga_draw_private.h @@ -116,6 +116,13 @@ struct draw_cmd { struct svga_hwtnl { struct svga_context *svga; struct u_upload_mgr *upload_ib; + + /* Additional negative index bias due to partial buffer uploads + * This is compensated for in the offset associated with all + * vertex buffers. + */ + + int index_bias; /* Flatshade information: */ diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c index 2093bcae101..d53edcb23c5 100644 --- a/src/gallium/drivers/svga/svga_pipe_draw.c +++ b/src/gallium/drivers/svga/svga_pipe_draw.c @@ -25,6 +25,7 @@ #include "svga_cmd.h" +#include "util/u_format.h" #include "util/u_inlines.h" #include "util/u_prim.h" #include "util/u_time.h" @@ -37,6 +38,178 @@ #include "svga_state.h" #include "svga_swtnl.h" #include "svga_debug.h" +#include "svga_resource_buffer.h" +#include "util/u_upload_mgr.h" + +/** + * Determine the ranges to upload for the user-buffers referenced + * by the next draw command. + * + * TODO: It might be beneficial to support multiple ranges. In that case, + * the struct svga_buffer::uploaded member should be made an array or a + * list, since we need to account for the possibility that different ranges + * may be uploaded to different hardware buffers chosen by the utility + * upload manager. + */ + +static void +svga_user_buffer_range(struct svga_context *svga, + unsigned start, + unsigned count, + unsigned instance_count) +{ + const struct pipe_vertex_element *ve = svga->curr.velems->velem; + int i; + + /* + * Release old uploaded range (if not done already) and + * initialize new ranges. + */ + + for (i=0; i < svga->curr.velems->count; i++) { + struct pipe_vertex_buffer *vb = + &svga->curr.vb[ve[i].vertex_buffer_index]; + + if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) { + struct svga_buffer *buffer = svga_buffer(vb->buffer); + + pipe_resource_reference(&buffer->uploaded.buffer, NULL); + buffer->uploaded.start = ~0; + buffer->uploaded.end = 0; + } + } + + for (i=0; i < svga->curr.velems->count; i++) { + struct pipe_vertex_buffer *vb = + &svga->curr.vb[ve[i].vertex_buffer_index]; + + if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) { + struct svga_buffer *buffer = svga_buffer(vb->buffer); + unsigned first, size; + unsigned instance_div = ve[i].instance_divisor; + unsigned elemSize = util_format_get_blocksize(ve[i].src_format); + + svga->dirty |= SVGA_NEW_VBUFFER; + + if (instance_div) { + first = ve[i].src_offset; + count = (instance_count + instance_div - 1) / instance_div; + size = vb->stride * (count - 1) + elemSize; + } else if (vb->stride) { + first = vb->stride * start + ve[i].src_offset; + size = vb->stride * (count - 1) + elemSize; + } else { + /* Only a single vertex! + * Upload with the largest vertex size the hw supports, + * if possible. + */ + first = ve[i].src_offset; + size = MIN2(16, vb->buffer->width0); + } + + buffer->uploaded.start = MIN2(buffer->uploaded.start, first); + buffer->uploaded.end = MAX2(buffer->uploaded.end, first + size); + } + } +} + +/** + * svga_upload_user_buffers - upload parts of user buffers + * + * This function streams a part of a user buffer to hw and fills + * svga_buffer::uploaded with information on the upload. + */ + +static int +svga_upload_user_buffers(struct svga_context *svga, + unsigned start, + unsigned count, + unsigned instance_count) +{ + const struct pipe_vertex_element *ve = svga->curr.velems->velem; + unsigned i; + int ret; + + svga_user_buffer_range(svga, start, count, instance_count); + + for (i=0; i < svga->curr.velems->count; i++) { + struct pipe_vertex_buffer *vb = + &svga->curr.vb[ve[i].vertex_buffer_index]; + + if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) { + struct svga_buffer *buffer = svga_buffer(vb->buffer); + boolean flushed; + + /* + * Check if already uploaded. Otherwise go ahead and upload. + */ + + if (buffer->uploaded.buffer) + continue; + + ret = u_upload_buffer( svga->upload_vb, + 0, + buffer->uploaded.start, + buffer->uploaded.end - buffer->uploaded.start, + &buffer->b.b, + &buffer->uploaded.offset, + &buffer->uploaded.buffer, + &flushed); + + if (ret) + return ret; + + if (0) + debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sofs %d" + " sz %d\n", + __FUNCTION__, + i, + buffer, + buffer->uploaded.buffer, + buffer->uploaded.offset, + buffer->uploaded.start, + buffer->uploaded.end - buffer->uploaded.start); + + vb->buffer_offset = buffer->uploaded.offset; + } + } + + return PIPE_OK; +} + +/** + * svga_release_user_upl_buffers - release uploaded parts of user buffers + * + * This function releases the hw copy of the uploaded fraction of the + * user-buffer. It's important to do this as soon as all draw calls + * affecting the uploaded fraction are issued, as this allows for + * efficient reuse of the hardware surface backing the uploaded fraction. + * + * svga_buffer::source_offset is set to 0, and svga_buffer::uploaded::buffer + * is set to 0. + */ + +static void +svga_release_user_upl_buffers(struct svga_context *svga) +{ + unsigned i; + unsigned nr; + + nr = svga->curr.num_vertex_buffers; + + for (i = 0; i < nr; ++i) { + struct pipe_vertex_buffer *vb = &svga->curr.vb[i]; + + if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) { + struct svga_buffer *buffer = svga_buffer(vb->buffer); + + buffer->uploaded.start = ~0; + buffer->uploaded.end = 0; + if (buffer->uploaded.buffer) + pipe_resource_reference(&buffer->uploaded.buffer, NULL); + } + } +} @@ -50,6 +223,7 @@ retry_draw_range_elements( struct svga_context *svga, unsigned prim, unsigned start, unsigned count, + unsigned instance_count, boolean do_retry ) { enum pipe_error ret = 0; @@ -61,6 +235,10 @@ retry_draw_range_elements( struct svga_context *svga, svga->curr.rast->templ.flatshade, svga->curr.rast->templ.flatshade_first ); + ret = svga_upload_user_buffers( svga, min_index + index_bias, + max_index - min_index + 1, instance_count ); + if (ret != PIPE_OK) + goto retry; ret = svga_update_state( svga, SVGA_STATE_HW_DRAW ); if (ret) @@ -84,7 +262,7 @@ retry: index_buffer, index_size, index_bias, min_index, max_index, prim, start, count, - FALSE ); + instance_count, FALSE ); } return ret; @@ -96,6 +274,7 @@ retry_draw_arrays( struct svga_context *svga, unsigned prim, unsigned start, unsigned count, + unsigned instance_count, boolean do_retry ) { enum pipe_error ret; @@ -107,6 +286,11 @@ retry_draw_arrays( struct svga_context *svga, svga->curr.rast->templ.flatshade, svga->curr.rast->templ.flatshade_first ); + ret = svga_upload_user_buffers( svga, start, count, instance_count ); + + if (ret != PIPE_OK) + goto retry; + ret = svga_update_state( svga, SVGA_STATE_HW_DRAW ); if (ret) goto retry; @@ -127,6 +311,7 @@ retry: prim, start, count, + instance_count, FALSE ); } @@ -141,18 +326,11 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) unsigned reduced_prim = u_reduced_prim( info->mode ); unsigned count = info->count; enum pipe_error ret = 0; + boolean needed_swtnl; if (!u_trim_pipe_prim( info->mode, &count )) return; - if (svga->state.sw.need_swtnl != svga->prev_draw_swtnl) { - /* We're switching between SW and HW drawing. Do a flush to avoid - * mixing HW and SW rendering with the same vertex buffer. - */ - pipe->flush(pipe, NULL); - svga->prev_draw_swtnl = svga->state.sw.need_swtnl; - } - /* * Mark currently bound target surfaces as dirty * doesn't really matter if it is done before drawing. @@ -167,6 +345,8 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) svga->dirty |= SVGA_NEW_REDUCED_PRIMITIVE; } + needed_swtnl = svga->state.sw.need_swtnl; + svga_update_state_retry( svga, SVGA_STATE_NEED_SWTNL ); #ifdef DEBUG @@ -176,6 +356,20 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) #endif if (svga->state.sw.need_swtnl) { + if (!needed_swtnl) { + /* + * We're switching from HW to SW TNL. SW TNL will require mapping all + * currently bound vertex buffers, some of which may already be + * referenced in the current command buffer as result of previous HW + * TNL. So flush now, to prevent the context to flush while a referred + * vertex buffer is mapped. + */ + + svga_context_flush(svga, NULL); + } + + /* Avoid leaking the previous hwtnl bias to swtnl */ + svga_hwtnl_set_index_bias( svga->hwtnl, 0 ); ret = svga_swtnl_draw_vbo( svga, info ); } else { @@ -194,6 +388,7 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) info->mode, info->start + offset, info->count, + info->instance_count, TRUE ); } else { @@ -201,10 +396,13 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) info->mode, info->start, info->count, + info->instance_count, TRUE ); } } + svga_release_user_upl_buffers( svga ); + if (SVGA_DEBUG & DEBUG_FLUSH) { svga_hwtnl_flush_retry( svga ); svga_context_flush(svga, NULL); diff --git a/src/gallium/drivers/svga/svga_resource_buffer.h b/src/gallium/drivers/svga/svga_resource_buffer.h index 95032213fa5..ca8c8d1f5ea 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer.h +++ b/src/gallium/drivers/svga/svga_resource_buffer.h @@ -129,6 +129,12 @@ struct svga_buffer * is the relative offset within that buffer. */ unsigned offset; + + /** + * Range of user buffer that is uploaded in @buffer at @offset. + */ + unsigned start; + unsigned end; } uploaded; /** @@ -193,7 +199,11 @@ svga_buffer(struct pipe_resource *buffer) static INLINE boolean svga_buffer_is_user_buffer( struct pipe_resource *buffer ) { - return svga_buffer(buffer)->user; + if (buffer) { + return svga_buffer(buffer)->user; + } else { + return FALSE; + } } diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c index 923958674b4..a657a8bc224 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c +++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c @@ -651,8 +651,6 @@ svga_redefine_user_buffer(struct pipe_context *pipe, unsigned offset, unsigned size) { - struct svga_screen *ss = svga_screen(pipe->screen); - struct svga_context *svga = svga_context(pipe); struct svga_buffer *sbuf = svga_buffer(resource); assert(sbuf->user); @@ -661,19 +659,8 @@ svga_redefine_user_buffer(struct pipe_context *pipe, assert(!sbuf->hwbuf); /* - * Release any uploaded user buffer. - * - * TODO: As an optimization, we could try to update the uploaded buffer - * instead. + * We always treat the contents of user-buffers as volatile, + * so no particular action needed here. */ - pipe_resource_reference(&sbuf->uploaded.buffer, NULL); - - pipe_mutex_lock(ss->swc_mutex); - - sbuf->key.size.width = sbuf->b.b.width0 = offset + size; - - pipe_mutex_unlock(ss->swc_mutex); - - svga->dirty |= SVGA_NEW_VBUFFER | SVGA_NEW_VELEMENT; } diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c index 7c393a1da8d..47eab1a9739 100644 --- a/src/gallium/drivers/svga/svga_state_vdecl.c +++ b/src/gallium/drivers/svga/svga_state_vdecl.c @@ -38,57 +38,6 @@ #include "svga_hw_reg.h" -static int -upload_user_buffers( struct svga_context *svga ) -{ - enum pipe_error ret = PIPE_OK; - int i; - int nr; - - if (0) - debug_printf("%s: %d\n", __FUNCTION__, svga->curr.num_vertex_buffers); - - nr = svga->curr.num_vertex_buffers; - - for (i = 0; i < nr; i++) - { - if (svga_buffer_is_user_buffer(svga->curr.vb[i].buffer)) - { - struct svga_buffer *buffer = svga_buffer(svga->curr.vb[i].buffer); - - if (!buffer->uploaded.buffer) { - boolean flushed; - ret = u_upload_buffer( svga->upload_vb, - 0, 0, - buffer->b.b.width0, - &buffer->b.b, - &buffer->uploaded.offset, - &buffer->uploaded.buffer, - &flushed); - if (ret) - return ret; - - if (0) - debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n", - __FUNCTION__, - i, - buffer, - buffer->uploaded.buffer, - buffer->uploaded.offset, - buffer->b.b.width0); - } - - svga->curr.vb[i].buffer_offset = buffer->uploaded.offset; - } - } - - if (0) - debug_printf("%s: DONE\n", __FUNCTION__); - - return ret; -} - - /*********************************************************************** */ @@ -99,6 +48,7 @@ static int emit_hw_vs_vdecl( struct svga_context *svga, const struct pipe_vertex_element *ve = svga->curr.velems->velem; SVGA3dVertexDecl decl; unsigned i; + unsigned neg_bias = 0; assert(svga->curr.velems->count >= svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]); @@ -106,12 +56,50 @@ static int emit_hw_vs_vdecl( struct svga_context *svga, svga_hwtnl_reset_vdecl( svga->hwtnl, svga->curr.velems->count ); + /** + * We can't set the VDECL offset to something negative, so we + * must calculate a common negative additional index bias, and modify + * the VDECL offsets accordingly so they *all* end up positive. + * + * Note that the exact value of the negative index bias is not that + * important, since we compensate for it when we calculate the vertex + * buffer offset below. The important thing is that all vertex buffer + * offsets remain positive. + * + * Note that we use a negative bias variable in order to make the + * rounding maths more easy to follow, and to avoid int / unsigned + * confusion. + */ + for (i = 0; i < svga->curr.velems->count; i++) { - const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index]; + const struct pipe_vertex_buffer *vb = + &svga->curr.vb[ve[i].vertex_buffer_index]; + struct svga_buffer *buffer; + unsigned int offset = vb->buffer_offset + ve[i].src_offset; + unsigned tmp_neg_bias = 0; + + if (!vb->buffer) + continue; + + buffer = svga_buffer(vb->buffer); + if (buffer->uploaded.start > offset) { + tmp_neg_bias = buffer->uploaded.start - offset; + if (vb->stride) + tmp_neg_bias = (tmp_neg_bias + vb->stride - 1) / vb->stride; + neg_bias = MAX2(neg_bias, tmp_neg_bias); + } + } + + for (i = 0; i < svga->curr.velems->count; i++) { + const struct pipe_vertex_buffer *vb = + &svga->curr.vb[ve[i].vertex_buffer_index]; unsigned usage, index; - struct svga_buffer *buffer = svga_buffer(vb->buffer); + struct svga_buffer *buffer; + if (!vb->buffer) + continue; + buffer= svga_buffer(vb->buffer); svga_generate_vdecl_semantics( i, &usage, &index ); /* SVGA_NEW_VELEMENT @@ -121,8 +109,16 @@ static int emit_hw_vs_vdecl( struct svga_context *svga, decl.identity.usage = usage; decl.identity.usageIndex = index; decl.array.stride = vb->stride; - decl.array.offset = (vb->buffer_offset + - ve[i].src_offset); + + /* Compensate for partially uploaded vbo, and + * for the negative index bias. + */ + decl.array.offset = (vb->buffer_offset + + ve[i].src_offset + + neg_bias * vb->stride + - buffer->uploaded.start); + + assert(decl.array.offset >= 0); svga_hwtnl_vdecl( svga->hwtnl, i, @@ -131,6 +127,7 @@ static int emit_hw_vs_vdecl( struct svga_context *svga, vb->buffer ); } + svga_hwtnl_set_index_bias( svga->hwtnl, -neg_bias ); return 0; } @@ -138,23 +135,11 @@ static int emit_hw_vs_vdecl( struct svga_context *svga, static int emit_hw_vdecl( struct svga_context *svga, unsigned dirty ) { - int ret = 0; - /* SVGA_NEW_NEED_SWTNL */ if (svga->state.sw.need_swtnl) return 0; /* Do not emit during swtnl */ - /* If we get to here, we know that we're going to draw. Upload - * userbuffers now and try to combine multiple userbuffers from - * multiple draw calls into a single host buffer for performance. - */ - if (svga->curr.any_user_vertex_buffers) { - ret = upload_user_buffers( svga ); - if (ret) - return ret; - } - return emit_hw_vs_vdecl( svga, dirty ); } diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h index 40f6f2bcb5f..eea3d79e64b 100644 --- a/src/gallium/include/pipe/p_config.h +++ b/src/gallium/include/pipe/p_config.h @@ -134,8 +134,6 @@ #error Unknown Endianness #endif -#if !defined(PIPE_OS_EMBEDDED) - /* * Auto-detect the operating system family. * @@ -222,7 +220,5 @@ #endif #endif /* PIPE_OS_WINDOWS */ -#endif /* !PIPE_OS_EMBEDDED */ - #endif /* P_CONFIG_H_ */ diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h index 04fc7c6c5de..f7cc2437747 100644 --- a/src/gallium/include/state_tracker/st_api.h +++ b/src/gallium/include/state_tracker/st_api.h @@ -253,6 +253,12 @@ struct st_context_attribs struct st_framebuffer_iface { /** + * Atomic stamp which changes when framebuffers need to be updated. + */ + + int32_t stamp; + + /** * Available for the state tracker manager to use. */ void *st_manager_private; @@ -315,25 +321,6 @@ struct st_context_iface void (*destroy)(struct st_context_iface *stctxi); /** - * Invalidate the current textures that was taken from a framebuffer. - * - * The state tracker manager calls this function to let the rendering - * context know that it should update the textures it got from - * st_framebuffer_iface::validate. It should do so at the latest time possible. - * Possible right before sending triangles to the pipe context. - * - * For certain platforms this function might be called from a thread other - * than the thread that the context is currently bound in, and must - * therefore be thread safe. But it is the state tracker manager's - * responsibility to make sure that the framebuffer is bound to the context - * and the API context is current for the duration of this call. - * - * Thus reducing the sync primitive needed to a single atomic flag. - */ - void (*notify_invalid_framebuffer)(struct st_context_iface *stctxi, - struct st_framebuffer_iface *stfbi); - - /** * Flush all drawing from context to the pipe also flushes the pipe. */ void (*flush)(struct st_context_iface *stctxi, unsigned flags, diff --git a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp index 741a97f897d..0bb9d852f84 100644 --- a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp +++ b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp @@ -250,21 +250,21 @@ struct GalliumDXGIAdapter DXGI_ADAPTER_DESC1 desc; std::vector<ComPtr<IDXGIOutput> > outputs; int num_outputs; - struct native_event_handler handler; GalliumDXGIAdapter(GalliumDXGIFactory* factory, const struct native_platform* platform, void* dpy) { this->parent = factory; - /* FIXME handler should be static */ - handler.invalid_surface = handle_invalid_surface; - handler.new_drm_screen = dxgi_loader_create_drm_screen; - handler.new_sw_screen = dxgi_loader_create_sw_screen; - platform->set_event_handler(&handler); - - display = platform->create_display(dpy, FALSE, this); + display = platform->create_display(dpy, FALSE); if(!display) - display = platform->create_display(dpy, TRUE, this); + display = platform->create_display(dpy, TRUE); + if (display) { + display->user_data = this; + if (!display->init_screen(display)) { + display->destroy(display); + display = NULL; + } + } if(!display) throw E_FAIL; memset(&desc, 0, sizeof(desc)); @@ -1413,6 +1413,11 @@ struct dxgi_binding static dxgi_binding dxgi_default_binding; static __thread dxgi_binding dxgi_thread_binding; +static const struct native_event_handler dxgi_event_handler = { + GalliumDXGIAdapter::handle_invalid_surface, + dxgi_loader_create_drm_screen, + dxgi_loader_create_sw_screen +}; void STDMETHODCALLTYPE GalliumDXGIUseNothing() { @@ -1427,7 +1432,7 @@ void STDMETHODCALLTYPE GalliumDXGIUseNothing() void STDMETHODCALLTYPE GalliumDXGIUseX11Display(Display* dpy, IGalliumDXGIBackend* backend) { GalliumDXGIUseNothing(); - dxgi_thread_binding.platform = native_get_x11_platform(); + dxgi_thread_binding.platform = native_get_x11_platform(&dxgi_event_handler); dxgi_thread_binding.display = dpy; if(backend) @@ -1443,7 +1448,7 @@ void STDMETHODCALLTYPE GalliumDXGIUseX11Display(Display* dpy, IGalliumDXGIBacken void STDMETHODCALLTYPE GalliumDXGIUseDRMCard(int fd) { GalliumDXGIUseNothing(); - dxgi_thread_binding.platform = native_get_drm_platform(); + dxgi_thread_binding.platform = native_get_drm_platform(&dxgi_event_handler); dxgi_thread_binding.display = (void*)fd; dxgi_thread_binding.backend = 0; } @@ -1453,7 +1458,7 @@ void STDMETHODCALLTYPE GalliumDXGIUseDRMCard(int fd) void STDMETHODCALLTYPE GalliumDXGIUseFBDev(int fd) { GalliumDXGIUseNothing(); - dxgi_thread_binding.platform = native_get_fbdev_platform(); + dxgi_thread_binding.platform = native_get_fbdev_platform(&dxgi_event_handler); dxgi_thread_binding.display = (void*)fd; dxgi_thread_binding.backend = 0; } @@ -1463,7 +1468,7 @@ void STDMETHODCALLTYPE GalliumDXGIUseFBDev(int fd) void STDMETHODCALLTYPE GalliumDXGIUseHDC(HDC hdc, PFNHWNDRESOLVER resolver, void* resolver_cookie) { GalliumDXGIUseNothing(); - dxgi_thread_binding.platform = native_get_gdi_platform(); + dxgi_thread_binding.platform = native_get_gdi_platform(&dxgi_event_handler); dxgi_thread_binding.display = (void*)hdc; dxgi_thread_binding.backend = 0; } @@ -1493,7 +1498,7 @@ void STDMETHODCALLTYPE GalliumDXGIMakeDefault() else if(dxgi_default_binding.platform) factory = new GalliumDXGIFactory(dxgi_default_binding.platform, dxgi_default_binding.display, dxgi_default_binding.backend); else - factory = new GalliumDXGIFactory(native_get_x11_platform(), NULL, NULL); + factory = new GalliumDXGIFactory(native_get_x11_platform(&dxgi_event_handler), NULL, NULL); HRESULT hres = factory->QueryInterface(riid, out_factory); factory->Release(); return hres; diff --git a/src/gallium/state_trackers/dri/common/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c index e23c1bcafaf..08bbdf96e34 100644 --- a/src/gallium/state_trackers/dri/common/dri_context.c +++ b/src/gallium/state_trackers/dri/common/dri_context.c @@ -151,8 +151,6 @@ dri_unbind_context(__DRIcontext * cPriv) if (ctx->st == ctx->stapi->get_current(ctx->stapi)) { ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL); stapi->make_current(stapi, NULL, NULL, NULL); - draw->context = NULL; - read->context = NULL; } } @@ -180,12 +178,10 @@ dri_make_current(__DRIcontext * cPriv, else if (!driDrawPriv || !driReadPriv) return GL_FALSE; - draw->context = ctx; if (ctx->dPriv != driDrawPriv) { ctx->dPriv = driDrawPriv; draw->texture_stamp = driDrawPriv->lastStamp - 1; } - read->context = ctx; if (ctx->rPriv != driReadPriv) { ctx->rPriv = driReadPriv; read->texture_stamp = driReadPriv->lastStamp - 1; diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c index 28a33ac7d07..7b8de3174be 100644 --- a/src/gallium/state_trackers/dri/common/dri_drawable.c +++ b/src/gallium/state_trackers/dri/common/dri_drawable.c @@ -136,6 +136,7 @@ dri_create_buffer(__DRIscreen * sPriv, drawable->sPriv = sPriv; drawable->dPriv = dPriv; dPriv->driverPrivate = (void *)drawable; + p_atomic_set(&drawable->base.stamp, 1); return GL_TRUE; fail: diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.h b/src/gallium/state_trackers/dri/common/dri_drawable.h index 7f1aa512ca1..fd3460dd30b 100644 --- a/src/gallium/state_trackers/dri/common/dri_drawable.h +++ b/src/gallium/state_trackers/dri/common/dri_drawable.h @@ -42,7 +42,6 @@ struct dri_drawable struct st_visual stvis; struct dri_screen *screen; - struct dri_context *context; /* dri */ __DRIdrawable *dPriv; diff --git a/src/gallium/state_trackers/dri/drm/SConscript b/src/gallium/state_trackers/dri/drm/SConscript index b188f76f910..c63918a0e18 100644 --- a/src/gallium/state_trackers/dri/drm/SConscript +++ b/src/gallium/state_trackers/dri/drm/SConscript @@ -5,7 +5,7 @@ Import('*') env = env.Clone() -env.ParseConfig('pkg-config --cflags --libs libdrm') +env.PkgUseModules(['DRM']) env.Append(CPPPATH = [ '#/src/mapi', diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c index e471e8e5be2..fe4ddb312be 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.c +++ b/src/gallium/state_trackers/dri/drm/dri2.c @@ -52,13 +52,11 @@ static void dri2_invalidate_drawable(__DRIdrawable *dPriv) { struct dri_drawable *drawable = dri_drawable(dPriv); - struct dri_context *ctx = drawable->context; dri2InvalidateDrawable(dPriv); drawable->dPriv->lastStamp = *drawable->dPriv->pStamp; - if (ctx) - ctx->st->notify_invalid_framebuffer(ctx->st, &drawable->base); + p_atomic_inc(&drawable->base.stamp); } static const __DRI2flushExtension dri2FlushExtension = { @@ -564,6 +562,24 @@ dri2_query_image(__DRIimage *image, int attrib, int *value) } } +static __DRIimage * +dri2_dup_image(__DRIimage *image, void *loaderPrivate) +{ + __DRIimage *img; + + img = CALLOC_STRUCT(__DRIimageRec); + if (!img) + return NULL; + + img->texture = NULL; + pipe_resource_reference(&img->texture, image->texture); + img->level = image->level; + img->layer = image->layer; + img->loader_private = loaderPrivate; + + return img; +} + static void dri2_destroy_image(__DRIimage *img) { @@ -578,6 +594,7 @@ static struct __DRIimageExtensionRec dri2ImageExtension = { dri2_destroy_image, dri2_create_image, dri2_query_image, + dri2_dup_image, }; /* diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c index ac11f7c47f6..a1879a8f46a 100644 --- a/src/gallium/state_trackers/dri/sw/drisw.c +++ b/src/gallium/state_trackers/dri/sw/drisw.c @@ -103,14 +103,11 @@ drisw_present_texture(__DRIdrawable *dPriv, static INLINE void drisw_invalidate_drawable(__DRIdrawable *dPriv) { - struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv); struct dri_drawable *drawable = dri_drawable(dPriv); drawable->texture_stamp = dPriv->lastStamp - 1; - /* check if swapping currently bound buffer */ - if (ctx && ctx->dPriv == dPriv) - ctx->st->notify_invalid_framebuffer(ctx->st, &drawable->base); + p_atomic_inc(&drawable->base.stamp); } static INLINE void diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile index 763e7b58a49..1c970222c1f 100644 --- a/src/gallium/state_trackers/egl/Makefile +++ b/src/gallium/state_trackers/egl/Makefile @@ -33,7 +33,8 @@ wayland_INCLUDES = \ wayland_SOURCES = $(wildcard wayland/*.c) wayland_OBJECTS = $(wayland_SOURCES:.c=.o) -drm_INCLUDES = -I$(TOP)/src/gallium/winsys $(shell pkg-config --cflags-only-I libdrm) +drm_INCLUDES = -I$(TOP)/src/gallium/winsys $(shell pkg-config --cflags-only-I libdrm) \ + -I$(TOP)/src/gbm/main -I$(TOP)/src/gallium/state_trackers/gbm drm_SOURCES = $(wildcard drm/*.c) drm_OBJECTS = $(drm_SOURCES:.c=.o) diff --git a/src/gallium/state_trackers/egl/SConscript b/src/gallium/state_trackers/egl/SConscript index 9ade76ecbb2..c04fec637c1 100644 --- a/src/gallium/state_trackers/egl/SConscript +++ b/src/gallium/state_trackers/egl/SConscript @@ -40,7 +40,12 @@ else: env.Append(CPPDEFINES = ['GLX_DIRECT_RENDERING']) sources.append(['#/src/glx/dri2.c']) if env['drm']: + env.PkgUseModules('DRM') env.Append(CPPDEFINES = ['HAVE_DRM_BACKEND']) + env.Append(CPPPATH = [ + '#/src/gbm/main', + '#/src/gallium/state_trackers/gbm', + ]) sources.append(['drm/native_drm.c', 'drm/modeset.c']) st_egl = env.ConvenienceLibrary( diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index 29dbbefbf48..6649f02b244 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -31,6 +31,7 @@ #include "util/u_memory.h" #include "util/u_format.h" #include "util/u_string.h" +#include "util/u_atomic.h" #include "egl_g3d.h" #include "egl_g3d_api.h" @@ -45,15 +46,9 @@ egl_g3d_invalid_surface(struct native_display *ndpy, { /* XXX not thread safe? */ struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data); - struct egl_g3d_context *gctx; - - /* - * Some functions such as egl_g3d_copy_buffers create a temporary native - * surface. There is no gsurf associated with it. - */ - gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL; - if (gctx) - gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi); + + if (gsurf && gsurf->stfbi) + p_atomic_inc(&gsurf->stfbi->stamp); } static struct pipe_screen * @@ -72,10 +67,26 @@ egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws) return gdpy->loader->create_sw_screen(ws); } -static struct native_event_handler egl_g3d_native_event_handler = { +static struct pipe_resource * +egl_g3d_lookup_egl_image(struct native_display *ndpy, void *egl_image) +{ + _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct st_egl_image img; + struct pipe_resource *resource = NULL; + + memset(&img, 0, sizeof(img)); + if (gdpy->smapi->get_egl_image(gdpy->smapi, egl_image, &img)) + resource = img.texture; + + return resource; +} + +static const struct native_event_handler egl_g3d_native_event_handler = { egl_g3d_invalid_surface, egl_g3d_new_drm_screen, - egl_g3d_new_sw_screen + egl_g3d_new_sw_screen, + egl_g3d_lookup_egl_image }; /** @@ -94,40 +105,38 @@ egl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat) case _EGL_PLATFORM_WINDOWS: plat_name = "Windows"; #ifdef HAVE_GDI_BACKEND - nplat = native_get_gdi_platform(); + nplat = native_get_gdi_platform(&egl_g3d_native_event_handler); #endif break; case _EGL_PLATFORM_X11: plat_name = "X11"; #ifdef HAVE_X11_BACKEND - nplat = native_get_x11_platform(); + nplat = native_get_x11_platform(&egl_g3d_native_event_handler); #endif break; case _EGL_PLATFORM_WAYLAND: plat_name = "wayland"; #ifdef HAVE_WAYLAND_BACKEND - nplat = native_get_wayland_platform(); + nplat = native_get_wayland_platform(&egl_g3d_native_event_handler); #endif break; case _EGL_PLATFORM_DRM: plat_name = "DRM"; #ifdef HAVE_DRM_BACKEND - nplat = native_get_drm_platform(); + nplat = native_get_drm_platform(&egl_g3d_native_event_handler); #endif break; case _EGL_PLATFORM_FBDEV: plat_name = "FBDEV"; #ifdef HAVE_FBDEV_BACKEND - nplat = native_get_fbdev_platform(); + nplat = native_get_fbdev_platform(&egl_g3d_native_event_handler); #endif break; default: break; } - if (nplat) - nplat->set_event_handler(&egl_g3d_native_event_handler); - else + if (!nplat) _eglLog(_EGL_WARNING, "unsupported platform %s", plat_name); gdrv->platforms[plat] = nplat; @@ -504,13 +513,20 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy) gdpy->loader = gdrv->loader; dpy->DriverData = gdpy; - _eglLog(_EGL_INFO, "use %s for display %p", nplat->name, dpy->PlatformDisplay); - gdpy->native = nplat->create_display(dpy->PlatformDisplay, - dpy->Options.UseFallback, (void *) dpy); + _eglLog(_EGL_INFO, "use %s for display %p", + nplat->name, dpy->PlatformDisplay); + gdpy->native = + nplat->create_display(dpy->PlatformDisplay, dpy->Options.UseFallback); if (!gdpy->native) { _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)"); goto fail; } + gdpy->native->user_data = (void *) dpy; + if (!gdpy->native->init_screen(gdpy->native)) { + _eglError(EGL_NOT_INITIALIZED, + "eglInitialize(failed to initialize screen)"); + goto fail; + } if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_DEFAULT_MASK) dpy->ClientAPIs |= EGL_OPENGL_BIT; diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h index 301db3128ff..5989a023573 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.h +++ b/src/gallium/state_trackers/egl/common/egl_g3d.h @@ -126,4 +126,12 @@ _EGL_DRIVER_TYPECAST(egl_g3d_screen, _EGLScreen, obj) #endif /* EGL_MESA_screen_surface */ +static INLINE struct st_api * +egl_g3d_get_st_api(_EGLDriver *drv, enum st_api_type api) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + + return gdrv->loader->get_st_api(api); +} + #endif /* _EGL_G3D_H_ */ diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c index 8b1821e0055..f897054a540 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c @@ -37,7 +37,6 @@ #include "egl_g3d_image.h" #include "egl_g3d_sync.h" #include "egl_g3d_st.h" -#include "egl_g3d_loader.h" #include "native.h" /** @@ -47,7 +46,6 @@ static struct st_api * egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx, enum st_profile_type *profile) { - struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); struct st_api *stapi; EGLint api = -1; @@ -81,96 +79,66 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx, break; } - switch (api) { - case ST_API_OPENGL: - stapi = gdrv->loader->guess_gl_api(*profile); - break; - case ST_API_OPENVG: - stapi = gdrv->loader->get_st_api(api); - break; - default: - stapi = NULL; - break; - } + stapi = egl_g3d_get_st_api(drv, api); if (stapi && !(stapi->profile_mask & (1 << *profile))) stapi = NULL; return stapi; } +struct egl_g3d_choose_config_data { + _EGLConfig criteria; + enum pipe_format format; +}; + static int egl_g3d_compare_config(const _EGLConfig *conf1, const _EGLConfig *conf2, void *priv_data) { - const _EGLConfig *criteria = (const _EGLConfig *) priv_data; + struct egl_g3d_choose_config_data *data = + (struct egl_g3d_choose_config_data *) priv_data; + const _EGLConfig *criteria = &data->criteria;; /* EGL_NATIVE_VISUAL_TYPE ignored? */ return _eglCompareConfigs(conf1, conf2, criteria, EGL_TRUE); } static EGLBoolean -egl_g3d_match_config(const _EGLConfig *conf, const _EGLConfig *criteria) +egl_g3d_match_config(const _EGLConfig *conf, void *priv_data) { - if (!_eglMatchConfig(conf, criteria)) - return EGL_FALSE; - - if (criteria->MatchNativePixmap != EGL_NONE && - criteria->MatchNativePixmap != EGL_DONT_CARE) { - struct egl_g3d_display *gdpy = egl_g3d_display(conf->Display); - struct egl_g3d_config *gconf = egl_g3d_config(conf); - EGLNativePixmapType pix = - (EGLNativePixmapType) criteria->MatchNativePixmap; + struct egl_g3d_choose_config_data *data = + (struct egl_g3d_choose_config_data *) priv_data; + struct egl_g3d_config *gconf = egl_g3d_config(conf); - if (!gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native)) - return EGL_FALSE; - } + if (data->format != PIPE_FORMAT_NONE && + data->format != gconf->native->color_format) + return EGL_FALSE; - return EGL_TRUE; + return _eglMatchConfig(conf, &data->criteria); } static EGLBoolean egl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs, EGLConfig *configs, EGLint size, EGLint *num_configs) { - _EGLConfig **tmp_configs, criteria; - EGLint tmp_size, i; - - if (!num_configs) - return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs"); + struct egl_g3d_choose_config_data data; - if (!_eglParseConfigAttribList(&criteria, dpy, attribs)) + if (!_eglParseConfigAttribList(&data.criteria, dpy, attribs)) return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig"); - /* get the number of matched configs */ - tmp_size = _eglFilterArray(dpy->Configs, NULL, 0, - (_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria); - if (!tmp_size) { - *num_configs = tmp_size; - return EGL_TRUE; - } - - tmp_configs = MALLOC(sizeof(tmp_configs[0]) * tmp_size); - if (!tmp_configs) - return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)"); + data.format = PIPE_FORMAT_NONE; + if (data.criteria.MatchNativePixmap != EGL_NONE && + data.criteria.MatchNativePixmap != EGL_DONT_CARE) { + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - /* get the matched configs */ - _eglFilterArray(dpy->Configs, (void **) tmp_configs, tmp_size, - (_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria); - - /* perform sorting of configs */ - if (configs && tmp_size) { - _eglSortConfigs((const _EGLConfig **) tmp_configs, tmp_size, - egl_g3d_compare_config, (void *) &criteria); - tmp_size = MIN2(tmp_size, size); - for (i = 0; i < tmp_size; i++) - configs[i] = _eglGetConfigHandle(tmp_configs[i]); + if (!gdpy->native->get_pixmap_format(gdpy->native, + (EGLNativePixmapType) data.criteria.MatchNativePixmap, + &data.format)) + return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglChooseConfig"); } - FREE(tmp_configs); - - *num_configs = tmp_size; - - return EGL_TRUE; + return _eglFilterConfigArray(dpy->Configs, configs, size, num_configs, + egl_g3d_match_config, egl_g3d_compare_config, &data); } static _EGLContext * @@ -536,19 +504,12 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy, (gdraw) ? gdraw->stfbi : NULL, (gread) ? gread->stfbi : NULL); if (ok) { if (gdraw) { - gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, - gdraw->stfbi); - if (gdraw->base.Type == EGL_WINDOW_BIT) { gctx->base.WindowRenderBuffer = (gdraw->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) ? EGL_SINGLE_BUFFER : EGL_BACK_BUFFER; } } - if (gread && gread != gdraw) { - gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, - gread->stfbi); - } } } else if (old_gctx) { @@ -614,21 +575,6 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) gsurf->base.SwapInterval); } -/** - * Get the pipe surface of the given attachment of the native surface. - */ -static struct pipe_resource * -get_pipe_resource(struct native_display *ndpy, struct native_surface *nsurf, - enum native_attachment natt) -{ - struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS]; - - textures[natt] = NULL; - nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL); - - return textures[natt]; -} - static EGLBoolean egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLNativePixmapType target) @@ -636,43 +582,18 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, struct egl_g3d_display *gdpy = egl_g3d_display(dpy); struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); _EGLContext *ctx = _eglGetCurrentContext(); - struct native_surface *nsurf; - struct pipe_resource *ptex; - struct pipe_context *pipe; if (!gsurf->render_texture) return EGL_TRUE; - nsurf = gdpy->native->create_pixmap_surface(gdpy->native, target, NULL); - if (!nsurf) - return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers"); - /* flush if the surface is current */ if (ctx && ctx->DrawSurface == &gsurf->base) { struct egl_g3d_context *gctx = egl_g3d_context(ctx); gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL); } - pipe = ndpy_get_copy_context(gdpy->native); - if (!pipe) - return EGL_FALSE; - - ptex = get_pipe_resource(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); - if (ptex) { - struct pipe_box src_box; - - u_box_origin_2d(ptex->width0, ptex->height0, &src_box); - pipe->resource_copy_region(pipe, ptex, 0, 0, 0, 0, - gsurf->render_texture, 0, &src_box); - pipe->flush(pipe, NULL); - nsurf->present(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0); - - pipe_resource_reference(&ptex, NULL); - } - - nsurf->destroy(nsurf); - - return EGL_TRUE; + return gdpy->native->copy_to_pixmap(gdpy->native, + target, gsurf->render_texture); } static EGLBoolean diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c index ce72e27c3d5..7e9a29b0284 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c @@ -37,9 +37,6 @@ #include "egl_g3d.h" #include "egl_g3d_image.h" -/* for struct winsys_handle */ -#include "state_tracker/drm_driver.h" - /** * Reference and return the front left buffer of the native pixmap. */ @@ -137,10 +134,9 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name, _EGLImage *img, const EGLint *attribs) { struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - struct pipe_resource templ; - struct winsys_handle wsh; _EGLImageAttribs attrs; EGLint format; + struct native_buffer nbuf; if (!dpy->Extensions.MESA_drm_image) return NULL; @@ -166,21 +162,21 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name, break; } - memset(&templ, 0, sizeof(templ)); - templ.target = PIPE_TEXTURE_2D; - templ.format = format; - templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; - templ.width0 = attrs.Width; - templ.height0 = attrs.Height; - templ.depth0 = 1; - templ.array_size = 1; - - memset(&wsh, 0, sizeof(wsh)); - wsh.handle = (unsigned) name; - wsh.stride = - attrs.DRMBufferStrideMESA * util_format_get_blocksize(templ.format); - - return gdpy->native->buffer->import_buffer(gdpy->native, &templ, &wsh); + memset(&nbuf, 0, sizeof(nbuf)); + nbuf.type = NATIVE_BUFFER_DRM; + nbuf.u.drm.templ.target = PIPE_TEXTURE_2D; + nbuf.u.drm.templ.format = format; + nbuf.u.drm.templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; + nbuf.u.drm.templ.width0 = attrs.Width; + nbuf.u.drm.templ.height0 = attrs.Height; + nbuf.u.drm.templ.depth0 = 1; + nbuf.u.drm.templ.array_size = 1; + + nbuf.u.drm.name = name; + nbuf.u.drm.stride = + attrs.DRMBufferStrideMESA * util_format_get_blocksize(format); + + return gdpy->native->buffer->import_buffer(gdpy->native, &nbuf); } #endif /* EGL_MESA_drm_image */ @@ -327,35 +323,26 @@ egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img, { struct egl_g3d_display *gdpy = egl_g3d_display(dpy); struct egl_g3d_image *gimg = egl_g3d_image(img); - struct winsys_handle wsh; + struct native_buffer nbuf; if (!dpy->Extensions.MESA_drm_image) return EGL_FALSE; - /* get shared handle */ - if (name) { - memset(&handle, 0, sizeof(handle)); - wsh.type = DRM_API_HANDLE_TYPE_SHARED; - if (!gdpy->native->buffer->export_buffer(gdpy->native, - gimg->texture, &wsh)) - return EGL_FALSE; + memset(&nbuf, 0, sizeof(nbuf)); + nbuf.type = NATIVE_BUFFER_DRM; + if (name) + nbuf.u.drm.templ.bind |= PIPE_BIND_SHARED; - *name = wsh.handle; - } + if (!gdpy->native->buffer->export_buffer(gdpy->native, + gimg->texture, &nbuf)) + return EGL_FALSE; - /* get KMS handle */ - if (handle || stride) { - memset(&wsh, 0, sizeof(wsh)); - wsh.type = DRM_API_HANDLE_TYPE_KMS; - if (!gdpy->native->buffer->export_buffer(gdpy->native, - gimg->texture, &wsh)) - return EGL_FALSE; - - if (handle) - *handle = wsh.handle; - if (stride) - *stride = wsh.stride; - } + if (name) + *name = nbuf.u.drm.name; + if (handle) + *handle = nbuf.u.drm.handle; + if (stride) + *stride = nbuf.u.drm.stride; return EGL_TRUE; } diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_loader.h b/src/gallium/state_trackers/egl/common/egl_g3d_loader.h index 78bfe2131ef..e9403fa293b 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_loader.h +++ b/src/gallium/state_trackers/egl/common/egl_g3d_loader.h @@ -39,7 +39,6 @@ struct sw_winsys; struct egl_g3d_loader { uint profile_masks[ST_API_COUNT]; struct st_api *(*get_st_api)(enum st_api_type api); - struct st_api *(*guess_gl_api)(enum st_profile_type profile); struct pipe_screen *(*create_drm_screen)(const char *name, int fd); struct pipe_screen *(*create_sw_screen)(struct sw_winsys *ws); diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c index 2b944b521a4..60c3e332ac9 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c @@ -292,6 +292,8 @@ egl_g3d_create_st_framebuffer(_EGLSurface *surf) return NULL; stfbi->visual = &gsurf->stvis; + p_atomic_set(&stfbi->stamp, 1); + if (gsurf->base.Type != EGL_PBUFFER_BIT) { stfbi->flush_front = egl_g3d_st_framebuffer_flush_front; stfbi->validate = egl_g3d_st_framebuffer_validate; diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h index 8646e52ed7c..fc50ee485fe 100644 --- a/src/gallium/state_trackers/egl/common/native.h +++ b/src/gallium/state_trackers/egl/common/native.h @@ -152,6 +152,11 @@ struct native_display { */ void *user_data; + /** + * Initialize and create the pipe screen. + */ + boolean (*init_screen)(struct native_display *ndpy); + void (*destroy)(struct native_display *ndpy); /** @@ -170,16 +175,21 @@ struct native_display { int *num_configs); /** - * Test if a pixmap is supported by the given config. Required unless no - * config has pixmap_bit set. - * - * This function is usually called to find a config that supports a given - * pixmap. Thus, it is usually called with the same pixmap in a row. + * Get the color format of the pixmap. Required unless no config has + * pixmap_bit set. */ - boolean (*is_pixmap_supported)(struct native_display *ndpy, - EGLNativePixmapType pix, - const struct native_config *nconf); + boolean (*get_pixmap_format)(struct native_display *ndpy, + EGLNativePixmapType pix, + enum pipe_format *format); + /** + * Copy the contents of the resource to the pixmap's front-left attachment. + * This is used to implement eglCopyBuffers. Required unless no config has + * pixmap_bit set. + */ + boolean (*copy_to_pixmap)(struct native_display *ndpy, + EGLNativePixmapType pix, + struct pipe_resource *src); /** * Create a window surface. Required unless no config has window_bit set. @@ -219,6 +229,9 @@ struct native_event_handler { const char *name, int fd); struct pipe_screen *(*new_sw_screen)(struct native_display *ndpy, struct sw_winsys *ws); + + struct pipe_resource *(*lookup_egl_image)(struct native_display *ndpy, + void *egl_image); }; /** @@ -256,26 +269,29 @@ ndpy_uninit(struct native_display *ndpy) struct native_platform { const char *name; - void (*set_event_handler)(struct native_event_handler *handler); - struct native_display *(*create_display)(void *dpy, - boolean use_sw, - void *user_data); + /** + * Create the native display and usually establish a connection to the + * display server. + * + * No event should be generated at this stage. + */ + struct native_display *(*create_display)(void *dpy, boolean use_sw); }; const struct native_platform * -native_get_gdi_platform(void); +native_get_gdi_platform(const struct native_event_handler *event_handler); const struct native_platform * -native_get_x11_platform(void); +native_get_x11_platform(const struct native_event_handler *event_handler); const struct native_platform * -native_get_wayland_platform(void); +native_get_wayland_platform(const struct native_event_handler *event_handler); const struct native_platform * -native_get_drm_platform(void); +native_get_drm_platform(const struct native_event_handler *event_handler); const struct native_platform * -native_get_fbdev_platform(void); +native_get_fbdev_platform(const struct native_event_handler *event_handler); #ifdef __cplusplus } diff --git a/src/gallium/state_trackers/egl/common/native_buffer.h b/src/gallium/state_trackers/egl/common/native_buffer.h index 5c29ab97411..b8a66d17e12 100644 --- a/src/gallium/state_trackers/egl/common/native_buffer.h +++ b/src/gallium/state_trackers/egl/common/native_buffer.h @@ -30,30 +30,43 @@ #define _NATIVE_BUFFER_H_ #include "pipe/p_compiler.h" +#include "pipe/p_state.h" struct native_display; -struct pipe_resource; + +enum native_buffer_type { + NATIVE_BUFFER_DRM, + + NUM_NATIVE_BUFFERS +}; + +struct native_buffer { + enum native_buffer_type type; + + union { + struct { + struct pipe_resource templ; + unsigned name; /**< the name of the GEM object */ + unsigned handle; /**< the handle of the GEM object */ + unsigned stride; + } drm; + } u; +}; /** * Buffer interface of the native display. It allows native buffers to be * imported and exported. - * - * Just like a native window or a native pixmap, a native buffer is another - * native type. Its definition depends on the native display. - * - * For DRM platform, the type of a native buffer is struct winsys_handle. */ struct native_display_buffer { struct pipe_resource *(*import_buffer)(struct native_display *ndpy, - const struct pipe_resource *templ, - void *buf); + struct native_buffer *buf); /** * The resource must be creatred with PIPE_BIND_SHARED. */ boolean (*export_buffer)(struct native_display *ndpy, struct pipe_resource *res, - void *buf); + struct native_buffer *nbuf); }; #endif /* _NATIVE_BUFFER_H_ */ diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c index ee18cb2025b..cca1e1c6295 100644 --- a/src/gallium/state_trackers/egl/common/native_helper.c +++ b/src/gallium/state_trackers/egl/common/native_helper.c @@ -282,9 +282,9 @@ resource_surface_copy_swap(struct resource_surface *rsurf, btex, 0, &src_box); ret = TRUE; - out_no_ftex: - pipe_resource_reference(&btex, NULL); out_no_btex: + pipe_resource_reference(&btex, NULL); + out_no_ftex: pipe_resource_reference(&ftex, NULL); return ret; @@ -367,3 +367,116 @@ resource_surface_wait(struct resource_surface *rsurf) { while (resource_surface_throttle(rsurf)); } + +boolean +native_display_copy_to_pixmap(struct native_display *ndpy, + EGLNativePixmapType pix, + struct pipe_resource *src) +{ + struct pipe_context *pipe; + struct native_surface *nsurf; + struct pipe_resource *dst; + struct pipe_resource *tmp[NUM_NATIVE_ATTACHMENTS]; + const enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT; + + pipe = ndpy_get_copy_context(ndpy); + if (!pipe) + return FALSE; + + nsurf = ndpy->create_pixmap_surface(ndpy, pix, NULL); + if (!nsurf) + return FALSE; + + /* get the texutre */ + tmp[natt] = NULL; + nsurf->validate(nsurf, 1 << natt, NULL, tmp, NULL, NULL); + dst = tmp[natt]; + + if (dst && dst->format == src->format) { + struct pipe_box src_box; + + u_box_origin_2d(src->width0, src->height0, &src_box); + pipe->resource_copy_region(pipe, dst, 0, 0, 0, 0, src, 0, &src_box); + pipe->flush(pipe, NULL); + nsurf->present(nsurf, natt, FALSE, 0); + } + + if (dst) + pipe_resource_reference(&dst, NULL); + + nsurf->destroy(nsurf); + + return TRUE; +} + +#include "state_tracker/drm_driver.h" +struct pipe_resource * +drm_display_import_native_buffer(struct native_display *ndpy, + struct native_buffer *nbuf) +{ + struct pipe_screen *screen = ndpy->screen; + struct pipe_resource *res = NULL; + + switch (nbuf->type) { + case NATIVE_BUFFER_DRM: + { + struct winsys_handle wsh; + + memset(&wsh, 0, sizeof(wsh)); + wsh.handle = nbuf->u.drm.name; + wsh.stride = nbuf->u.drm.stride; + + res = screen->resource_from_handle(screen, &nbuf->u.drm.templ, &wsh); + } + break; + default: + break; + } + + return res; +} + +boolean +drm_display_export_native_buffer(struct native_display *ndpy, + struct pipe_resource *res, + struct native_buffer *nbuf) +{ + struct pipe_screen *screen = ndpy->screen; + boolean ret = FALSE; + + switch (nbuf->type) { + case NATIVE_BUFFER_DRM: + { + struct winsys_handle wsh; + + if ((nbuf->u.drm.templ.bind & res->bind) != nbuf->u.drm.templ.bind) + break; + + memset(&wsh, 0, sizeof(wsh)); + wsh.type = DRM_API_HANDLE_TYPE_KMS; + if (!screen->resource_get_handle(screen, res, &wsh)) + break; + + nbuf->u.drm.handle = wsh.handle; + nbuf->u.drm.stride = wsh.stride; + + /* get the name of the GEM object */ + if (nbuf->u.drm.templ.bind & PIPE_BIND_SHARED) { + memset(&wsh, 0, sizeof(wsh)); + wsh.type = DRM_API_HANDLE_TYPE_SHARED; + if (!screen->resource_get_handle(screen, res, &wsh)) + break; + + nbuf->u.drm.name = wsh.handle; + } + + nbuf->u.drm.templ = *res; + ret = TRUE; + } + break; + default: + break; + } + + return ret; +} diff --git a/src/gallium/state_trackers/egl/common/native_helper.h b/src/gallium/state_trackers/egl/common/native_helper.h index 39564a04365..e8d91ccb02a 100644 --- a/src/gallium/state_trackers/egl/common/native_helper.h +++ b/src/gallium/state_trackers/egl/common/native_helper.h @@ -105,3 +105,17 @@ resource_surface_flush(struct resource_surface *rsurf, */ void resource_surface_wait(struct resource_surface *rsurf); + +boolean +native_display_copy_to_pixmap(struct native_display *ndpy, + EGLNativePixmapType pix, + struct pipe_resource *src); + +struct pipe_resource * +drm_display_import_native_buffer(struct native_display *ndpy, + struct native_buffer *nbuf); + +boolean +drm_display_export_native_buffer(struct native_display *ndpy, + struct pipe_resource *res, + struct native_buffer *nbuf); diff --git a/src/gallium/state_trackers/egl/drm/modeset.c b/src/gallium/state_trackers/egl/drm/modeset.c index 3fff9540905..73968d1343b 100644 --- a/src/gallium/state_trackers/egl/drm/modeset.c +++ b/src/gallium/state_trackers/egl/drm/modeset.c @@ -290,6 +290,42 @@ drm_display_create_surface(struct native_display *ndpy, return drmsurf; } +struct native_surface * +drm_display_create_surface_from_resource(struct native_display *ndpy, + struct pipe_resource *resource) +{ + struct drm_display *drmdpy = drm_display(ndpy); + struct drm_surface *drmsurf; + enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT; + + drmsurf = CALLOC_STRUCT(drm_surface); + if (!drmsurf) + return NULL; + + drmsurf->drmdpy = drmdpy; + drmsurf->color_format = resource->format; + drmsurf->width = resource->width0; + drmsurf->height = resource->height0; + drmsurf->have_pageflip = FALSE; + + drmsurf->rsurf = resource_surface_create(drmdpy->base.screen, + drmsurf->color_format, + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT); + + resource_surface_import_resource(drmsurf->rsurf, natt, resource); + + drmsurf->base.destroy = drm_surface_destroy; + drmsurf->base.present = drm_surface_present; + drmsurf->base.validate = drm_surface_validate; + drmsurf->base.wait = drm_surface_wait; + + return &drmsurf->base; +} + + /** * Choose a CRTC that supports all given connectors. */ diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c index 725fe28e4e2..47910de8d3c 100644 --- a/src/gallium/state_trackers/egl/drm/native_drm.c +++ b/src/gallium/state_trackers/egl/drm/native_drm.c @@ -33,6 +33,8 @@ #include "native_drm.h" +#include "gbm_gallium_drmint.h" + #ifdef HAVE_LIBUDEV #include <libudev.h> #endif @@ -125,6 +127,8 @@ drm_display_destroy(struct native_display *ndpy) drm_display_fini_modeset(&drmdpy->base); + /* gbm owns screen */ + ndpy->screen = NULL; ndpy_uninit(ndpy); if (drmdpy->device_name) @@ -136,54 +140,10 @@ drm_display_destroy(struct native_display *ndpy) FREE(drmdpy); } -/** - * Initialize KMS and pipe screen. - */ -static boolean -drm_display_init_screen(struct native_display *ndpy) -{ - struct drm_display *drmdpy = drm_display(ndpy); - drmVersionPtr version; - - version = drmGetVersion(drmdpy->fd); - if (!version) { - _eglLog(_EGL_WARNING, "invalid fd %d", drmdpy->fd); - return FALSE; - } - - drmdpy->base.screen = - drmdpy->event_handler->new_drm_screen(&drmdpy->base, NULL, drmdpy->fd); - drmFreeVersion(version); - - if (!drmdpy->base.screen) { - _eglLog(_EGL_DEBUG, "failed to create DRM screen"); - return FALSE; - } - - return TRUE; -} - -static struct pipe_resource * -drm_display_import_buffer(struct native_display *ndpy, - const struct pipe_resource *templ, - void *buf) -{ - return ndpy->screen->resource_from_handle(ndpy->screen, - templ, (struct winsys_handle *) buf); -} - -static boolean -drm_display_export_buffer(struct native_display *ndpy, - struct pipe_resource *res, - void *buf) -{ - return ndpy->screen->resource_get_handle(ndpy->screen, - res, (struct winsys_handle *) buf); -} - static struct native_display_buffer drm_display_buffer = { - drm_display_import_buffer, - drm_display_export_buffer + /* use the helpers */ + drm_display_import_native_buffer, + drm_display_export_native_buffer }; static int @@ -281,9 +241,25 @@ static struct native_display_wayland_bufmgr drm_display_wayland_bufmgr = { #endif /* HAVE_WAYLAND_BACKEND */ +static struct native_surface * +drm_create_pixmap_surface(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf) +{ + struct gbm_gallium_drm_bo *bo = (void *) pix; + + return drm_display_create_surface_from_resource(ndpy, bo->resource); +} + +static boolean +drm_display_init_screen(struct native_display *ndpy) +{ + return TRUE; +} + static struct native_display * -drm_create_display(int fd, struct native_event_handler *event_handler, - void *user_data) +drm_create_display(struct gbm_gallium_drm_device *gbmdrm, + const struct native_event_handler *event_handler) { struct drm_display *drmdpy; @@ -291,20 +267,24 @@ drm_create_display(int fd, struct native_event_handler *event_handler, if (!drmdpy) return NULL; - drmdpy->fd = fd; - drmdpy->device_name = drm_get_device_name(fd); + drmdpy->fd = gbmdrm->base.base.fd; + drmdpy->device_name = drm_get_device_name(drmdpy->fd); + + gbmdrm->lookup_egl_image = (struct pipe_resource *(*)(void *, void *)) + event_handler->lookup_egl_image; + gbmdrm->lookup_egl_image_data = &drmdpy->base; + drmdpy->event_handler = event_handler; - drmdpy->base.user_data = user_data; - if (!drm_display_init_screen(&drmdpy->base)) { - drm_display_destroy(&drmdpy->base); - return NULL; - } + drmdpy->base.screen = gbmdrm->screen; + drmdpy->base.init_screen = drm_display_init_screen; drmdpy->base.destroy = drm_display_destroy; drmdpy->base.get_param = drm_display_get_param; drmdpy->base.get_configs = drm_display_get_configs; + drmdpy->base.create_pixmap_surface = drm_create_pixmap_surface; + drmdpy->base.buffer = &drm_display_buffer; #ifdef HAVE_WAYLAND_BACKEND if (drmdpy->device_name) @@ -315,39 +295,39 @@ drm_create_display(int fd, struct native_event_handler *event_handler, return &drmdpy->base; } -static struct native_event_handler *drm_event_handler; - -static void -native_set_event_handler(struct native_event_handler *event_handler) -{ - drm_event_handler = event_handler; -} +static const struct native_event_handler *drm_event_handler; static struct native_display * -native_create_display(void *dpy, boolean use_sw, void *user_data) +native_create_display(void *dpy, boolean use_sw) { + struct gbm_gallium_drm_device *gbm; int fd; - if (dpy) { - fd = dup((int) pointer_to_intptr(dpy)); - } - else { + gbm = dpy; + + if (gbm == NULL) { fd = open("/dev/dri/card0", O_RDWR); + gbm = gbm_gallium_drm_device(gbm_create_device(fd)); } - if (fd < 0) + + if (gbm == NULL) + return NULL; + + if (strcmp(gbm_device_get_backend_name(&gbm->base.base), "drm") != 0 || + gbm->base.type != GBM_DRM_DRIVER_TYPE_GALLIUM) return NULL; - return drm_create_display(fd, drm_event_handler, user_data); + return drm_create_display(gbm, drm_event_handler); } static const struct native_platform drm_platform = { "DRM", /* name */ - native_set_event_handler, native_create_display }; const struct native_platform * -native_get_drm_platform(void) +native_get_drm_platform(const struct native_event_handler *event_handler) { + drm_event_handler = event_handler; return &drm_platform; } diff --git a/src/gallium/state_trackers/egl/drm/native_drm.h b/src/gallium/state_trackers/egl/drm/native_drm.h index 41cdc4f9d04..675a58a1922 100644 --- a/src/gallium/state_trackers/egl/drm/native_drm.h +++ b/src/gallium/state_trackers/egl/drm/native_drm.h @@ -50,7 +50,7 @@ struct drm_surface; struct drm_display { struct native_display base; - struct native_event_handler *event_handler; + const struct native_event_handler *event_handler; int fd; char *device_name; @@ -154,4 +154,8 @@ drm_display_init_modeset(struct native_display *ndpy); void drm_display_fini_modeset(struct native_display *ndpy); +struct native_surface * +drm_display_create_surface_from_resource(struct native_display *ndpy, + struct pipe_resource *resource); + #endif /* _NATIVE_DRM_H_ */ diff --git a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c index e2fde00e975..6772d379f73 100644 --- a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c +++ b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c @@ -26,6 +26,21 @@ * Chia-I Wu <[email protected]> */ +/** + * Considering fbdev as an in-kernel window system, + * + * - opening a device opens a connection + * - there is only one window: the framebuffer + * - fb_var_screeninfo decides window position, size, and even color format + * - there is no pixmap + * + * Now EGL is built on top of this window system. So we should have + * + * - the fd as the handle of the native display + * - reject all but one native window: NULL + * - no pixmap support + */ + #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> @@ -45,16 +60,13 @@ struct fbdev_display { struct native_display base; int fd; - struct native_event_handler *event_handler; + const struct native_event_handler *event_handler; struct fb_fix_screeninfo finfo; - struct fb_var_screeninfo vinfo; - + struct fb_var_screeninfo config_vinfo; struct native_config config; - struct native_connector connector; - struct native_mode mode; - struct fbdev_surface *current_surface; + boolean assume_fixed_vinfo; }; struct fbdev_surface { @@ -66,7 +78,7 @@ struct fbdev_surface { unsigned int sequence_number; - boolean is_current; + struct fbdev_sw_drawable drawable; }; static INLINE struct fbdev_display * @@ -103,38 +115,70 @@ fbdev_surface_validate(struct native_surface *nsurf, uint attachment_mask, return TRUE; } -static boolean -fbdev_surface_flush_frontbuffer(struct native_surface *nsurf) +static enum pipe_format +vinfo_to_format(const struct fb_var_screeninfo *vinfo) { - struct fbdev_surface *fbsurf = fbdev_surface(nsurf); + enum pipe_format format = PIPE_FORMAT_NONE; - if (!fbsurf->is_current) - return TRUE; + /* should also check channel offsets... */ + switch (vinfo->bits_per_pixel) { + case 32: + if (vinfo->red.length == 8 && + vinfo->green.length == 8 && + vinfo->blue.length == 8) { + format = (vinfo->transp.length == 8) ? + PIPE_FORMAT_B8G8R8A8_UNORM : PIPE_FORMAT_B8G8R8X8_UNORM; + } + break; + case 16: + if (vinfo->red.length == 5 && + vinfo->green.length == 6 && + vinfo->blue.length == 5 && + vinfo->transp.length == 0) + format = PIPE_FORMAT_B5G6R5_UNORM; + break; + default: + break; + } - return resource_surface_present(fbsurf->rsurf, - NATIVE_ATTACHMENT_FRONT_LEFT, NULL); + return format; } static boolean -fbdev_surface_swap_buffers(struct native_surface *nsurf) +fbdev_surface_update_drawable(struct native_surface *nsurf, + const struct fb_var_screeninfo *vinfo) { struct fbdev_surface *fbsurf = fbdev_surface(nsurf); - struct fbdev_display *fbdpy = fbsurf->fbdpy; - boolean ret = TRUE; - - if (fbsurf->is_current) { - ret = resource_surface_present(fbsurf->rsurf, - NATIVE_ATTACHMENT_BACK_LEFT, NULL); + unsigned x, y, width, height; + + x = vinfo->xoffset; + y = vinfo->yoffset; + width = MIN2(vinfo->xres, fbsurf->width); + height = MIN2(vinfo->yres, fbsurf->height); + + /* sanitize the values */ + if (x + width > vinfo->xres_virtual) { + if (x > vinfo->xres_virtual) + width = 0; + else + width = vinfo->xres_virtual - x; + } + if (y + height > vinfo->yres_virtual) { + if (y > vinfo->yres_virtual) + height = 0; + else + height = vinfo->yres_virtual - y; } - resource_surface_swap_buffers(fbsurf->rsurf, - NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE); - /* the front/back textures are swapped */ - fbsurf->sequence_number++; - fbdpy->event_handler->invalid_surface(&fbdpy->base, - &fbsurf->base, fbsurf->sequence_number); + fbsurf->drawable.format = vinfo_to_format(vinfo); + fbsurf->drawable.x = vinfo->xoffset; + fbsurf->drawable.y = vinfo->yoffset; + fbsurf->drawable.width = vinfo->xres; + fbsurf->drawable.height = vinfo->yres; - return ret; + return (fbsurf->drawable.format != PIPE_FORMAT_NONE && + fbsurf->drawable.width && + fbsurf->drawable.height); } static boolean @@ -143,21 +187,43 @@ fbdev_surface_present(struct native_surface *nsurf, boolean preserve, uint swap_interval) { - boolean ret; + struct fbdev_surface *fbsurf = fbdev_surface(nsurf); + struct fbdev_display *fbdpy = fbsurf->fbdpy; + boolean ret = FALSE; - if (preserve || swap_interval) + if (swap_interval) + return FALSE; + if (natt != NATIVE_ATTACHMENT_BACK_LEFT) return FALSE; - switch (natt) { - case NATIVE_ATTACHMENT_FRONT_LEFT: - ret = fbdev_surface_flush_frontbuffer(nsurf); - break; - case NATIVE_ATTACHMENT_BACK_LEFT: - ret = fbdev_surface_swap_buffers(nsurf); - break; - default: - ret = FALSE; - break; + if (!fbdpy->assume_fixed_vinfo) { + struct fb_var_screeninfo vinfo; + + memset(&vinfo, 0, sizeof(vinfo)); + if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &vinfo)) + return FALSE; + + /* present the surface */ + if (fbdev_surface_update_drawable(&fbsurf->base, &vinfo)) { + ret = resource_surface_present(fbsurf->rsurf, + natt, (void *) &fbsurf->drawable); + } + + fbsurf->width = vinfo.xres; + fbsurf->height = vinfo.yres; + + if (resource_surface_set_size(fbsurf->rsurf, + fbsurf->width, fbsurf->height)) { + /* surface resized */ + fbsurf->sequence_number++; + fbdpy->event_handler->invalid_surface(&fbdpy->base, + &fbsurf->base, fbsurf->sequence_number); + } + } + else { + /* the drawable never changes */ + ret = resource_surface_present(fbsurf->rsurf, + natt, (void *) &fbsurf->drawable); } return ret; @@ -179,26 +245,48 @@ fbdev_surface_destroy(struct native_surface *nsurf) } static struct native_surface * -fbdev_display_create_scanout_surface(struct native_display *ndpy, - const struct native_config *nconf, - uint width, uint height) +fbdev_display_create_window_surface(struct native_display *ndpy, + EGLNativeWindowType win, + const struct native_config *nconf) { struct fbdev_display *fbdpy = fbdev_display(ndpy); struct fbdev_surface *fbsurf; + struct fb_var_screeninfo vinfo; + + /* there is only one native window: NULL */ + if (win) + return NULL; fbsurf = CALLOC_STRUCT(fbdev_surface); if (!fbsurf) return NULL; fbsurf->fbdpy = fbdpy; - fbsurf->width = width; - fbsurf->height = height; + + /* get current vinfo */ + if (fbdpy->assume_fixed_vinfo) { + vinfo = fbdpy->config_vinfo; + } + else { + memset(&vinfo, 0, sizeof(vinfo)); + if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &vinfo)) { + FREE(fbsurf); + return NULL; + } + } + + fbsurf->width = vinfo.xres; + fbsurf->height = vinfo.yres; + + if (!fbdev_surface_update_drawable(&fbsurf->base, &vinfo)) { + FREE(fbsurf); + return NULL; + } fbsurf->rsurf = resource_surface_create(fbdpy->base.screen, nconf->color_format, PIPE_BIND_RENDER_TARGET | - PIPE_BIND_DISPLAY_TARGET | - PIPE_BIND_SCANOUT); + PIPE_BIND_DISPLAY_TARGET); if (!fbsurf->rsurf) { FREE(fbsurf); return NULL; @@ -214,42 +302,43 @@ fbdev_display_create_scanout_surface(struct native_display *ndpy, return &fbsurf->base; } +static struct native_surface * +fbdev_display_create_scanout_surface(struct native_display *ndpy, + const struct native_config *nconf, + uint width, uint height) +{ + return fbdev_display_create_window_surface(ndpy, + (EGLNativeWindowType) NULL, nconf); +} + static boolean fbdev_display_program(struct native_display *ndpy, int crtc_idx, struct native_surface *nsurf, uint x, uint y, const struct native_connector **nconns, int num_nconns, const struct native_mode *nmode) { - struct fbdev_display *fbdpy = fbdev_display(ndpy); - struct fbdev_surface *fbsurf = fbdev_surface(nsurf); - - if (x || y) - return FALSE; - - if (fbdpy->current_surface) { - if (fbdpy->current_surface == fbsurf) - return TRUE; - fbdpy->current_surface->is_current = FALSE; - } - - if (fbsurf) - fbsurf->is_current = TRUE; - fbdpy->current_surface = fbsurf; - return TRUE; } static const struct native_mode ** fbdev_display_get_modes(struct native_display *ndpy, - const struct native_connector *nconn, - int *num_modes) + const struct native_connector *nconn, + int *num_modes) { - struct fbdev_display *fbdpy = fbdev_display(ndpy); + static struct native_mode mode; const struct native_mode **modes; + if (!mode.desc) { + struct fbdev_display *fbdpy = fbdev_display(ndpy); + mode.desc = "Current Mode"; + mode.width = fbdpy->config_vinfo.xres; + mode.height = fbdpy->config_vinfo.yres; + mode.refresh_rate = 60 * 1000; /* dummy */ + } + modes = MALLOC(sizeof(*modes)); if (modes) { - modes[0] = &fbdpy->mode; + modes[0] = &mode; if (num_modes) *num_modes = 1; } @@ -261,12 +350,12 @@ static const struct native_connector ** fbdev_display_get_connectors(struct native_display *ndpy, int *num_connectors, int *num_crtc) { - struct fbdev_display *fbdpy = fbdev_display(ndpy); + static struct native_connector connector; const struct native_connector **connectors; connectors = MALLOC(sizeof(*connectors)); if (connectors) { - connectors[0] = &fbdpy->connector; + connectors[0] = &connector; if (num_connectors) *num_connectors = 1; } @@ -274,7 +363,8 @@ fbdev_display_get_connectors(struct native_display *ndpy, int *num_connectors, return connectors; } -static struct native_display_modeset fbdev_display_modeset = { +/* remove modeset support one day! */ +static const struct native_display_modeset fbdev_display_modeset = { .get_connectors = fbdev_display_get_connectors, .get_modes = fbdev_display_get_modes, .create_scanout_surface = fbdev_display_create_scanout_surface, @@ -304,8 +394,10 @@ fbdev_display_get_param(struct native_display *ndpy, int val; switch (param) { - case NATIVE_PARAM_USE_NATIVE_BUFFER: case NATIVE_PARAM_PRESERVE_BUFFER: + val = 1; + break; + case NATIVE_PARAM_USE_NATIVE_BUFFER: case NATIVE_PARAM_MAX_SWAP_INTERVAL: default: val = 0; @@ -326,114 +418,55 @@ fbdev_display_destroy(struct native_display *ndpy) } static boolean -fbdev_display_init_modes(struct native_display *ndpy) +fbdev_display_init_screen(struct native_display *ndpy) { struct fbdev_display *fbdpy = fbdev_display(ndpy); - struct native_mode *nmode = &fbdpy->mode; - - nmode->desc = "Current Mode"; - nmode->width = fbdpy->vinfo.xres; - nmode->height = fbdpy->vinfo.yres; - nmode->refresh_rate = 60 * 1000; /* dummy */ - - return TRUE; -} - -static boolean -fbdev_display_init_connectors(struct native_display *ndpy) -{ - return TRUE; -} + struct sw_winsys *ws; -static enum pipe_format -vinfo_to_format(const struct fb_var_screeninfo *vinfo) -{ - enum pipe_format format = PIPE_FORMAT_NONE; + ws = fbdev_create_sw_winsys(fbdpy->fd); + if (!ws) + return FALSE; - switch (vinfo->bits_per_pixel) { - case 32: - if (vinfo->red.length == 8 && - vinfo->green.length == 8 && - vinfo->blue.length == 8) { - format = (vinfo->transp.length == 8) ? - PIPE_FORMAT_B8G8R8A8_UNORM : PIPE_FORMAT_B8G8R8X8_UNORM; - } - break; - case 16: - if (vinfo->red.length == 5 && - vinfo->green.length == 6 && - vinfo->blue.length == 5 && - vinfo->transp.length == 0) - format = PIPE_FORMAT_B5G6R5_UNORM; - break; - default: - break; + fbdpy->base.screen = fbdpy->event_handler->new_sw_screen(&fbdpy->base, ws); + if (!fbdpy->base.screen) { + if (ws->destroy) + ws->destroy(ws); + return FALSE; } - return format; -} - -static boolean -fbdev_display_init_configs(struct native_display *ndpy) -{ - struct fbdev_display *fbdpy = fbdev_display(ndpy); - struct native_config *nconf = &fbdpy->config; - - nconf->color_format = vinfo_to_format(&fbdpy->vinfo); - if (nconf->color_format == PIPE_FORMAT_NONE) + if (!fbdpy->base.screen->is_format_supported(fbdpy->base.screen, + fbdpy->config.color_format, PIPE_TEXTURE_2D, 0, + PIPE_BIND_RENDER_TARGET)) { + fbdpy->base.screen->destroy(fbdpy->base.screen); + fbdpy->base.screen = NULL; return FALSE; - - nconf->buffer_mask = - (1 << NATIVE_ATTACHMENT_FRONT_LEFT) | - (1 << NATIVE_ATTACHMENT_BACK_LEFT); - - nconf->scanout_bit = TRUE; + } return TRUE; } static boolean -fbdev_display_init(struct native_display *ndpy) +fbdev_display_init_config(struct native_display *ndpy) { struct fbdev_display *fbdpy = fbdev_display(ndpy); - struct sw_winsys *ws; - - if (ioctl(fbdpy->fd, FBIOGET_FSCREENINFO, &fbdpy->finfo)) - return FALSE; + struct native_config *nconf = &fbdpy->config; - if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &fbdpy->vinfo)) + if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &fbdpy->config_vinfo)) return FALSE; - if (fbdpy->finfo.visual != FB_VISUAL_TRUECOLOR || - fbdpy->finfo.type != FB_TYPE_PACKED_PIXELS) + nconf->color_format = vinfo_to_format(&fbdpy->config_vinfo); + if (nconf->color_format == PIPE_FORMAT_NONE) return FALSE; - if (!fbdev_display_init_configs(&fbdpy->base) || - !fbdev_display_init_connectors(&fbdpy->base) || - !fbdev_display_init_modes(&fbdpy->base)) - return FALSE; + nconf->buffer_mask = (1 << NATIVE_ATTACHMENT_BACK_LEFT); - ws = fbdev_create_sw_winsys(fbdpy->fd, fbdpy->config.color_format); - if (ws) { - fbdpy->base.screen = - fbdpy->event_handler->new_sw_screen(&fbdpy->base, ws); - } + nconf->window_bit = TRUE; - if (fbdpy->base.screen) { - if (!fbdpy->base.screen->is_format_supported(fbdpy->base.screen, - fbdpy->config.color_format, PIPE_TEXTURE_2D, 0, - PIPE_BIND_RENDER_TARGET)) { - fbdpy->base.screen->destroy(fbdpy->base.screen); - fbdpy->base.screen = NULL; - } - } - - return (fbdpy->base.screen != NULL); + return TRUE; } static struct native_display * -fbdev_display_create(int fd, struct native_event_handler *event_handler, - void *user_data) +fbdev_display_create(int fd, const struct native_event_handler *event_handler) { struct fbdev_display *fbdpy; @@ -443,32 +476,41 @@ fbdev_display_create(int fd, struct native_event_handler *event_handler, fbdpy->fd = fd; fbdpy->event_handler = event_handler; - fbdpy->base.user_data = user_data; - if (!fbdev_display_init(&fbdpy->base)) { - FREE(fbdpy); - return NULL; - } + if (ioctl(fbdpy->fd, FBIOGET_FSCREENINFO, &fbdpy->finfo)) + goto fail; + + if (fbdpy->finfo.visual != FB_VISUAL_TRUECOLOR || + fbdpy->finfo.type != FB_TYPE_PACKED_PIXELS) + goto fail; + + if (!fbdev_display_init_config(&fbdpy->base)) + goto fail; + fbdpy->assume_fixed_vinfo = TRUE; + + fbdpy->base.init_screen = fbdev_display_init_screen; fbdpy->base.destroy = fbdev_display_destroy; fbdpy->base.get_param = fbdev_display_get_param; fbdpy->base.get_configs = fbdev_display_get_configs; + fbdpy->base.create_window_surface = fbdev_display_create_window_surface; + + /* we'd like to remove modeset support one day */ + fbdpy->config.scanout_bit = TRUE; fbdpy->base.modeset = &fbdev_display_modeset; return &fbdpy->base; -} -static struct native_event_handler *fbdev_event_handler; - -static void -native_set_event_handler(struct native_event_handler *event_handler) -{ - fbdev_event_handler = event_handler; +fail: + FREE(fbdpy); + return NULL; } +static const struct native_event_handler *fbdev_event_handler; + static struct native_display * -native_create_display(void *dpy, boolean use_sw, void *user_data) +native_create_display(void *dpy, boolean use_sw) { struct native_display *ndpy; int fd; @@ -483,7 +525,7 @@ native_create_display(void *dpy, boolean use_sw, void *user_data) if (fd < 0) return NULL; - ndpy = fbdev_display_create(fd, fbdev_event_handler, user_data); + ndpy = fbdev_display_create(fd, fbdev_event_handler); if (!ndpy) close(fd); @@ -492,12 +534,12 @@ native_create_display(void *dpy, boolean use_sw, void *user_data) static const struct native_platform fbdev_platform = { "FBDEV", /* name */ - native_set_event_handler, native_create_display }; const struct native_platform * -native_get_fbdev_platform(void) +native_get_fbdev_platform(const struct native_event_handler *event_handler) { + fbdev_event_handler = event_handler; return &fbdev_platform; } diff --git a/src/gallium/state_trackers/egl/gdi/native_gdi.c b/src/gallium/state_trackers/egl/gdi/native_gdi.c index 5d0045f92ee..6bf0d4e4668 100644 --- a/src/gallium/state_trackers/egl/gdi/native_gdi.c +++ b/src/gallium/state_trackers/egl/gdi/native_gdi.c @@ -41,7 +41,7 @@ struct gdi_display { struct native_display base; HDC hDC; - struct native_event_handler *event_handler; + const struct native_event_handler *event_handler; struct native_config *configs; int num_configs; @@ -368,35 +368,39 @@ gdi_display_destroy(struct native_display *ndpy) FREE(gdpy); } -static struct native_display * -gdi_create_display(HDC hDC, struct native_event_handler *event_handler, - void *user_data) +static boolean +gdi_display_init_screen(struct native_display *ndpy) { - struct gdi_display *gdpy; + struct gdi_display *gdpy = gdi_display(ndpy); struct sw_winsys *winsys; - gdpy = CALLOC_STRUCT(gdi_display); - if (!gdpy) - return NULL; - - gdpy->hDC = hDC; - gdpy->event_handler = event_handler; - gdpy->base.user_data = user_data; - winsys = gdi_create_sw_winsys(); - if (!winsys) { - FREE(gdpy); - return NULL; - } + if (!winsys) + return FALSE; gdpy->base.screen = gdpy->event_handler->new_sw_screen(&gdpy->base, winsys); if (!gdpy->base.screen) { if (winsys->destroy) winsys->destroy(winsys); - FREE(gdpy); - return NULL; + return FALSE; } + return TRUE; +} + +static struct native_display * +gdi_create_display(HDC hDC, const struct native_event_handler *event_handler) +{ + struct gdi_display *gdpy; + + gdpy = CALLOC_STRUCT(gdi_display); + if (!gdpy) + return NULL; + + gdpy->hDC = hDC; + gdpy->event_handler = event_handler; + + gdpy->base.init_screen = gdi_display_init_screen; gdpy->base.destroy = gdi_display_destroy; gdpy->base.get_param = gdi_display_get_param; @@ -406,28 +410,22 @@ gdi_create_display(HDC hDC, struct native_event_handler *event_handler, return &gdpy->base; } -static struct native_event_handler *gdi_event_handler; - -static void -native_set_event_handler(struct native_event_handler *event_handler) -{ - gdi_event_handler = event_handler; -} +static const struct native_event_handler *gdi_event_handler; static struct native_display * -native_create_display(void *dpy, boolean use_sw, void *user_data) +native_create_display(void *dpy, boolean use_sw) { - return gdi_create_display((HDC) dpy, gdi_event_handler, user_data); + return gdi_create_display((HDC) dpy, gdi_event_handler); } static const struct native_platform gdi_platform = { "GDI", /* name */ - native_set_event_handler, native_create_display }; const struct native_platform * -native_get_gdi_platform(void) +native_get_gdi_platform(const struct native_event_handler *event_handler) { + gdi_event_handler = event_handler; return &gdi_platform; } diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c index 15383e89301..e34b24b58b1 100644 --- a/src/gallium/state_trackers/egl/wayland/native_drm.c +++ b/src/gallium/state_trackers/egl/wayland/native_drm.c @@ -51,7 +51,7 @@ struct wayland_drm_display { struct wayland_display base; - struct native_event_handler *event_handler; + const struct native_event_handler *event_handler; struct wl_drm *wl_drm; struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */ @@ -98,6 +98,8 @@ wayland_drm_display_destroy(struct native_display *ndpy) FREE(drmdpy->device_name); if (drmdpy->base.config) FREE(drmdpy->base.config); + if (drmdpy->base.own_dpy) + wl_display_destroy(drmdpy->base.dpy); ndpy_uninit(ndpy); @@ -210,27 +212,10 @@ wayland_drm_display_init_screen(struct native_display *ndpy) return TRUE; } -static struct pipe_resource * -wayland_drm_display_import_buffer(struct native_display *ndpy, - const struct pipe_resource *templ, - void *buf) -{ - return ndpy->screen->resource_from_handle(ndpy->screen, - templ, (struct winsys_handle *) buf); -} - -static boolean -wayland_drm_display_export_buffer(struct native_display *ndpy, - struct pipe_resource *res, - void *buf) -{ - return ndpy->screen->resource_get_handle(ndpy->screen, - res, (struct winsys_handle *) buf); -} - static struct native_display_buffer wayland_drm_display_buffer = { - wayland_drm_display_import_buffer, - wayland_drm_display_export_buffer + /* use the helpers */ + drm_display_import_native_buffer, + drm_display_export_native_buffer }; static int @@ -300,8 +285,7 @@ static struct native_display_wayland_bufmgr wayland_drm_display_wayland_bufmgr = struct wayland_display * wayland_create_drm_display(struct wl_display *dpy, - struct native_event_handler *event_handler, - void *user_data) + const struct native_event_handler *event_handler) { struct wayland_drm_display *drmdpy; @@ -310,7 +294,6 @@ wayland_create_drm_display(struct wl_display *dpy, return NULL; drmdpy->event_handler = event_handler; - drmdpy->base.base.user_data = user_data; drmdpy->base.dpy = dpy; if (!drmdpy->base.dpy) { @@ -318,10 +301,7 @@ wayland_create_drm_display(struct wl_display *dpy, return NULL; } - if (!wayland_drm_display_init_screen(&drmdpy->base.base)) { - wayland_drm_display_destroy(&drmdpy->base.base); - return NULL; - } + drmdpy->base.base.init_screen = wayland_drm_display_init_screen; drmdpy->base.base.destroy = wayland_drm_display_destroy; drmdpy->base.base.buffer = &wayland_drm_display_buffer; drmdpy->base.base.wayland_bufmgr = &wayland_drm_display_wayland_bufmgr; diff --git a/src/gallium/state_trackers/egl/wayland/native_shm.c b/src/gallium/state_trackers/egl/wayland/native_shm.c index 609fc0cd04a..1c0799528fe 100644 --- a/src/gallium/state_trackers/egl/wayland/native_shm.c +++ b/src/gallium/state_trackers/egl/wayland/native_shm.c @@ -47,7 +47,7 @@ struct wayland_shm_display { struct wayland_display base; - struct native_event_handler *event_handler; + const struct native_event_handler *event_handler; struct wl_shm *wl_shm; }; @@ -65,6 +65,8 @@ wayland_shm_display_destroy(struct native_display *ndpy) if (shmdpy->base.config) FREE(shmdpy->base.config); + if (shmdpy->base.own_dpy) + wl_display_destroy(shmdpy->base.dpy); ndpy_uninit(ndpy); @@ -142,8 +144,7 @@ wayland_shm_display_init_screen(struct native_display *ndpy) struct wayland_display * wayland_create_shm_display(struct wl_display *dpy, - struct native_event_handler *event_handler, - void *user_data) + const struct native_event_handler *event_handler) { struct wayland_shm_display *shmdpy; @@ -152,7 +153,6 @@ wayland_create_shm_display(struct wl_display *dpy, return NULL; shmdpy->event_handler = event_handler; - shmdpy->base.base.user_data = user_data; shmdpy->base.dpy = dpy; if (!shmdpy->base.dpy) { @@ -160,11 +160,7 @@ wayland_create_shm_display(struct wl_display *dpy, return NULL; } - if (!wayland_shm_display_init_screen(&shmdpy->base.base)) { - wayland_shm_display_destroy(&shmdpy->base.base); - return NULL; - } - + shmdpy->base.base.init_screen = wayland_shm_display_init_screen; shmdpy->base.base.destroy = wayland_shm_display_destroy; shmdpy->base.create_buffer = wayland_create_shm_buffer; diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.c b/src/gallium/state_trackers/egl/wayland/native_wayland.c index 0292d5631d6..544d4be215a 100644 --- a/src/gallium/state_trackers/egl/wayland/native_wayland.c +++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c @@ -35,7 +35,7 @@ #include "native_wayland.h" -static struct native_event_handler *wayland_event_handler; +static const struct native_event_handler *wayland_event_handler; static void sync_callback(void *data) @@ -114,11 +114,12 @@ wayland_display_get_param(struct native_display *ndpy, } static boolean -wayland_display_is_pixmap_supported(struct native_display *ndpy, - EGLNativePixmapType pix, - const struct native_config *nconf) +wayland_display_get_pixmap_format(struct native_display *ndpy, + EGLNativePixmapType pix, + enum pipe_format *format) { /* all wl_egl_pixmaps are supported */ + *format = PIPE_FORMAT_NONE; return TRUE; } @@ -195,13 +196,11 @@ wayland_window_surface_handle_resize(struct wayland_surface *surface) wl_buffer_destroy(surface->buffer[i]); surface->buffer[i] = NULL; } + + surface->dx = surface->win->dx; + surface->dy = surface->win->dy; } pipe_resource_reference(&front_resource, NULL); - - surface->dx = surface->win->dx; - surface->dy = surface->win->dy; - surface->win->dx = 0; - surface->win->dy = 0; } static boolean @@ -449,28 +448,28 @@ wayland_create_window_surface(struct native_display *ndpy, return &surface->base; } -static void -native_set_event_handler(struct native_event_handler *event_handler) -{ - wayland_event_handler = event_handler; -} - static struct native_display * -native_create_display(void *dpy, boolean use_sw, void *user_data) +native_create_display(void *dpy, boolean use_sw) { struct wayland_display *display = NULL; + boolean own_dpy = FALSE; use_sw = use_sw || debug_get_bool_option("EGL_SOFTWARE", FALSE); + if (dpy == NULL) { + dpy = wl_display_connect(NULL); + if (dpy == NULL) + return NULL; + own_dpy = TRUE; + } + if (use_sw) { _eglLog(_EGL_INFO, "use software fallback"); display = wayland_create_shm_display((struct wl_display *) dpy, - wayland_event_handler, - user_data); + wayland_event_handler); } else { display = wayland_create_drm_display((struct wl_display *) dpy, - wayland_event_handler, - user_data); + wayland_event_handler); } if (!display) @@ -478,22 +477,25 @@ native_create_display(void *dpy, boolean use_sw, void *user_data) display->base.get_param = wayland_display_get_param; display->base.get_configs = wayland_display_get_configs; - display->base.is_pixmap_supported = wayland_display_is_pixmap_supported; + display->base.get_pixmap_format = wayland_display_get_pixmap_format; + display->base.copy_to_pixmap = native_display_copy_to_pixmap; display->base.create_window_surface = wayland_create_window_surface; display->base.create_pixmap_surface = wayland_create_pixmap_surface; + display->own_dpy = own_dpy; + return &display->base; } static const struct native_platform wayland_platform = { "wayland", /* name */ - native_set_event_handler, native_create_display }; const struct native_platform * -native_get_wayland_platform(void) +native_get_wayland_platform(const struct native_event_handler *event_handler) { + wayland_event_handler = event_handler; return &wayland_platform; } diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.h b/src/gallium/state_trackers/egl/wayland/native_wayland.h index e69a8f00f82..5390f2f08c9 100644 --- a/src/gallium/state_trackers/egl/wayland/native_wayland.h +++ b/src/gallium/state_trackers/egl/wayland/native_wayland.h @@ -41,6 +41,7 @@ struct wayland_display { struct wayland_config *config; struct wl_display *dpy; + boolean own_dpy; struct wl_buffer *(*create_buffer)(struct wayland_display *display, struct wayland_surface *surface, @@ -102,11 +103,10 @@ wayland_config(const struct native_config *nconf) struct wayland_display * wayland_create_shm_display(struct wl_display *display, - struct native_event_handler *event_handler, - void *user_data); + const struct native_event_handler *event_handler); + struct wayland_display * wayland_create_drm_display(struct wl_display *display, - struct native_event_handler *event_handler, - void *user_data); + const struct native_event_handler *event_handler); #endif /* _NATIVE_WAYLAND_H_ */ diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c index a56d43428fc..4b8be7bc759 100644 --- a/src/gallium/state_trackers/egl/x11/native_dri2.c +++ b/src/gallium/state_trackers/egl/x11/native_dri2.c @@ -38,6 +38,7 @@ #include "native_x11.h" #include "x11_screen.h" +#include "common/native_helper.h" #ifdef HAVE_WAYLAND_BACKEND #include "common/native_wayland_drm_bufmgr_helper.h" #endif @@ -49,7 +50,7 @@ struct dri2_display { Display *dpy; boolean own_dpy; - struct native_event_handler *event_handler; + const struct native_event_handler *event_handler; struct x11_screen *xscr; int xscr_number; @@ -682,18 +683,30 @@ dri2_display_get_configs(struct native_display *ndpy, int *num_configs) } static boolean -dri2_display_is_pixmap_supported(struct native_display *ndpy, - EGLNativePixmapType pix, - const struct native_config *nconf) +dri2_display_get_pixmap_format(struct native_display *ndpy, + EGLNativePixmapType pix, + enum pipe_format *format) { struct dri2_display *dri2dpy = dri2_display(ndpy); - uint depth, nconf_depth; + boolean ret = EGL_TRUE; + uint depth; depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix); - nconf_depth = util_format_get_blocksizebits(nconf->color_format); + switch (depth) { + case 32: + case 24: + *format = PIPE_FORMAT_B8G8R8A8_UNORM; + break; + case 16: + *format = PIPE_FORMAT_B5G6R5_UNORM; + break; + default: + *format = PIPE_FORMAT_NONE; + ret = EGL_FALSE; + break; + } - /* simple depth match for now */ - return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth)); + return ret; } static int @@ -870,8 +883,7 @@ static struct native_display_wayland_bufmgr dri2_display_wayland_bufmgr = { struct native_display * x11_create_dri2_display(Display *dpy, - struct native_event_handler *event_handler, - void *user_data) + const struct native_event_handler *event_handler) { struct dri2_display *dri2dpy; @@ -880,7 +892,6 @@ x11_create_dri2_display(Display *dpy, return NULL; dri2dpy->event_handler = event_handler; - dri2dpy->base.user_data = user_data; dri2dpy->dpy = dpy; if (!dri2dpy->dpy) { @@ -899,11 +910,6 @@ x11_create_dri2_display(Display *dpy, return NULL; } - if (!dri2_display_init_screen(&dri2dpy->base)) { - dri2_display_destroy(&dri2dpy->base); - return NULL; - } - dri2dpy->surfaces = util_hash_table_create(dri2_display_hash_table_hash, dri2_display_hash_table_compare); if (!dri2dpy->surfaces) { @@ -911,10 +917,12 @@ x11_create_dri2_display(Display *dpy, return NULL; } + dri2dpy->base.init_screen = dri2_display_init_screen; dri2dpy->base.destroy = dri2_display_destroy; dri2dpy->base.get_param = dri2_display_get_param; dri2dpy->base.get_configs = dri2_display_get_configs; - dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported; + dri2dpy->base.get_pixmap_format = dri2_display_get_pixmap_format; + dri2dpy->base.copy_to_pixmap = native_display_copy_to_pixmap; dri2dpy->base.create_window_surface = dri2_display_create_window_surface; dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface; #ifdef HAVE_WAYLAND_BACKEND @@ -928,8 +936,7 @@ x11_create_dri2_display(Display *dpy, struct native_display * x11_create_dri2_display(Display *dpy, - struct native_event_handler *event_handler, - void *user_data) + const struct native_event_handler *event_handler) { return NULL; } diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c index a0bcad4c734..ef038b52152 100644 --- a/src/gallium/state_trackers/egl/x11/native_x11.c +++ b/src/gallium/state_trackers/egl/x11/native_x11.c @@ -30,16 +30,10 @@ #include "native_x11.h" -static struct native_event_handler *x11_event_handler; - -static void -native_set_event_handler(struct native_event_handler *event_handler) -{ - x11_event_handler = event_handler; -} +static const struct native_event_handler *x11_event_handler; static struct native_display * -native_create_display(void *dpy, boolean use_sw, void *user_data) +native_create_display(void *dpy, boolean use_sw) { struct native_display *ndpy = NULL; boolean force_sw; @@ -48,12 +42,10 @@ native_create_display(void *dpy, boolean use_sw, void *user_data) if (force_sw || use_sw) { _eglLog(_EGL_INFO, "use software fallback"); - ndpy = x11_create_ximage_display((Display *) dpy, - x11_event_handler, user_data); + ndpy = x11_create_ximage_display((Display *) dpy, x11_event_handler); } else { - ndpy = x11_create_dri2_display((Display *) dpy, - x11_event_handler, user_data); + ndpy = x11_create_dri2_display((Display *) dpy, x11_event_handler); } return ndpy; @@ -61,12 +53,12 @@ native_create_display(void *dpy, boolean use_sw, void *user_data) static const struct native_platform x11_platform = { "X11", /* name */ - native_set_event_handler, native_create_display }; const struct native_platform * -native_get_x11_platform(void) +native_get_x11_platform(const struct native_event_handler *event_handler) { + x11_event_handler = event_handler; return &x11_platform; } diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h index 8945117276e..d3c9270a667 100644 --- a/src/gallium/state_trackers/egl/x11/native_x11.h +++ b/src/gallium/state_trackers/egl/x11/native_x11.h @@ -31,12 +31,10 @@ struct native_display * x11_create_ximage_display(Display *dpy, - struct native_event_handler *event_handler, - void *user_data); + const struct native_event_handler *event_handler); struct native_display * x11_create_dri2_display(Display *dpy, - struct native_event_handler *event_handler, - void *user_data); + const struct native_event_handler *event_handler); #endif /* _NATIVE_X11_H_ */ diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c index 8e32c6ff0c4..e7794f0d3d7 100644 --- a/src/gallium/state_trackers/egl/x11/native_ximage.c +++ b/src/gallium/state_trackers/egl/x11/native_ximage.c @@ -43,7 +43,7 @@ struct ximage_display { Display *dpy; boolean own_dpy; - struct native_event_handler *event_handler; + const struct native_event_handler *event_handler; struct x11_screen *xscr; int xscr_number; @@ -437,14 +437,54 @@ ximage_display_get_configs(struct native_display *ndpy, int *num_configs) } static boolean -ximage_display_is_pixmap_supported(struct native_display *ndpy, - EGLNativePixmapType pix, - const struct native_config *nconf) +ximage_display_get_pixmap_format(struct native_display *ndpy, + EGLNativePixmapType pix, + enum pipe_format *format) { struct ximage_display *xdpy = ximage_display(ndpy); - enum pipe_format fmt = get_pixmap_format(&xdpy->base, pix); - return (fmt == nconf->color_format); + *format = get_pixmap_format(&xdpy->base, pix); + + return (*format != PIPE_FORMAT_NONE); +} + +static boolean +ximage_display_copy_to_pixmap(struct native_display *ndpy, + EGLNativePixmapType pix, + struct pipe_resource *src) +{ + /* fast path to avoid unnecessary allocation and resource_copy_region */ + if (src->bind & PIPE_BIND_DISPLAY_TARGET) { + struct ximage_display *xdpy = ximage_display(ndpy); + enum pipe_format fmt = get_pixmap_format(&xdpy->base, pix); + const struct ximage_config *xconf; + struct xlib_drawable xdraw; + int i; + + if (fmt == PIPE_FORMAT_NONE || src->format != fmt) + return FALSE; + + for (i = 0; i < xdpy->num_configs; i++) { + if (xdpy->configs[i].base.color_format == fmt) { + xconf = &xdpy->configs[i]; + break; + } + } + if (!xconf) + return FALSE; + + memset(&xdraw, 0, sizeof(xdraw)); + xdraw.visual = xconf->visual->visual; + xdraw.depth = xconf->visual->depth; + xdraw.drawable = (Drawable) pix; + + xdpy->base.screen->flush_frontbuffer(xdpy->base.screen, + src, 0, 0, &xdraw); + + return TRUE; + } + + return native_display_copy_to_pixmap(ndpy, pix, src); } static int @@ -484,13 +524,32 @@ ximage_display_destroy(struct native_display *ndpy) FREE(xdpy); } +static boolean +ximage_display_init_screen(struct native_display *ndpy) +{ + struct ximage_display *xdpy = ximage_display(ndpy); + struct sw_winsys *winsys; + + winsys = xlib_create_sw_winsys(xdpy->dpy); + if (!winsys) + return FALSE; + + xdpy->base.screen = + xdpy->event_handler->new_sw_screen(&xdpy->base, winsys); + if (!xdpy->base.screen) { + if (winsys->destroy) + winsys->destroy(winsys); + return FALSE; + } + + return TRUE; +} + struct native_display * x11_create_ximage_display(Display *dpy, - struct native_event_handler *event_handler, - void *user_data) + const struct native_event_handler *event_handler) { struct ximage_display *xdpy; - struct sw_winsys *winsys = NULL; xdpy = CALLOC_STRUCT(ximage_display); if (!xdpy) @@ -507,39 +566,25 @@ x11_create_ximage_display(Display *dpy, } xdpy->event_handler = event_handler; - xdpy->base.user_data = user_data; xdpy->xscr_number = DefaultScreen(xdpy->dpy); xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number); - if (!xdpy->xscr) - goto fail; - - winsys = xlib_create_sw_winsys(xdpy->dpy); - if (!winsys) - goto fail; - - xdpy->base.screen = - xdpy->event_handler->new_sw_screen(&xdpy->base, winsys); - if (!xdpy->base.screen) - goto fail; + if (!xdpy->xscr) { + if (xdpy->own_dpy) + XCloseDisplay(xdpy->dpy); + FREE(xdpy); + return NULL; + } + xdpy->base.init_screen = ximage_display_init_screen; xdpy->base.destroy = ximage_display_destroy; xdpy->base.get_param = ximage_display_get_param; xdpy->base.get_configs = ximage_display_get_configs; - xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported; + xdpy->base.get_pixmap_format = ximage_display_get_pixmap_format; + xdpy->base.copy_to_pixmap = ximage_display_copy_to_pixmap; xdpy->base.create_window_surface = ximage_display_create_window_surface; xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface; return &xdpy->base; - -fail: - if (winsys && winsys->destroy) - winsys->destroy(winsys); - if (xdpy->xscr) - x11_screen_destroy(xdpy->xscr); - if (xdpy->dpy && xdpy->own_dpy) - XCloseDisplay(xdpy->dpy); - FREE(xdpy); - return NULL; } diff --git a/src/gallium/state_trackers/gbm/Makefile b/src/gallium/state_trackers/gbm/Makefile new file mode 100644 index 00000000000..1d96eb2032d --- /dev/null +++ b/src/gallium/state_trackers/gbm/Makefile @@ -0,0 +1,46 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +gbm_INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gbm/main \ + -I$(TOP)/include + +gbm_SOURCES = $(wildcard *.c) +gbm_OBJECTS = $(gbm_SOURCES:.c=.o) + +ALL_INCLUDES = $(gbm_INCLUDES) +ALL_SOURCES = $(gbm_SOURCES) + +GBM_OBJECTS = $(gbm_OBJECTS) +GBM_CPPFLAGS = $(gbm_INCLUDES) + +##### TARGETS ##### + +default: depend libgbm.a + +libgbm.a: $(GBM_OBJECTS) Makefile + $(MKLIB) -o gbm -static $(GBM_OBJECTS) + +depend: + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(ALL_INCLUDES) $(ALL_SOURCES) 2> /dev/null + +clean: + rm -f libgbm.a + rm -f $(GBM_OBJECTS) + rm -f depend depend.bak + +# Dummy target +install: + @echo -n "" + +##### RULES ##### + +$(gbm_OBJECTS): %.o: %.c + $(CC) -c $(GBM_CPPFLAGS) $(DEFINES) $(CFLAGS) $< -o $@ + +sinclude depend diff --git a/src/gallium/state_trackers/gbm/gbm_drm.c b/src/gallium/state_trackers/gbm/gbm_drm.c new file mode 100644 index 00000000000..d4baf87096a --- /dev/null +++ b/src/gallium/state_trackers/gbm/gbm_drm.c @@ -0,0 +1,226 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#include "util/u_memory.h" +#include "util/u_inlines.h" + +#include "state_tracker/drm_driver.h" + +#include <unistd.h> +#include <sys/types.h> + +#include "gbm_gallium_drmint.h" + +static INLINE enum pipe_format +gbm_format_to_gallium(enum gbm_bo_format format) +{ + switch (format) { + case GBM_BO_FORMAT_XRGB8888: + return PIPE_FORMAT_B8G8R8X8_UNORM; + case GBM_BO_FORMAT_ARGB8888: + return PIPE_FORMAT_B8G8R8A8_UNORM; + default: + return PIPE_FORMAT_NONE; + } + + return PIPE_FORMAT_NONE; +} + +static INLINE uint +gbm_usage_to_gallium(uint usage) +{ + uint resource_usage = 0; + + if (usage & GBM_BO_USE_SCANOUT) + resource_usage |= PIPE_BIND_SCANOUT; + + if (usage & GBM_BO_USE_RENDERING) + resource_usage |= PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; + + if (usage & GBM_BO_USE_CURSOR_64X64) + resource_usage |= PIPE_BIND_CURSOR; + + return resource_usage; +} + +static int +gbm_gallium_drm_is_format_supported(struct gbm_device *gbm, + enum gbm_bo_format format, + uint32_t usage) +{ + struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); + enum pipe_format pf; + + pf = gbm_format_to_gallium(format); + if (pf == PIPE_FORMAT_NONE) + return 0; + + if (!gdrm->screen->is_format_supported(gdrm->screen, PIPE_TEXTURE_2D, pf, 0, + gbm_usage_to_gallium(usage))) + return 0; + + if (usage & GBM_BO_USE_SCANOUT && format != GBM_BO_FORMAT_XRGB8888) + return 0; + + return 1; +} + +static void +gbm_gallium_drm_bo_destroy(struct gbm_bo *_bo) +{ + struct gbm_gallium_drm_bo *bo = gbm_gallium_drm_bo(_bo); + + pipe_resource_reference(&bo->resource, NULL); + free(bo); +} + +static struct gbm_bo * +gbm_gallium_drm_bo_create_from_egl_image(struct gbm_device *gbm, + void *egl_dpy, void *egl_image, + uint32_t width, uint32_t height, + uint32_t usage) +{ + struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); + struct gbm_gallium_drm_bo *bo; + struct winsys_handle whandle; + + if (!gdrm->lookup_egl_image) + return NULL; + + bo = CALLOC_STRUCT(gbm_gallium_drm_bo); + if (bo == NULL) + return NULL; + + bo->resource = gdrm->lookup_egl_image(gdrm->lookup_egl_image_data, + egl_image); + if (bo->resource == NULL) { + FREE(bo); + return NULL; + } + + bo->base.base.gbm = gbm; + bo->base.base.width = width; + bo->base.base.height = height; + + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_KMS; + gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle); + + bo->base.base.handle.u32 = whandle.handle; + bo->base.base.pitch = whandle.stride; + + return &bo->base.base; +} + +static struct gbm_bo * +gbm_gallium_drm_bo_create(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, uint32_t usage) +{ + struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); + struct gbm_gallium_drm_bo *bo; + struct pipe_resource templ; + struct winsys_handle whandle; + enum pipe_format pf; + + bo = CALLOC_STRUCT(gbm_gallium_drm_bo); + if (bo == NULL) + return NULL; + + bo->base.base.gbm = gbm; + bo->base.base.width = width; + bo->base.base.height = height; + + pf = gbm_format_to_gallium(format); + if (pf == PIPE_FORMAT_NONE) + return NULL; + + memset(&templ, 0, sizeof(templ)); + templ.bind = gbm_usage_to_gallium(usage); + templ.format = pf; + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; + templ.array_size = 1; + + bo->resource = gdrm->screen->resource_create(gdrm->screen, &templ); + if (bo->resource == NULL) { + FREE(bo); + return NULL; + } + + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_KMS; + gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle); + + bo->base.base.handle.u32 = whandle.handle; + bo->base.base.pitch = whandle.stride; + + return &bo->base.base; +} + +static void +gbm_gallium_drm_destroy(struct gbm_device *gbm) +{ + struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm); + + gdrm->screen->destroy(gdrm->screen); + + FREE(gdrm->base.driver_name); + + FREE(gdrm); +} + +struct gbm_device * +gbm_gallium_drm_device_create(int fd) +{ + struct gbm_gallium_drm_device *gdrm; + int ret; + + gdrm = calloc(1, sizeof *gdrm); + + gdrm->base.base.fd = fd; + gdrm->base.base.bo_create = gbm_gallium_drm_bo_create; + gdrm->base.base.bo_create_from_egl_image = + gbm_gallium_drm_bo_create_from_egl_image; + gdrm->base.base.bo_destroy = gbm_gallium_drm_bo_destroy; + gdrm->base.base.is_format_supported = gbm_gallium_drm_is_format_supported; + gdrm->base.base.destroy = gbm_gallium_drm_destroy; + + gdrm->base.type = GBM_DRM_DRIVER_TYPE_GALLIUM; + gdrm->base.base.name = "drm"; + + ret = gallium_screen_create(gdrm); + if (ret) { + free(gdrm); + return NULL; + } + + return &gdrm->base.base; +} diff --git a/src/gallium/state_trackers/gbm/gbm_gallium_drmint.h b/src/gallium/state_trackers/gbm/gbm_gallium_drmint.h new file mode 100644 index 00000000000..6277b8dba2e --- /dev/null +++ b/src/gallium/state_trackers/gbm/gbm_gallium_drmint.h @@ -0,0 +1,74 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#ifndef _GBM_GALLIUM_DRMINT_H_ +#define _GBM_GALLIUM_DRMINT_H_ + +#include "pipe/p_state.h" + +#include "gbmint.h" + +#include "common.h" +#include "common_drm.h" + +struct gbm_gallium_drm_device { + struct gbm_drm_device base; + + struct pipe_screen *screen; + void *driver; + + struct pipe_resource *(*lookup_egl_image)(void *data, + void *egl_image); + void *lookup_egl_image_data; + +}; + +struct gbm_gallium_drm_bo { + struct gbm_drm_bo base; + + struct pipe_resource *resource; +}; + +static inline struct gbm_gallium_drm_device * +gbm_gallium_drm_device(struct gbm_device *gbm) +{ + return (struct gbm_gallium_drm_device *) gbm; +} + +static inline struct gbm_gallium_drm_bo * +gbm_gallium_drm_bo(struct gbm_bo *bo) +{ + return (struct gbm_gallium_drm_bo *) bo; +} + +struct gbm_device * +gbm_gallium_drm_device_create(int fd); + +int +gallium_screen_create(struct gbm_gallium_drm_device *gdrm); + +#endif diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index ab4f6753e11..8f6406ddaee 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -59,6 +59,7 @@ #include "pipe/p_defines.h" #include "pipe/p_screen.h" #include "pipe/p_context.h" +#include "util/u_atomic.h" #include "xm_public.h" #include <GL/glx.h> @@ -1113,10 +1114,7 @@ XMesaDestroyBuffer(XMesaBuffer b) void xmesa_notify_invalid_buffer(XMesaBuffer b) { - XMesaContext xmctx = XMesaGetCurrentContext(); - - if (xmctx && xmctx->xm_buffer == b) - xmctx->st->notify_invalid_framebuffer(xmctx->st, b->stfb); + p_atomic_inc(&b->stfb->stamp); } @@ -1126,11 +1124,18 @@ xmesa_notify_invalid_buffer(XMesaBuffer b) void xmesa_check_buffer_size(XMesaBuffer b) { + GLuint old_width, old_height; + if (b->type == PBUFFER) return; + old_width = b->width; + old_height = b->height; + xmesa_get_window_size(b->xm_visual->display, b, &b->width, &b->height); - xmesa_notify_invalid_buffer(b); + + if (b->width != old_width || b->height != old_height) + xmesa_notify_invalid_buffer(b); } diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c index 6bfe8b0788c..ec3f531f7df 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_st.c +++ b/src/gallium/state_trackers/glx/xlib/xm_st.c @@ -30,6 +30,7 @@ #include "xm_st.h" #include "util/u_inlines.h" +#include "util/u_atomic.h" struct xmesa_st_framebuffer { XMesaDisplay display; @@ -302,6 +303,7 @@ xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b) stfbi->visual = &xstfb->stvis; stfbi->flush_front = xmesa_st_framebuffer_flush_front; stfbi->validate = xmesa_st_framebuffer_validate; + p_atomic_set(&stfbi->stamp, 1); stfbi->st_manager_private = (void *) xstfb; return stfbi; diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h index 71491a5aa22..d91ee9797f1 100644 --- a/src/gallium/state_trackers/vega/vg_context.h +++ b/src/gallium/state_trackers/vega/vg_context.h @@ -65,6 +65,8 @@ struct st_framebuffer { enum st_attachment_type strb_att; void *privateData; + int32_t stamp; + int32_t iface_stamp; }; enum vg_object_type { @@ -105,7 +107,6 @@ struct vg_context VGErrorCode _error; struct st_framebuffer *draw_buffer; - int32_t draw_buffer_invalid; struct cso_hash *owned_objects[VG_OBJECT_LAST]; @@ -129,6 +130,8 @@ struct vg_context struct vg_paint *default_paint; struct blit_state *blit; + + int32_t draw_stamp; }; diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c index eeea68677de..dec1581fb84 100644 --- a/src/gallium/state_trackers/vega/vg_manager.c +++ b/src/gallium/state_trackers/vega/vg_manager.c @@ -106,35 +106,38 @@ vg_manager_validate_framebuffer(struct vg_context *ctx) { struct st_framebuffer *stfb = ctx->draw_buffer; struct pipe_resource *pt; + int32_t new_stamp; /* no binding surface */ if (!stfb) return; - if (!p_atomic_read(&ctx->draw_buffer_invalid)) - return; + new_stamp = p_atomic_read(&stfb->iface->stamp); + if (stfb->iface_stamp != new_stamp) { + do { + /* validate the fb */ + if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, + 1, &pt) || !pt) + return; - /* validate the fb */ - if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt) - return; + stfb->iface_stamp = new_stamp; + new_stamp = p_atomic_read(&stfb->iface->stamp); - p_atomic_set(&ctx->draw_buffer_invalid, FALSE); + } while (stfb->iface_stamp != new_stamp); - if (vg_context_update_color_rb(ctx, pt) || - stfb->width != pt->width0 || - stfb->height != pt->height0) - ctx->state.dirty |= FRAMEBUFFER_DIRTY; + if (vg_context_update_color_rb(ctx, pt) || + stfb->width != pt->width0 || + stfb->height != pt->height0) + ++stfb->stamp; - stfb->width = pt->width0; - stfb->height = pt->height0; -} + stfb->width = pt->width0; + stfb->height = pt->height0; + } -static void -vg_context_notify_invalid_framebuffer(struct st_context_iface *stctxi, - struct st_framebuffer_iface *stfbi) -{ - struct vg_context *ctx = (struct vg_context *) stctxi; - p_atomic_set(&ctx->draw_buffer_invalid, TRUE); + if (ctx->draw_stamp != stfb->stamp) { + ctx->state.dirty |= FRAMEBUFFER_DIRTY; + ctx->draw_stamp = stfb->stamp; + } } static void @@ -187,8 +190,6 @@ vg_api_create_context(struct st_api *stapi, struct st_manager *smapi, ctx->iface.destroy = vg_context_destroy; - ctx->iface.notify_invalid_framebuffer = - vg_context_notify_invalid_framebuffer; ctx->iface.flush = vg_context_flush; ctx->iface.teximage = NULL; @@ -266,8 +267,6 @@ vg_context_bind_framebuffers(struct st_context_iface *stctxi, if (stdrawi != streadi) return FALSE; - p_atomic_set(&ctx->draw_buffer_invalid, TRUE); - strb_att = (stdrawi) ? choose_attachment(stdrawi) : ST_ATTACHMENT_INVALID; if (ctx->draw_buffer) { @@ -313,11 +312,14 @@ vg_context_bind_framebuffers(struct st_context_iface *stctxi, stfb->width = 0; stfb->height = 0; stfb->strb_att = strb_att; + stfb->stamp = 1; + stfb->iface_stamp = p_atomic_read(&stdrawi->stamp) - 1; ctx->draw_buffer = stfb; } ctx->draw_buffer->iface = stdrawi; + ctx->draw_stamp = ctx->draw_buffer->stamp - 1; return TRUE; } diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c index 5608d4f4ce7..c2839fe815f 100644 --- a/src/gallium/state_trackers/wgl/stw_context.c +++ b/src/gallium/state_trackers/wgl/stw_context.c @@ -31,6 +31,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "util/u_memory.h" +#include "util/u_atomic.h" #include "state_tracker/st_api.h" #include "stw_icd.h" @@ -361,10 +362,7 @@ stw_flush_current_locked( struct stw_framebuffer *fb ) void stw_notify_current_locked( struct stw_framebuffer *fb ) { - struct stw_context *ctx = stw_current_context(); - - if (ctx && ctx->current_framebuffer == fb) - ctx->st->notify_invalid_framebuffer(ctx->st, fb->stfb); + p_atomic_inc(&fb->stfb->stamp); } /** diff --git a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c index 424d8daccb3..c7273f26545 100644 --- a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c +++ b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c @@ -268,7 +268,7 @@ wglQueryPbufferARB(HPBUFFERARB hPbuffer, *piValue = fb->width; return TRUE; case WGL_PBUFFER_HEIGHT_ARB: - *piValue = fb->width; + *piValue = fb->height; return TRUE; case WGL_PBUFFER_LOST_ARB: /* We assume that no content is ever lost due to display mode change */ diff --git a/src/gallium/state_trackers/wgl/stw_st.c b/src/gallium/state_trackers/wgl/stw_st.c index 9174533fc06..28c93f4fb57 100644 --- a/src/gallium/state_trackers/wgl/stw_st.c +++ b/src/gallium/state_trackers/wgl/stw_st.c @@ -27,6 +27,7 @@ #include "util/u_memory.h" #include "util/u_inlines.h" +#include "util/u_atomic.h" #include "state_tracker/st_gl_api.h" /* for st_gl_api_create */ #include "stw_st.h" @@ -196,6 +197,7 @@ stw_st_create_framebuffer(struct stw_framebuffer *fb) stwfb->stvis = fb->pfi->stvis; stwfb->base.visual = &stwfb->stvis; + p_atomic_set(&stwfb->base.stamp, 1); stwfb->base.flush_front = stw_st_framebuffer_flush_front; stwfb->base.validate = stw_st_framebuffer_validate; diff --git a/src/gallium/state_trackers/xa/Makefile b/src/gallium/state_trackers/xa/Makefile new file mode 100644 index 00000000000..d95f9382630 --- /dev/null +++ b/src/gallium/state_trackers/xa/Makefile @@ -0,0 +1,67 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +##### MACROS ##### + +XA_MAJOR = 0 +XA_MINOR = 4 +XA_TINY = 0 +XA_CFLAGS = -g -fPIC -Wall + +XA_INCLUDES= -I$(TOP)/src/gallium/ \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/winsys \ + -I$(TOP)/src/gallium/drivers + +XA_LIB = xatracker +XA_LIB_NAME = lib$(XA_LIB).o +XA_LIB_DEPS = + +COMMON_GALLIUM_SOURCES= + +SOURCES = \ + xa_tracker.c \ + xa_context.c \ + xa_renderer.c \ + xa_tgsi.c \ + xa_yuv.c \ + xa_composite.c +OBJECTS = $(SOURCES:.c=.o) + +##### RULES ##### + +.c.o: + $(CC) -c $(XA_CFLAGS) $(XA_INCLUDES) $< + + +##### TARGETS ##### + +default: $(XA_LIB_NAME) + + +# Make the library +$(XA_LIB_NAME): depend $(OBJECTS) + $(CC) -r -nostdlib -o $(XA_LIB_NAME) $(OBJECTS) + +install: FORCE + +clean: + -rm -f *.o *~ + -rm -f *.lo + -rm -f *.la + -rm -f *.pc + -rm -rf .libs + -rm -f depend depend.bak + + +depend: $(SOURCES) + @ echo "running $(MKDEP)" + @ rm -f depend + @ touch depend + @ $(MKDEP) $(MKDEP_OPTIONS) -I$(TOP)/include $(XA_INCLUDES) $(SOURCES) \ + > /dev/null + +-include depend + +FORCE: diff --git a/src/gallium/state_trackers/xa/README b/src/gallium/state_trackers/xa/README new file mode 100644 index 00000000000..1f08861588c --- /dev/null +++ b/src/gallium/state_trackers/xa/README @@ -0,0 +1,72 @@ +/********************************************************** + * Copyright 2009-2011 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice 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: + * Zack Rusin <zackr-at-vmware-dot-com> + * Thomas Hellstrom <thellstrom-at-vmware-dot-com> + */ + +The XA state tracker is intended as a versioned interface to gallium for +xorg driver writers. Initially it's mostly based on Zack Rusin's +composite / video work for the Xorg state tracker. + +The motivation behind this state tracker is that the Xorg state tracker has +a number of interfaces to work with: + +1) The Xorg sdk (versioned) +2) Gallium3D (not versioned) +3) KMS modesetting (versioned) +4) Driver-private (hopefully versioned) + +Since Gallium3D is not versioned, the Xorg state tracker needs to be compiled +with Gallium, but it's really beneficial to be able to compile xorg drivers +standalone. + +Therefore the xa state tracker is intended to supply the following +functionality: + +1) Versioning. +2) Surface functionality (creation and copying for a basic dri2 implementation) +3) YUV blits for textured Xv. +4) Solid fills without ROP functionality. +5) Copies with format conversion and - reinterpretation but without ROP +6) Xrender- type compositing for general acceleration. + + +The first user will be the vmwgfx xorg driver. When there are more users, +we need to be able to load the appropriate gallium pipe driver, and we +should investigate sharing the loadig mechanism with the EGL state tracker. + +IMPORTANT: +Version compatibilities: +While this library remains OUTSIDE any mesa release branch, +and the major version number is still 0. Any minor bump should be viewed as +an incompatibility event, and any user of this library should test for that +and refuse to use the library if minor versions differ. +As soon as the library enters a mesa release branch, if not earlier, major +will be bumped to 1, and normal incompatibility rules (major bump) +will be followed. +It is allowed to add function interfaces while only bumping minor. Any +user that uses these function interfaces must therefore use lazy symbol +lookups and test minor for compatibility before using such a function. diff --git a/src/gallium/state_trackers/xa/xa-indent b/src/gallium/state_trackers/xa/xa-indent new file mode 100755 index 00000000000..1972e53226f --- /dev/null +++ b/src/gallium/state_trackers/xa/xa-indent @@ -0,0 +1,3 @@ +# +indent --linux-style -i4 -ip4 -bad -bap -psl $* + diff --git a/src/gallium/state_trackers/xa/xa_composite.c b/src/gallium/state_trackers/xa/xa_composite.c new file mode 100644 index 00000000000..5389af6f363 --- /dev/null +++ b/src/gallium/state_trackers/xa/xa_composite.c @@ -0,0 +1,499 @@ +/********************************************************** + * Copyright 2009-2011 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice 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: + * Zack Rusin <zackr-at-vmware-dot-com> + * Thomas Hellstrom <thellstrom-at-vmware-dot-com> + */ + +#include "xa_composite.h" +#include "xa_context.h" +#include "xa_priv.h" +#include "cso_cache/cso_context.h" +#include "util/u_sampler.h" +#include "util/u_inlines.h" + + +/*XXX also in Xrender.h but the including it here breaks compilition */ +#define XFixedToDouble(f) (((double) (f)) / 65536.) + +struct xa_composite_blend { + enum xa_composite_op op : 8; + + unsigned alpha_dst : 4; + unsigned alpha_src : 4; + + unsigned rgb_src : 8; /**< PIPE_BLENDFACTOR_x */ + unsigned rgb_dst : 8; /**< PIPE_BLENDFACTOR_x */ +}; + +#define XA_BLEND_OP_OVER 3 +static const struct xa_composite_blend xa_blends[] = { + { xa_op_clear, + 0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO}, + { xa_op_src, + 0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO}, + { xa_op_dst, + 0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ONE}, + { xa_op_over, + 0, 1, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_INV_SRC_ALPHA}, + { xa_op_over_reverse, + 1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ONE}, + { xa_op_in, + 1, 0, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_ZERO}, + { xa_op_in_reverse, + 0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_SRC_ALPHA}, + { xa_op_out, + 1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ZERO}, + { xa_op_out_reverse, + 0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_INV_SRC_ALPHA}, + { xa_op_atop, + 1, 1, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA}, + { xa_op_atop_reverse, + 1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_SRC_ALPHA}, + { xa_op_xor, + 1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA}, + { xa_op_add, + 0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE}, +}; + + +static boolean +blend_for_op(struct xa_composite_blend *blend, + enum xa_composite_op op, + struct xa_picture *src_pic, + struct xa_picture *mask_pic, + struct xa_picture *dst_pic) +{ + const int num_blends = + sizeof(xa_blends)/sizeof(struct xa_composite_blend); + int i; + boolean supported = FALSE; + + /* + * our default in case something goes wrong + */ + + *blend = xa_blends[XA_BLEND_OP_OVER]; + + for (i = 0; i < num_blends; ++i) { + if (xa_blends[i].op == op) { + *blend = xa_blends[i]; + supported = TRUE; + } + } + + + /* + * If there's no dst alpha channel, adjust the blend op so that we'll treat + * it as always 1. + */ + + if (dst_pic && + xa_format_a(dst_pic->pict_format) == 0 && + blend->alpha_dst) { + if (blend->rgb_src == PIPE_BLENDFACTOR_DST_ALPHA) + blend->rgb_src = PIPE_BLENDFACTOR_ONE; + else if (blend->rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA) + blend->rgb_src = PIPE_BLENDFACTOR_ZERO; + } + + /* + * If the source alpha is being used, then we should only be in a case where + * the source blend factor is 0, and the source blend value is the mask + * channels multiplied by the source picture's alpha. + */ + if (mask_pic && mask_pic->component_alpha && + xa_format_rgb(mask_pic->pict_format) && + blend->alpha_src) { + if (blend->rgb_dst == PIPE_BLENDFACTOR_SRC_ALPHA) { + blend->rgb_dst = PIPE_BLENDFACTOR_SRC_COLOR; + } else if (blend->rgb_dst == PIPE_BLENDFACTOR_INV_SRC_ALPHA) { + blend->rgb_dst = PIPE_BLENDFACTOR_INV_SRC_COLOR; + } + } + + return supported; +} + + +static INLINE int +xa_repeat_to_gallium(int mode) +{ + switch(mode) { + case xa_wrap_clamp_to_border: + return PIPE_TEX_WRAP_CLAMP_TO_BORDER; + case xa_wrap_repeat: + return PIPE_TEX_WRAP_REPEAT; + case xa_wrap_mirror_repeat: + return PIPE_TEX_WRAP_MIRROR_REPEAT; + case xa_wrap_clamp_to_edge: + return PIPE_TEX_WRAP_CLAMP_TO_EDGE; + default: + break; + } + return PIPE_TEX_WRAP_REPEAT; +} + +static INLINE boolean +xa_filter_to_gallium(int xrender_filter, int *out_filter) +{ + + switch (xrender_filter) { + case xa_filter_nearest: + *out_filter = PIPE_TEX_FILTER_NEAREST; + break; + case xa_filter_linear: + *out_filter = PIPE_TEX_FILTER_LINEAR; + break; + default: + *out_filter = PIPE_TEX_FILTER_NEAREST; + return FALSE; + } + return TRUE; +} + +static int +xa_is_filter_accelerated(struct xa_picture *pic) +{ + int filter; + if (pic && !xa_filter_to_gallium(pic->filter, &filter)) + return 0; + return 1; +} + +int +xa_composite_check_accelerated(const struct xa_composite *comp) +{ + struct xa_composite_blend blend; + struct xa_picture *src_pic = comp->src; + + if (!xa_is_filter_accelerated(src_pic) || + !xa_is_filter_accelerated(comp->mask)) { + return XA_ERR_INVAL; + } + + + if (src_pic->src_pict) { + if (src_pic->src_pict->type != xa_src_pict_solid_fill) + return XA_ERR_INVAL; + } + + if (blend_for_op(&blend, comp->op, comp->src, comp->mask, comp->dst)) { + struct xa_picture *mask = comp->mask; + if (mask && mask->component_alpha && + xa_format_rgb(mask->pict_format)) { + if (blend.alpha_src && blend.rgb_src != PIPE_BLENDFACTOR_ZERO) { + return XA_ERR_INVAL; + } + } + + return XA_ERR_NONE; + } + return XA_ERR_INVAL; +} + +static void +bind_composite_blend_state(struct xa_context *ctx, + const struct xa_composite *comp) +{ + struct xa_composite_blend blend_opt; + struct pipe_blend_state blend; + + blend_for_op(&blend_opt, comp->op, comp->src, comp->mask, comp->dst); + + memset(&blend, 0, sizeof(struct pipe_blend_state)); + blend.rt[0].blend_enable = 1; + blend.rt[0].colormask = PIPE_MASK_RGBA; + + blend.rt[0].rgb_src_factor = blend_opt.rgb_src; + blend.rt[0].alpha_src_factor = blend_opt.rgb_src; + blend.rt[0].rgb_dst_factor = blend_opt.rgb_dst; + blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst; + + cso_set_blend(ctx->cso, &blend); +} + +static unsigned int +picture_format_fixups(struct xa_picture *src_pic, + struct xa_picture *dst_pic, + int mask) +{ + boolean set_alpha = FALSE; + boolean swizzle = FALSE; + unsigned ret = 0; + struct xa_surface *src = src_pic->srf; + enum xa_formats src_hw_format, src_pic_format; + enum xa_surface_type src_hw_type, src_pic_type; + + if (!src) + return 0; + + src_hw_format = xa_surface_format(src); + src_pic_format = src_pic->pict_format; + + if (!src || src_hw_format == src_pic_format) { + if (src_pic_format == xa_format_a8) { + if (mask) + return FS_MASK_LUMINANCE; + else if (dst_pic->pict_format != xa_format_a8) { + + /* + * if both dst and src are luminance then + * we don't want to swizzle the alpha (X) of the + * source into W component of the dst because + * it will break our destination + */ + return FS_SRC_LUMINANCE; + } + } + return 0; + } + + src_hw_type = xa_format_type(src_hw_format); + src_pic_type = xa_format_type(src_pic_format); + + swizzle = ((src_hw_type == xa_type_argb && + src_pic_type == xa_type_abgr) || + ((src_hw_type == xa_type_abgr && + src_pic_type == xa_type_argb))); + + if (!swizzle && (src_hw_type != src_pic_type)) + return 0; + + set_alpha = (xa_format_type_is_color(src_pic_format) && + xa_format_a(src_pic_type) == 0); + + if (set_alpha) + ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA; + if (swizzle) + ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB; + + return ret; +} + +static void +bind_shaders(struct xa_context *ctx, const struct xa_composite *comp) +{ + unsigned vs_traits = 0, fs_traits = 0; + struct xa_shader shader; + struct xa_picture *src_pic = comp->src; + struct xa_picture *mask_pic = comp->mask; + struct xa_picture *dst_pic = comp->dst; + + ctx->has_solid_color = FALSE; + + if (src_pic) { + if (src_pic->wrap == xa_wrap_clamp_to_border && src_pic->has_transform) + fs_traits |= FS_SRC_REPEAT_NONE; + + if (src_pic->src_pict) { + if (src_pic->src_pict->type == xa_src_pict_solid_fill) { + fs_traits |= FS_SOLID_FILL; + vs_traits |= VS_SOLID_FILL; + xa_pixel_to_float4(src_pic->src_pict->solid_fill.color, + ctx->solid_color); + ctx->has_solid_color = TRUE; + } + } else { + fs_traits |= FS_COMPOSITE; + vs_traits |= VS_COMPOSITE; + } + + fs_traits |= picture_format_fixups(src_pic, dst_pic, 0); + } + + if (mask_pic) { + vs_traits |= VS_MASK; + fs_traits |= FS_MASK; + if (mask_pic->wrap == xa_wrap_clamp_to_border && + mask_pic->has_transform) + fs_traits |= FS_MASK_REPEAT_NONE; + + if (mask_pic->component_alpha) { + struct xa_composite_blend blend; + blend_for_op(&blend, comp->op, src_pic, mask_pic, NULL); + if (blend.alpha_src) { + fs_traits |= FS_CA_SRCALPHA; + } else + fs_traits |= FS_CA_FULL; + } + + fs_traits |= picture_format_fixups(mask_pic, dst_pic, 1); + } + + shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits); + cso_set_vertex_shader_handle(ctx->cso, shader.vs); + cso_set_fragment_shader_handle(ctx->cso, shader.fs); +} + +static void +bind_samplers(struct xa_context *ctx, + const struct xa_composite *comp) +{ + struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_state src_sampler, mask_sampler; + struct pipe_sampler_view view_templ; + struct pipe_sampler_view *src_view; + struct pipe_context *pipe = ctx->pipe; + struct xa_picture *src_pic = comp->src; + struct xa_picture *mask_pic = comp->mask; + + ctx->num_bound_samplers = 0; + + memset(&src_sampler, 0, sizeof(struct pipe_sampler_state)); + memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state)); + + if (src_pic) { + if (ctx->has_solid_color) { + samplers[0] = NULL; + pipe_sampler_view_reference(&ctx->bound_sampler_views[0], NULL); + } else { + unsigned src_wrap = xa_repeat_to_gallium(src_pic->wrap); + int filter; + + (void) xa_filter_to_gallium(src_pic->filter, &filter); + + src_sampler.wrap_s = src_wrap; + src_sampler.wrap_t = src_wrap; + src_sampler.min_img_filter = filter; + src_sampler.mag_img_filter = filter; + src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; + src_sampler.normalized_coords = 1; + samplers[0] = &src_sampler; + ctx->num_bound_samplers = 1; + u_sampler_view_default_template(&view_templ, + src_pic->srf->tex, + src_pic->srf->tex->format); + src_view = pipe->create_sampler_view(pipe, src_pic->srf->tex, + &view_templ); + pipe_sampler_view_reference(&ctx->bound_sampler_views[0], NULL); + ctx->bound_sampler_views[0] = src_view; + } + } + + if (mask_pic) { + unsigned mask_wrap = xa_repeat_to_gallium(mask_pic->wrap); + int filter; + + (void) xa_filter_to_gallium(mask_pic->filter, &filter); + + mask_sampler.wrap_s = mask_wrap; + mask_sampler.wrap_t = mask_wrap; + mask_sampler.min_img_filter = filter; + mask_sampler.mag_img_filter = filter; + src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; + mask_sampler.normalized_coords = 1; + samplers[1] = &mask_sampler; + ctx->num_bound_samplers = 2; + u_sampler_view_default_template(&view_templ, + mask_pic->srf->tex, + mask_pic->srf->tex->format); + src_view = pipe->create_sampler_view(pipe, mask_pic->srf->tex, + &view_templ); + pipe_sampler_view_reference(&ctx->bound_sampler_views[1], NULL); + ctx->bound_sampler_views[1] = src_view; + } + + cso_set_samplers(ctx->cso, ctx->num_bound_samplers, + (const struct pipe_sampler_state **)samplers); + cso_set_fragment_sampler_views(ctx->cso, ctx->num_bound_samplers, + ctx->bound_sampler_views); +} + +int +xa_composite_prepare(struct xa_context *ctx, + const struct xa_composite *comp) +{ + struct xa_surface *dst_srf = comp->dst->srf; + int ret; + + ret = xa_surface_psurf_create(ctx, dst_srf); + if (ret != XA_ERR_NONE) + return ret; + + renderer_bind_destination(ctx, dst_srf->srf, + dst_srf->srf->width, + dst_srf->srf->height); + + bind_composite_blend_state(ctx, comp); + bind_shaders(ctx, comp); + bind_samplers(ctx, comp); + + if (ctx->num_bound_samplers == 0 ) { /* solid fill */ + renderer_begin_solid(ctx); + } else { + renderer_begin_textures(ctx); + ctx->comp = comp; + } + + xa_surface_psurf_destroy(dst_srf); + return XA_ERR_NONE; +} + +void xa_composite_rect(struct xa_context *ctx, + int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + if (ctx->num_bound_samplers == 0 ) { /* solid fill */ + renderer_solid(ctx, dstX, dstY, dstX + width, dstY + height, + ctx->solid_color); + } else { + const struct xa_composite *comp = ctx->comp; + int pos[6] = {srcX, srcY, maskX, maskY, dstX, dstY}; + const float *src_matrix = NULL; + const float *mask_matrix = NULL; + + if (comp->src->has_transform) + src_matrix = comp->src->transform; + if (comp->mask && comp->mask->has_transform) + mask_matrix = comp->mask->transform; + + renderer_texture(ctx, pos, width, height, + src_matrix, mask_matrix); + } +} + +void +xa_composite_done(struct xa_context *ctx) +{ + renderer_draw_flush(ctx); + ctx->pipe->flush(ctx->pipe, &ctx->last_fence); + + ctx->comp = NULL; + ctx->has_solid_color = FALSE; + ctx->num_bound_samplers = 0; +} + +static const struct xa_composite_allocation a = { + .xa_composite_size = sizeof(struct xa_composite), + .xa_picture_size = sizeof(struct xa_picture), + .xa_source_pict_size = sizeof(union xa_source_pict), +}; + +const struct xa_composite_allocation * +xa_composite_allocation(void) +{ + return &a; +} diff --git a/src/gallium/state_trackers/xa/xa_composite.h b/src/gallium/state_trackers/xa/xa_composite.h new file mode 100644 index 00000000000..d16ef89ebd8 --- /dev/null +++ b/src/gallium/state_trackers/xa/xa_composite.h @@ -0,0 +1,140 @@ +/********************************************************** + * Copyright 2009-2011 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice 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: + * Zack Rusin <zackr-at-vmware-dot-com> + * Thomas Hellstrom <thellstrom-at-vmware-dot-com> + */ + +#ifndef _XA_COMPOSITE_H_ +#define _XA_COMPOSITE_H_ + +#include "xa_tracker.h" +#include "xa_context.h" + +/* + * Supported composite ops. + */ +enum xa_composite_op { + xa_op_clear, + xa_op_src, + xa_op_dst, + xa_op_over, + xa_op_over_reverse, + xa_op_in, + xa_op_in_reverse, + xa_op_out, + xa_op_out_reverse, + xa_op_atop, + xa_op_atop_reverse, + xa_op_xor, + xa_op_add +}; + +/* + * Supported filters. + */ +enum xa_composite_filter { + xa_filter_nearest, + xa_filter_linear +}; + +/* + * Supported clamp methods. + */ +enum xa_composite_wrap { + xa_wrap_clamp_to_border, + xa_wrap_repeat, + xa_wrap_mirror_repeat, + xa_wrap_clamp_to_edge +}; + +/* + * Src picture types. + */ +enum xa_composite_src_pict_type { + xa_src_pict_solid_fill +}; + +struct xa_pict_solid_fill { + enum xa_composite_src_pict_type type; + unsigned int class; + uint32_t color; +}; + +union xa_source_pict { + unsigned int type; + struct xa_pict_solid_fill solid_fill; +}; + +struct xa_picture { + enum xa_formats pict_format; + struct xa_surface *srf; + struct xa_surface *alpha_map; + float transform[9]; + int has_transform; + int component_alpha; + enum xa_composite_wrap wrap; + enum xa_composite_filter filter; + union xa_source_pict *src_pict; +}; + +struct xa_composite { + struct xa_picture *src, *mask, *dst; + int op; + int no_solid; +}; + +struct xa_composite_allocation { + unsigned int xa_composite_size; + unsigned int xa_picture_size; + unsigned int xa_source_pict_size; +}; + +/* + * Get allocation sizes for minor bump compatibility. + */ + +extern const struct xa_composite_allocation * +xa_composite_allocation(void); + +/* + * This function checks most things except the format of the hardware + * surfaces, since they are generally not available at the time this + * function is called. Returns usual XA error codes. + */ +extern int +xa_composite_check_accelerated(const struct xa_composite *comp); + +extern int +xa_composite_prepare(struct xa_context *ctx, const struct xa_composite *comp); + +extern void +xa_composite_rect(struct xa_context *ctx, + int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height); +extern void +xa_composite_done(struct xa_context *ctx); + +#endif diff --git a/src/gallium/state_trackers/xa/xa_context.c b/src/gallium/state_trackers/xa/xa_context.c new file mode 100644 index 00000000000..3cc25ed2071 --- /dev/null +++ b/src/gallium/state_trackers/xa/xa_context.c @@ -0,0 +1,386 @@ +/********************************************************** + * Copyright 2009-2011 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice 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: + * Zack Rusin <zackr-at-vmware-dot-com> + * Thomas Hellstrom <thellstrom-at-vmware-dot-com> + */ +#include "xa_context.h" +#include "xa_priv.h" +#include "cso_cache/cso_context.h" +#include "util/u_inlines.h" +#include "util/u_rect.h" +#include "util/u_surface.h" +#include "pipe/p_context.h" + + +struct xa_context * +xa_context_default(struct xa_tracker *xa) +{ + return xa->default_ctx; +} + +struct xa_context * +xa_context_create(struct xa_tracker *xa) +{ + struct xa_context *ctx = calloc(1, sizeof(*ctx)); + + ctx->xa = xa; + ctx->pipe = xa->screen->context_create(xa->screen, NULL); + ctx->cso = cso_create_context(ctx->pipe); + ctx->shaders = xa_shaders_create(ctx); + renderer_init_state(ctx); + + return ctx; +} + +void +xa_context_destroy(struct xa_context *r) +{ + struct pipe_resource **vsbuf = &r->vs_const_buffer; + struct pipe_resource **fsbuf = &r->fs_const_buffer; + + if (*vsbuf) + pipe_resource_reference(vsbuf, NULL); + + if (*fsbuf) + pipe_resource_reference(fsbuf, NULL); + + if (r->shaders) { + xa_shaders_destroy(r->shaders); + r->shaders = NULL; + } + + if (r->cso) { + cso_release_all(r->cso); + cso_destroy_context(r->cso); + r->cso = NULL; + } +} + +int +xa_surface_dma(struct xa_context *ctx, + struct xa_surface *srf, + void *data, + unsigned int pitch, + int to_surface, struct xa_box *boxes, unsigned int num_boxes) +{ + struct pipe_transfer *transfer; + void *map; + int w, h, i; + enum pipe_transfer_usage transfer_direction; + struct pipe_context *pipe = ctx->pipe; + + transfer_direction = (to_surface ? PIPE_TRANSFER_WRITE : + PIPE_TRANSFER_READ); + + for (i = 0; i < num_boxes; ++i, ++boxes) { + w = boxes->x2 - boxes->x1; + h = boxes->y2 - boxes->y1; + + transfer = pipe_get_transfer(pipe, srf->tex, 0, 0, + transfer_direction, boxes->x1, boxes->y1, + w, h); + if (!transfer) + return -XA_ERR_NORES; + + map = pipe_transfer_map(ctx->pipe, transfer); + if (!map) + goto out_no_map; + + if (to_surface) { + util_copy_rect(map, srf->tex->format, transfer->stride, + 0, 0, w, h, data, pitch, boxes->x1, boxes->y1); + } else { + util_copy_rect(data, srf->tex->format, pitch, + boxes->x1, boxes->y1, w, h, map, transfer->stride, 0, + 0); + } + pipe->transfer_unmap(pipe, transfer); + pipe->transfer_destroy(pipe, transfer); + if (to_surface) + pipe->flush(pipe, &ctx->last_fence); + } + return XA_ERR_NONE; + out_no_map: + pipe->transfer_destroy(pipe, transfer); + return -XA_ERR_NORES; +} + +void * +xa_surface_map(struct xa_context *ctx, + struct xa_surface *srf, unsigned int usage) +{ + void *map; + unsigned int transfer_direction = 0; + struct pipe_context *pipe = ctx->pipe; + + if (srf->transfer) + return NULL; + + if (usage & XA_MAP_READ) + transfer_direction = PIPE_TRANSFER_READ; + if (usage & XA_MAP_WRITE) + transfer_direction = PIPE_TRANSFER_WRITE; + + if (!transfer_direction) + return NULL; + + srf->transfer = pipe_get_transfer(pipe, srf->tex, 0, 0, + transfer_direction, 0, 0, + srf->tex->width0, srf->tex->height0); + if (!srf->transfer) + return NULL; + + map = pipe_transfer_map(pipe, srf->transfer); + if (!map) + pipe->transfer_destroy(pipe, srf->transfer); + + srf->mapping_pipe = pipe; + return map; +} + +void +xa_surface_unmap(struct xa_surface *srf) +{ + if (srf->transfer) { + struct pipe_context *pipe = srf->mapping_pipe; + + pipe->transfer_unmap(pipe, srf->transfer); + pipe->transfer_destroy(pipe, srf->transfer); + srf->transfer = NULL; + } +} + +int +xa_surface_psurf_create(struct xa_context *ctx, struct xa_surface *dst) +{ + struct pipe_screen *screen = ctx->pipe->screen; + struct pipe_surface srf_templ; + + if (dst->srf) + return -XA_ERR_INVAL; + + if (!screen->is_format_supported(screen, dst->tex->format, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_RENDER_TARGET)) + return -XA_ERR_INVAL; + + u_surface_default_template(&srf_templ, dst->tex, + PIPE_BIND_RENDER_TARGET); + dst->srf = ctx->pipe->create_surface(ctx->pipe, dst->tex, &srf_templ); + if (!dst->srf) + return -XA_ERR_NORES; + + return XA_ERR_NONE; +} + +void +xa_surface_psurf_destroy(struct xa_surface *dst) +{ + pipe_surface_reference(&dst->srf, NULL); +} + +int +xa_copy_prepare(struct xa_context *ctx, + struct xa_surface *dst, struct xa_surface *src) +{ + if (src == dst || dst->srf != NULL) + return -XA_ERR_INVAL; + + if (src->tex->format != dst->tex->format) { + int ret = xa_surface_psurf_create(ctx, dst); + if (ret != XA_ERR_NONE) + return ret; + renderer_copy_prepare(ctx, dst->srf, src->tex); + ctx->simple_copy = 0; + } else + ctx->simple_copy = 1; + + ctx->src = src; + ctx->dst = dst; + + return 0; +} + +void +xa_copy(struct xa_context *ctx, + int dx, int dy, int sx, int sy, int width, int height) +{ + struct pipe_box src_box; + + if (ctx->simple_copy) { + u_box_2d(sx, sy, width, height, &src_box); + ctx->pipe->resource_copy_region(ctx->pipe, + ctx->dst->tex, 0, dx, dy, 0, + ctx->src->tex, + 0, &src_box); + } else + renderer_copy(ctx, dx, dy, sx, sy, width, height, + (float) width, (float) height); +} + +void +xa_copy_done(struct xa_context *ctx) +{ + if (!ctx->simple_copy) { + renderer_draw_flush(ctx); + ctx->pipe->flush(ctx->pipe, &ctx->last_fence); + xa_surface_psurf_destroy(ctx->dst); + } else + ctx->pipe->flush(ctx->pipe, &ctx->last_fence); +} + +static void +bind_solid_blend_state(struct xa_context *ctx) +{ + struct pipe_blend_state blend; + + memset(&blend, 0, sizeof(struct pipe_blend_state)); + blend.rt[0].blend_enable = 0; + blend.rt[0].colormask = PIPE_MASK_RGBA; + + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + + cso_set_blend(ctx->cso, &blend); +} + +int +xa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst, + uint32_t fg) +{ + unsigned vs_traits, fs_traits; + struct xa_shader shader; + int width, height; + int ret; + + xa_pixel_to_float4(fg, ctx->solid_color); + ctx->has_solid_color = 1; + + ret = xa_surface_psurf_create(ctx, dst); + if (ret != XA_ERR_NONE) + return ret; + + ctx->dst = dst; + width = dst->srf->width; + height = dst->srf->height; + +#if 0 + debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n", + (fg >> 24) & 0xff, (fg >> 16) & 0xff, + (fg >> 8) & 0xff, (fg >> 0) & 0xff, + exa->solid_color[0], exa->solid_color[1], + exa->solid_color[2], exa->solid_color[3]); +#endif + + vs_traits = VS_SOLID_FILL; + fs_traits = FS_SOLID_FILL; + + renderer_bind_destination(ctx, dst->srf, width, height); + bind_solid_blend_state(ctx); + cso_set_samplers(ctx->cso, 0, NULL); + cso_set_fragment_sampler_views(ctx->cso, 0, NULL); + + shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits); + cso_set_vertex_shader_handle(ctx->cso, shader.vs); + cso_set_fragment_shader_handle(ctx->cso, shader.fs); + + renderer_begin_solid(ctx); + + xa_surface_psurf_destroy(dst); + return XA_ERR_NONE; +} + +void +xa_solid(struct xa_context *ctx, int x, int y, int width, int height) +{ + renderer_solid(ctx, x, y, x + width, y + height, ctx->solid_color); +} + +void +xa_solid_done(struct xa_context *ctx) +{ + renderer_draw_flush(ctx); + ctx->pipe->flush(ctx->pipe, &ctx->last_fence); + + ctx->comp = NULL; + ctx->has_solid_color = FALSE; + ctx->num_bound_samplers = 0; +} + +struct xa_fence * +xa_fence_get(struct xa_context *ctx) +{ + struct xa_fence *fence = malloc(sizeof(*fence)); + struct pipe_screen *screen = ctx->xa->screen; + + if (!fence) + return NULL; + + fence->xa = ctx->xa; + + if (ctx->last_fence == NULL) + fence->pipe_fence = NULL; + else + screen->fence_reference(screen, &fence->pipe_fence, ctx->last_fence); + + return fence; +} + +int +xa_fence_wait(struct xa_fence *fence, uint64_t timeout) +{ + if (!fence) + return XA_ERR_NONE; + + if (fence->pipe_fence) { + struct pipe_screen *screen = fence->xa->screen; + boolean timed_out; + + timed_out = !screen->fence_finish(screen, fence->pipe_fence, timeout); + if (timed_out) + return -XA_ERR_BUSY; + + screen->fence_reference(screen, &fence->pipe_fence, NULL); + } + return XA_ERR_NONE; +} + +void +xa_fence_destroy(struct xa_fence *fence) +{ + if (!fence) + return; + + if (fence->pipe_fence) { + struct pipe_screen *screen = fence->xa->screen; + + screen->fence_reference(screen, &fence->pipe_fence, NULL); + } + + free(fence); +} diff --git a/src/gallium/state_trackers/xa/xa_context.h b/src/gallium/state_trackers/xa/xa_context.h new file mode 100644 index 00000000000..ea2b923a5a1 --- /dev/null +++ b/src/gallium/state_trackers/xa/xa_context.h @@ -0,0 +1,86 @@ +/********************************************************** + * Copyright 2009-2011 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice 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: + * Zack Rusin <zackr-at-vmware-dot-com> + * Thomas Hellstrom <thellstrom-at-vmware-dot-com> + */ + +#ifndef _XA_CONTEXT_H_ +#define _XA_CONTEXT_H_ +#include "xa_tracker.h" +#include <stdint.h> + +struct xa_context; + +extern struct xa_context *xa_context_default(struct xa_tracker *xa); + +extern struct xa_context *xa_context_create(struct xa_tracker *xa); + +extern void xa_context_destroy(struct xa_context *r); + +extern int xa_yuv_planar_blit(struct xa_context *r, + int src_x, + int src_y, + int src_w, + int src_h, + int dst_x, + int dst_y, + int dst_w, + int dst_h, + struct xa_box *box, + unsigned int num_boxes, + const float conversion_matrix[], + struct xa_surface *dst, struct xa_surface *yuv[]); + +extern int xa_copy_prepare(struct xa_context *ctx, + struct xa_surface *dst, struct xa_surface *src); + +extern void xa_copy(struct xa_context *ctx, + int dx, int dy, int sx, int sy, int width, int height); + +extern void xa_copy_done(struct xa_context *ctx); + +extern int xa_surface_dma(struct xa_context *ctx, + struct xa_surface *srf, + void *data, + unsigned int byte_pitch, + int to_surface, struct xa_box *boxes, + unsigned int num_boxes); + +extern int +xa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst, + uint32_t fg); +extern void +xa_solid(struct xa_context *ctx, int x, int y, int width, int height); + +extern void +xa_solid_done(struct xa_context *ctx); + +extern struct xa_fence *xa_fence_get(struct xa_context *ctx); + +extern int xa_fence_wait(struct xa_fence *fence, uint64_t timeout); + +extern void xa_fence_destroy(struct xa_fence *fence); +#endif diff --git a/src/gallium/state_trackers/xa/xa_priv.h b/src/gallium/state_trackers/xa/xa_priv.h new file mode 100644 index 00000000000..94627e1e9d0 --- /dev/null +++ b/src/gallium/state_trackers/xa/xa_priv.h @@ -0,0 +1,241 @@ +/********************************************************** + * Copyright 2009-2011 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice 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: + * Zack Rusin <zackr-at-vmware-dot-com> + * Thomas Hellstrom <thellstrom-at-vmware-dot-com> + */ + +#ifndef _XA_PRIV_H_ +#define _XA_PRIV_H_ + +#include "xa_tracker.h" +#include "xa_context.h" +#include "xa_composite.h" + +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" + +#define XA_VB_SIZE (100 * 4 * 3 * 4) +#define XA_LAST_SURFACE_TYPE (xa_type_yuv_component + 1) +#define XA_MAX_SAMPLERS 3 + +struct xa_fence { + struct pipe_fence_handle *pipe_fence; + struct xa_tracker *xa; +}; + +struct xa_format_descriptor { + enum pipe_format format; + enum xa_formats xa_format; +}; + +struct xa_surface { + struct pipe_resource template; + struct xa_tracker *xa; + struct pipe_resource *tex; + struct pipe_surface *srf; + struct pipe_sampler_view *view; + unsigned int flags; + struct xa_format_descriptor fdesc; + struct pipe_transfer *transfer; + struct pipe_context *mapping_pipe; +}; + +struct xa_tracker { + enum xa_formats *supported_formats; + unsigned int format_map[XA_LAST_SURFACE_TYPE][2]; + int d_depth_bits_last; + int ds_depth_bits_last; + struct pipe_screen *screen; + struct xa_context *default_ctx; +}; + +struct xa_context { + struct xa_tracker *xa; + struct pipe_context *pipe; + + struct cso_context *cso; + struct xa_shaders *shaders; + + struct pipe_resource *vs_const_buffer; + struct pipe_resource *fs_const_buffer; + + float buffer[XA_VB_SIZE]; + unsigned int buffer_size; + struct pipe_vertex_element velems[3]; + + /* number of attributes per vertex for the current + * draw operation */ + unsigned int attrs_per_vertex; + + unsigned int fb_width; + unsigned int fb_height; + + struct pipe_fence_handle *last_fence; + struct xa_surface *src; + struct xa_surface *dst; + int simple_copy; + + int has_solid_color; + float solid_color[4]; + + unsigned int num_bound_samplers; + struct pipe_sampler_view *bound_sampler_views[XA_MAX_SAMPLERS]; + const struct xa_composite *comp; +}; + +enum xa_vs_traits { + VS_COMPOSITE = 1 << 0, + VS_MASK = 1 << 1, + VS_SOLID_FILL = 1 << 2, + VS_LINGRAD_FILL = 1 << 3, + VS_RADGRAD_FILL = 1 << 4, + VS_YUV = 1 << 5, + + VS_FILL = (VS_SOLID_FILL | VS_LINGRAD_FILL | VS_RADGRAD_FILL) +}; + +enum xa_fs_traits { + FS_COMPOSITE = 1 << 0, + FS_MASK = 1 << 1, + FS_SOLID_FILL = 1 << 2, + FS_LINGRAD_FILL = 1 << 3, + FS_RADGRAD_FILL = 1 << 4, + FS_CA_FULL = 1 << 5, /* src.rgba * mask.rgba */ + FS_CA_SRCALPHA = 1 << 6, /* src.aaaa * mask.rgba */ + FS_YUV = 1 << 7, + FS_SRC_REPEAT_NONE = 1 << 8, + FS_MASK_REPEAT_NONE = 1 << 9, + FS_SRC_SWIZZLE_RGB = 1 << 10, + FS_MASK_SWIZZLE_RGB = 1 << 11, + FS_SRC_SET_ALPHA = 1 << 12, + FS_MASK_SET_ALPHA = 1 << 13, + FS_SRC_LUMINANCE = 1 << 14, + FS_MASK_LUMINANCE = 1 << 15, + + FS_FILL = (FS_SOLID_FILL | FS_LINGRAD_FILL | FS_RADGRAD_FILL), + FS_COMPONENT_ALPHA = (FS_CA_FULL | FS_CA_SRCALPHA) +}; + +struct xa_shader { + void *fs; + void *vs; +}; + +struct xa_shaders; + +/* + * Inline utilities + */ + +static INLINE int +xa_min(int a, int b) +{ + return ((a <= b) ? a : b); +} + +static INLINE void +xa_pixel_to_float4(uint32_t pixel, float *color) +{ + uint32_t r, g, b, a; + + a = (pixel >> 24) & 0xff; + r = (pixel >> 16) & 0xff; + g = (pixel >> 8) & 0xff; + b = (pixel >> 0) & 0xff; + color[0] = ((float)r) / 255.; + color[1] = ((float)g) / 255.; + color[2] = ((float)b) / 255.; + color[3] = ((float)a) / 255.; +} + + +/* + * xa_tgsi.c + */ + +extern struct xa_shaders *xa_shaders_create(struct xa_context *); + +void xa_shaders_destroy(struct xa_shaders *shaders); + +struct xa_shader xa_shaders_get(struct xa_shaders *shaders, + unsigned vs_traits, unsigned fs_traits); + +/* + * xa_context.c + */ +extern int +xa_surface_psurf_create(struct xa_context *ctx, struct xa_surface *dst); + +extern void +xa_surface_psurf_destroy(struct xa_surface *dst); + +/* + * xa_renderer.c + */ +void renderer_set_constants(struct xa_context *r, + int shader_type, const float *params, + int param_bytes); + +void renderer_draw_yuv(struct xa_context *r, + float src_x, + float src_y, + float src_w, + float src_h, + int dst_x, + int dst_y, int dst_w, int dst_h, + struct xa_surface *srf[]); + +void renderer_bind_destination(struct xa_context *r, + struct pipe_surface *surface, int width, + int height); + +void renderer_init_state(struct xa_context *r); +void renderer_copy_prepare(struct xa_context *r, + struct pipe_surface *dst_surface, + struct pipe_resource *src_texture); +void renderer_copy(struct xa_context *r, int dx, + int dy, + int sx, + int sy, + int width, int height, float src_width, float src_height); + +void renderer_draw_flush(struct xa_context *r); + +void renderer_begin_solid(struct xa_context *r); +void renderer_solid(struct xa_context *r, + int x0, int y0, int x1, int y1, float *color); +void +renderer_begin_textures(struct xa_context *r); + +void +renderer_texture(struct xa_context *r, + int *pos, + int width, int height, + const float *src_matrix, + const float *mask_matrix); + +#endif diff --git a/src/gallium/state_trackers/xa/xa_renderer.c b/src/gallium/state_trackers/xa/xa_renderer.c new file mode 100644 index 00000000000..559b2699da6 --- /dev/null +++ b/src/gallium/state_trackers/xa/xa_renderer.c @@ -0,0 +1,626 @@ +/********************************************************** + * Copyright 2009-2011 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice 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: + * Zack Rusin <zackr-at-vmware-dot-com> + */ + +#include "xa_context.h" +#include "xa_priv.h" +#include <math.h> +#include "cso_cache/cso_context.h" +#include "util/u_inlines.h" +#include "util/u_sampler.h" +#include "util/u_draw_quad.h" + +#define floatsEqual(x, y) (fabs(x - y) <= 0.00001f * MIN2(fabs(x), fabs(y))) +#define floatIsZero(x) (floatsEqual((x) + 1, 1)) + +#define NUM_COMPONENTS 4 + +void + + +renderer_set_constants(struct xa_context *r, + int shader_type, const float *params, int param_bytes); + +static INLINE boolean +is_affine(float *matrix) +{ + return floatIsZero(matrix[2]) && floatIsZero(matrix[5]) + && floatsEqual(matrix[8], 1); +} + +static INLINE void +map_point(float *mat, float x, float y, float *out_x, float *out_y) +{ + if (!mat) { + *out_x = x; + *out_y = y; + return; + } + + *out_x = mat[0] * x + mat[3] * y + mat[6]; + *out_y = mat[1] * x + mat[4] * y + mat[7]; + if (!is_affine(mat)) { + float w = 1 / (mat[2] * x + mat[5] * y + mat[8]); + + *out_x *= w; + *out_y *= w; + } +} + +static INLINE struct pipe_resource * +renderer_buffer_create(struct xa_context *r) +{ + struct pipe_resource *buf = pipe_user_buffer_create(r->pipe->screen, + r->buffer, + sizeof(float) * + r->buffer_size, + PIPE_BIND_VERTEX_BUFFER); + + r->buffer_size = 0; + + return buf; +} + +static INLINE void +renderer_draw(struct xa_context *r) +{ + struct pipe_context *pipe = r->pipe; + struct pipe_resource *buf = 0; + int num_verts = r->buffer_size / (r->attrs_per_vertex * NUM_COMPONENTS); + + if (!r->buffer_size) + return; + + buf = renderer_buffer_create(r); + + if (buf) { + cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems); + + util_draw_vertex_buffer(pipe, r->cso, buf, 0, PIPE_PRIM_QUADS, num_verts, /* verts */ + r->attrs_per_vertex); /* attribs/vert */ + + pipe_resource_reference(&buf, NULL); + } +} + +static INLINE void +renderer_draw_conditional(struct xa_context *r, int next_batch) +{ + if (r->buffer_size + next_batch >= XA_VB_SIZE || + (next_batch == 0 && r->buffer_size)) { + renderer_draw(r); + } +} + +void +renderer_init_state(struct xa_context *r) +{ + struct pipe_depth_stencil_alpha_state dsa; + struct pipe_rasterizer_state raster; + unsigned i; + + /* set common initial clip state */ + memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); + cso_set_depth_stencil_alpha(r->cso, &dsa); + + /* XXX: move to renderer_init_state? */ + memset(&raster, 0, sizeof(struct pipe_rasterizer_state)); + raster.gl_rasterization_rules = 1; + cso_set_rasterizer(r->cso, &raster); + + /* vertex elements state */ + memset(&r->velems[0], 0, sizeof(r->velems[0]) * 3); + for (i = 0; i < 3; i++) { + r->velems[i].src_offset = i * 4 * sizeof(float); + r->velems[i].instance_divisor = 0; + r->velems[i].vertex_buffer_index = 0; + r->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + } +} + +static INLINE void +add_vertex_color(struct xa_context *r, float x, float y, float color[4]) +{ + float *vertex = r->buffer + r->buffer_size; + + vertex[0] = x; + vertex[1] = y; + vertex[2] = 0.f; /*z */ + vertex[3] = 1.f; /*w */ + + vertex[4] = color[0]; /*r */ + vertex[5] = color[1]; /*g */ + vertex[6] = color[2]; /*b */ + vertex[7] = color[3]; /*a */ + + r->buffer_size += 8; +} + +static INLINE void +add_vertex_1tex(struct xa_context *r, float x, float y, float s, float t) +{ + float *vertex = r->buffer + r->buffer_size; + + vertex[0] = x; + vertex[1] = y; + vertex[2] = 0.f; /*z */ + vertex[3] = 1.f; /*w */ + + vertex[4] = s; /*s */ + vertex[5] = t; /*t */ + vertex[6] = 0.f; /*r */ + vertex[7] = 1.f; /*q */ + + r->buffer_size += 8; +} + +static INLINE void +add_vertex_2tex(struct xa_context *r, + float x, float y, float s0, float t0, float s1, float t1) +{ + float *vertex = r->buffer + r->buffer_size; + + vertex[0] = x; + vertex[1] = y; + vertex[2] = 0.f; /*z */ + vertex[3] = 1.f; /*w */ + + vertex[4] = s0; /*s */ + vertex[5] = t0; /*t */ + vertex[6] = 0.f; /*r */ + vertex[7] = 1.f; /*q */ + + vertex[8] = s1; /*s */ + vertex[9] = t1; /*t */ + vertex[10] = 0.f; /*r */ + vertex[11] = 1.f; /*q */ + + r->buffer_size += 12; +} + +static void +add_vertex_data1(struct xa_context *r, + float srcX, float srcY, float dstX, float dstY, + float width, float height, + struct pipe_resource *src, const float *src_matrix) +{ + float s0, t0, s1, t1, s2, t2, s3, t3; + float pt0[2], pt1[2], pt2[2], pt3[2]; + + pt0[0] = srcX; + pt0[1] = srcY; + pt1[0] = (srcX + width); + pt1[1] = srcY; + pt2[0] = (srcX + width); + pt2[1] = (srcY + height); + pt3[0] = srcX; + pt3[1] = (srcY + height); + + if (src_matrix) { + map_point((float *)src_matrix, pt0[0], pt0[1], &pt0[0], &pt0[1]); + map_point((float *)src_matrix, pt1[0], pt1[1], &pt1[0], &pt1[1]); + map_point((float *)src_matrix, pt2[0], pt2[1], &pt2[0], &pt2[1]); + map_point((float *)src_matrix, pt3[0], pt3[1], &pt3[0], &pt3[1]); + } + + s0 = pt0[0] / src->width0; + s1 = pt1[0] / src->width0; + s2 = pt2[0] / src->width0; + s3 = pt3[0] / src->width0; + t0 = pt0[1] / src->height0; + t1 = pt1[1] / src->height0; + t2 = pt2[1] / src->height0; + t3 = pt3[1] / src->height0; + + /* 1st vertex */ + add_vertex_1tex(r, dstX, dstY, s0, t0); + /* 2nd vertex */ + add_vertex_1tex(r, dstX + width, dstY, s1, t1); + /* 3rd vertex */ + add_vertex_1tex(r, dstX + width, dstY + height, s2, t2); + /* 4th vertex */ + add_vertex_1tex(r, dstX, dstY + height, s3, t3); +} + +static void +add_vertex_data2(struct xa_context *r, + float srcX, float srcY, float maskX, float maskY, + float dstX, float dstY, float width, float height, + struct pipe_resource *src, + struct pipe_resource *mask, + const float *src_matrix, const float *mask_matrix) +{ + float src_s0, src_t0, src_s1, src_t1; + float mask_s0, mask_t0, mask_s1, mask_t1; + float spt0[2], spt1[2]; + float mpt0[2], mpt1[2]; + + spt0[0] = srcX; + spt0[1] = srcY; + spt1[0] = srcX + width; + spt1[1] = srcY + height; + + mpt0[0] = maskX; + mpt0[1] = maskY; + mpt1[0] = maskX + width; + mpt1[1] = maskY + height; + + if (src_matrix) { + map_point((float *)src_matrix, spt0[0], spt0[1], &spt0[0], &spt0[1]); + map_point((float *)src_matrix, spt1[0], spt1[1], &spt1[0], &spt1[1]); + } + + if (mask_matrix) { + map_point((float *)mask_matrix, mpt0[0], mpt0[1], &mpt0[0], &mpt0[1]); + map_point((float *)mask_matrix, mpt1[0], mpt1[1], &mpt1[0], &mpt1[1]); + } + + src_s0 = spt0[0] / src->width0; + src_t0 = spt0[1] / src->height0; + src_s1 = spt1[0] / src->width0; + src_t1 = spt1[1] / src->height0; + + mask_s0 = mpt0[0] / mask->width0; + mask_t0 = mpt0[1] / mask->height0; + mask_s1 = mpt1[0] / mask->width0; + mask_t1 = mpt1[1] / mask->height0; + + /* 1st vertex */ + add_vertex_2tex(r, dstX, dstY, + src_s0, src_t0, mask_s0, mask_t0); + /* 2nd vertex */ + add_vertex_2tex(r, dstX + width, dstY, + src_s1, src_t0, mask_s1, mask_t0); + /* 3rd vertex */ + add_vertex_2tex(r, dstX + width, dstY + height, + src_s1, src_t1, mask_s1, mask_t1); + /* 4th vertex */ + add_vertex_2tex(r, dstX, dstY + height, + src_s0, src_t1, mask_s0, mask_t1); +} + +static struct pipe_resource * +setup_vertex_data_yuv(struct xa_context *r, + float srcX, + float srcY, + float srcW, + float srcH, + float dstX, + float dstY, + float dstW, float dstH, struct xa_surface *srf[]) +{ + float s0, t0, s1, t1; + float spt0[2], spt1[2]; + struct pipe_resource *tex; + + spt0[0] = srcX; + spt0[1] = srcY; + spt1[0] = srcX + srcW; + spt1[1] = srcY + srcH; + + tex = srf[0]->tex; + s0 = spt0[0] / tex->width0; + t0 = spt0[1] / tex->height0; + s1 = spt1[0] / tex->width0; + t1 = spt1[1] / tex->height0; + + /* 1st vertex */ + add_vertex_1tex(r, dstX, dstY, s0, t0); + /* 2nd vertex */ + add_vertex_1tex(r, dstX + dstW, dstY, s1, t0); + /* 3rd vertex */ + add_vertex_1tex(r, dstX + dstW, dstY + dstH, s1, t1); + /* 4th vertex */ + add_vertex_1tex(r, dstX, dstY + dstH, s0, t1); + + return renderer_buffer_create(r); +} + +/* Set up framebuffer, viewport and vertex shader constant buffer + * state for a particular destinaton surface. In all our rendering, + * these concepts are linked. + */ +void +renderer_bind_destination(struct xa_context *r, + struct pipe_surface *surface, int width, int height) +{ + + struct pipe_framebuffer_state fb; + struct pipe_viewport_state viewport; + + /* Framebuffer uses actual surface width/height + */ + memset(&fb, 0, sizeof fb); + fb.width = surface->width; + fb.height = surface->height; + fb.nr_cbufs = 1; + fb.cbufs[0] = surface; + fb.zsbuf = 0; + + /* Viewport just touches the bit we're interested in: + */ + viewport.scale[0] = width / 2.f; + viewport.scale[1] = height / 2.f; + viewport.scale[2] = 1.0; + viewport.scale[3] = 1.0; + viewport.translate[0] = width / 2.f; + viewport.translate[1] = height / 2.f; + viewport.translate[2] = 0.0; + viewport.translate[3] = 0.0; + + /* Constant buffer set up to match viewport dimensions: + */ + if (r->fb_width != width || r->fb_height != height) { + float vs_consts[8] = { + 2.f / width, 2.f / height, 1, 1, + -1, -1, 0, 0 + }; + + r->fb_width = width; + r->fb_height = height; + + renderer_set_constants(r, PIPE_SHADER_VERTEX, + vs_consts, sizeof vs_consts); + } + + cso_set_framebuffer(r->cso, &fb); + cso_set_viewport(r->cso, &viewport); +} + +void +renderer_set_constants(struct xa_context *r, + int shader_type, const float *params, int param_bytes) +{ + struct pipe_resource **cbuf = + (shader_type == PIPE_SHADER_VERTEX) ? &r->vs_const_buffer : + &r->fs_const_buffer; + + pipe_resource_reference(cbuf, NULL); + *cbuf = pipe_buffer_create(r->pipe->screen, + PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STATIC, + param_bytes); + + if (*cbuf) { + pipe_buffer_write(r->pipe, *cbuf, 0, param_bytes, params); + } + r->pipe->set_constant_buffer(r->pipe, shader_type, 0, *cbuf); +} + +void +renderer_copy_prepare(struct xa_context *r, + struct pipe_surface *dst_surface, + struct pipe_resource *src_texture) +{ + struct pipe_context *pipe = r->pipe; + struct pipe_screen *screen = pipe->screen; + struct xa_shader shader; + + assert(screen->is_format_supported(screen, dst_surface->format, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_RENDER_TARGET)); + (void)screen; + + /* set misc state we care about */ + { + struct pipe_blend_state blend; + + memset(&blend, 0, sizeof(blend)); + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].colormask = PIPE_MASK_RGBA; + cso_set_blend(r->cso, &blend); + } + + /* sampler */ + { + struct pipe_sampler_state sampler; + + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.normalized_coords = 1; + cso_single_sampler(r->cso, 0, &sampler); + cso_single_sampler_done(r->cso); + } + + renderer_bind_destination(r, dst_surface, + dst_surface->width, dst_surface->height); + + /* texture/sampler view */ + { + struct pipe_sampler_view templ; + struct pipe_sampler_view *src_view; + + u_sampler_view_default_template(&templ, + src_texture, src_texture->format); + src_view = pipe->create_sampler_view(pipe, src_texture, &templ); + cso_set_fragment_sampler_views(r->cso, 1, &src_view); + pipe_sampler_view_reference(&src_view, NULL); + } + + /* shaders */ + shader = xa_shaders_get(r->shaders, VS_COMPOSITE, FS_COMPOSITE); + cso_set_vertex_shader_handle(r->cso, shader.vs); + cso_set_fragment_shader_handle(r->cso, shader.fs); + + r->buffer_size = 0; + r->attrs_per_vertex = 2; +} + +void +renderer_copy(struct xa_context *r, + int dx, + int dy, + int sx, + int sy, + int width, int height, float src_width, float src_height) +{ + float s0, t0, s1, t1; + float x0, y0, x1, y1; + + /* XXX: could put the texcoord scaling calculation into the vertex + * shader. + */ + s0 = sx / src_width; + s1 = (sx + width) / src_width; + t0 = sy / src_height; + t1 = (sy + height) / src_height; + + x0 = dx; + x1 = dx + width; + y0 = dy; + y1 = dy + height; + + /* draw quad */ + renderer_draw_conditional(r, 4 * 8); + add_vertex_1tex(r, x0, y0, s0, t0); + add_vertex_1tex(r, x1, y0, s1, t0); + add_vertex_1tex(r, x1, y1, s1, t1); + add_vertex_1tex(r, x0, y1, s0, t1); +} + +void +renderer_draw_yuv(struct xa_context *r, + float src_x, + float src_y, + float src_w, + float src_h, + int dst_x, + int dst_y, int dst_w, int dst_h, struct xa_surface *srf[]) +{ + struct pipe_context *pipe = r->pipe; + struct pipe_resource *buf = 0; + + buf = setup_vertex_data_yuv(r, + src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, + dst_h, srf); + + if (buf) { + const int num_attribs = 2; /*pos + tex coord */ + + cso_set_vertex_elements(r->cso, num_attribs, r->velems); + + util_draw_vertex_buffer(pipe, r->cso, buf, 0, PIPE_PRIM_QUADS, 4, /* verts */ + num_attribs); /* attribs/vert */ + + pipe_resource_reference(&buf, NULL); + } +} + +void +renderer_begin_solid(struct xa_context *r) +{ + r->buffer_size = 0; + r->attrs_per_vertex = 2; +} + +void +renderer_solid(struct xa_context *r, + int x0, int y0, int x1, int y1, float *color) +{ + /* + * debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n", + * x0, y0, x1, y1, color[0], color[1], color[2], color[3]); */ + + renderer_draw_conditional(r, 4 * 8); + + /* 1st vertex */ + add_vertex_color(r, x0, y0, color); + /* 2nd vertex */ + add_vertex_color(r, x1, y0, color); + /* 3rd vertex */ + add_vertex_color(r, x1, y1, color); + /* 4th vertex */ + add_vertex_color(r, x0, y1, color); +} + +void +renderer_draw_flush(struct xa_context *r) +{ + renderer_draw_conditional(r, 0); +} + +void +renderer_begin_textures(struct xa_context *r) +{ + r->attrs_per_vertex = 1 + r->num_bound_samplers; + r->buffer_size = 0; +} + +void +renderer_texture(struct xa_context *r, + int *pos, + int width, int height, + const float *src_matrix, + const float *mask_matrix) +{ + struct pipe_sampler_view **sampler_view = r->bound_sampler_views; + +#if 0 + if (src_matrix) { + debug_printf("src_matrix = \n"); + debug_printf("%f, %f, %f\n", src_matrix[0], src_matrix[1], src_matrix[2]); + debug_printf("%f, %f, %f\n", src_matrix[3], src_matrix[4], src_matrix[5]); + debug_printf("%f, %f, %f\n", src_matrix[6], src_matrix[7], src_matrix[8]); + } + if (mask_matrix) { + debug_printf("mask_matrix = \n"); + debug_printf("%f, %f, %f\n", mask_matrix[0], mask_matrix[1], mask_matrix[2]); + debug_printf("%f, %f, %f\n", mask_matrix[3], mask_matrix[4], mask_matrix[5]); + debug_printf("%f, %f, %f\n", mask_matrix[6], mask_matrix[7], mask_matrix[8]); + } +#endif + + switch(r->attrs_per_vertex) { + case 2: + renderer_draw_conditional(r, 4 * 8); + add_vertex_data1(r, + pos[0], pos[1], /* src */ + pos[4], pos[5], /* dst */ + width, height, + sampler_view[0]->texture, src_matrix); + break; + case 3: + renderer_draw_conditional(r, 4 * 12); + add_vertex_data2(r, + pos[0], pos[1], /* src */ + pos[2], pos[3], /* mask */ + pos[4], pos[5], /* dst */ + width, height, + sampler_view[0]->texture, sampler_view[1]->texture, + src_matrix, mask_matrix); + break; + default: + break; + } +} diff --git a/src/gallium/state_trackers/xa/xa_symbols b/src/gallium/state_trackers/xa/xa_symbols new file mode 100644 index 00000000000..6da701f9702 --- /dev/null +++ b/src/gallium/state_trackers/xa/xa_symbols @@ -0,0 +1,30 @@ +xa_tracker_version +xa_tracker_create +xa_tracker_destroy +xa_surface_create +xa_surface_destroy +xa_surface_redefine +xa_surface_dma +xa_surface_map +xa_surface_unmap +xa_surface_format +xa_surface_handle +xa_format_check_supported +xa_context_default +xa_context_create +xa_context_destroy +xa_fence_get +xa_fence_wait +xa_fence_destroy +xa_copy_prepare +xa_copy +xa_copy_done +xa_solid_prepare +xa_solid +xa_solid_done +xa_composite_allocation +xa_composite_check_accelerated +xa_composite_prepare +xa_composite_rect +xa_composite_done +xa_yuv_planar_blit diff --git a/src/gallium/state_trackers/xa/xa_tgsi.c b/src/gallium/state_trackers/xa/xa_tgsi.c new file mode 100644 index 00000000000..fb6ffefd636 --- /dev/null +++ b/src/gallium/state_trackers/xa/xa_tgsi.c @@ -0,0 +1,651 @@ +/********************************************************** + * Copyright 2009-2011 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice 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: + * Zack Rusin <zackr-at-vmware-dot-com> + */ +#include "xa_priv.h" + +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_shader_tokens.h" + +#include "util/u_memory.h" + +#include "tgsi/tgsi_ureg.h" + +#include "cso_cache/cso_context.h" +#include "cso_cache/cso_hash.h" + +/* Vertex shader: + * IN[0] = vertex pos + * IN[1] = src tex coord | solid fill color + * IN[2] = mask tex coord + * IN[3] = dst tex coord + * CONST[0] = (2/dst_width, 2/dst_height, 1, 1) + * CONST[1] = (-1, -1, 0, 0) + * + * OUT[0] = vertex pos + * OUT[1] = src tex coord | solid fill color + * OUT[2] = mask tex coord + * OUT[3] = dst tex coord + */ + +/* Fragment shader: + * SAMP[0] = src + * SAMP[1] = mask + * SAMP[2] = dst + * IN[0] = pos src | solid fill color + * IN[1] = pos mask + * IN[2] = pos dst + * CONST[0] = (0, 0, 0, 1) + * + * OUT[0] = color + */ + +static void +print_fs_traits(int fs_traits) +{ + const char *strings[] = { + "FS_COMPOSITE", /* = 1 << 0, */ + "FS_MASK", /* = 1 << 1, */ + "FS_SOLID_FILL", /* = 1 << 2, */ + "FS_LINGRAD_FILL", /* = 1 << 3, */ + "FS_RADGRAD_FILL", /* = 1 << 4, */ + "FS_CA_FULL", /* = 1 << 5, *//* src.rgba * mask.rgba */ + "FS_CA_SRCALPHA", /* = 1 << 6, *//* src.aaaa * mask.rgba */ + "FS_YUV", /* = 1 << 7, */ + "FS_SRC_REPEAT_NONE", /* = 1 << 8, */ + "FS_MASK_REPEAT_NONE", /* = 1 << 9, */ + "FS_SRC_SWIZZLE_RGB", /* = 1 << 10, */ + "FS_MASK_SWIZZLE_RGB", /* = 1 << 11, */ + "FS_SRC_SET_ALPHA", /* = 1 << 12, */ + "FS_MASK_SET_ALPHA", /* = 1 << 13, */ + "FS_SRC_LUMINANCE", /* = 1 << 14, */ + "FS_MASK_LUMINANCE", /* = 1 << 15, */ + }; + int i, k; + + debug_printf("%s: ", __func__); + + for (i = 0, k = 1; k < (1 << 16); i++, k <<= 1) { + if (fs_traits & k) + debug_printf("%s, ", strings[i]); + } + + debug_printf("\n"); +} + +struct xa_shaders { + struct xa_context *r; + + struct cso_hash *vs_hash; + struct cso_hash *fs_hash; +}; + +static INLINE void +src_in_mask(struct ureg_program *ureg, + struct ureg_dst dst, + struct ureg_src src, + struct ureg_src mask, + unsigned component_alpha, unsigned mask_luminance) +{ + if (component_alpha == FS_CA_FULL) { + ureg_MUL(ureg, dst, src, mask); + } else if (component_alpha == FS_CA_SRCALPHA) { + ureg_MUL(ureg, dst, ureg_scalar(src, TGSI_SWIZZLE_W), mask); + } else { + if (mask_luminance) + ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_X)); + else + ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_W)); + } +} + +static struct ureg_src +vs_normalize_coords(struct ureg_program *ureg, + struct ureg_src coords, + struct ureg_src const0, struct ureg_src const1) +{ + struct ureg_dst tmp = ureg_DECL_temporary(ureg); + struct ureg_src ret; + + ureg_MAD(ureg, tmp, coords, const0, const1); + ret = ureg_src(tmp); + ureg_release_temporary(ureg, tmp); + return ret; +} + +static void +linear_gradient(struct ureg_program *ureg, + struct ureg_dst out, + struct ureg_src pos, + struct ureg_src sampler, + struct ureg_src coords, + struct ureg_src const0124, + struct ureg_src matrow0, + struct ureg_src matrow1, struct ureg_src matrow2) +{ + struct ureg_dst temp0 = ureg_DECL_temporary(ureg); + struct ureg_dst temp1 = ureg_DECL_temporary(ureg); + struct ureg_dst temp2 = ureg_DECL_temporary(ureg); + struct ureg_dst temp3 = ureg_DECL_temporary(ureg); + struct ureg_dst temp4 = ureg_DECL_temporary(ureg); + struct ureg_dst temp5 = ureg_DECL_temporary(ureg); + + ureg_MOV(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos); + ureg_MOV(ureg, + ureg_writemask(temp0, TGSI_WRITEMASK_Z), + ureg_scalar(const0124, TGSI_SWIZZLE_Y)); + + ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0)); + ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0)); + ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0)); + ureg_RCP(ureg, temp3, ureg_src(temp3)); + ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3)); + ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3)); + + ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_X), ureg_src(temp1)); + ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_Y), ureg_src(temp2)); + + ureg_MUL(ureg, temp0, + ureg_scalar(coords, TGSI_SWIZZLE_Y), + ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_Y)); + ureg_MAD(ureg, temp1, + ureg_scalar(coords, TGSI_SWIZZLE_X), + ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_X), ureg_src(temp0)); + + ureg_MUL(ureg, temp2, ureg_src(temp1), ureg_scalar(coords, TGSI_SWIZZLE_Z)); + + ureg_TEX(ureg, out, TGSI_TEXTURE_1D, ureg_src(temp2), sampler); + + ureg_release_temporary(ureg, temp0); + ureg_release_temporary(ureg, temp1); + ureg_release_temporary(ureg, temp2); + ureg_release_temporary(ureg, temp3); + ureg_release_temporary(ureg, temp4); + ureg_release_temporary(ureg, temp5); +} + +static void +radial_gradient(struct ureg_program *ureg, + struct ureg_dst out, + struct ureg_src pos, + struct ureg_src sampler, + struct ureg_src coords, + struct ureg_src const0124, + struct ureg_src matrow0, + struct ureg_src matrow1, struct ureg_src matrow2) +{ + struct ureg_dst temp0 = ureg_DECL_temporary(ureg); + struct ureg_dst temp1 = ureg_DECL_temporary(ureg); + struct ureg_dst temp2 = ureg_DECL_temporary(ureg); + struct ureg_dst temp3 = ureg_DECL_temporary(ureg); + struct ureg_dst temp4 = ureg_DECL_temporary(ureg); + struct ureg_dst temp5 = ureg_DECL_temporary(ureg); + + ureg_MOV(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos); + ureg_MOV(ureg, + ureg_writemask(temp0, TGSI_WRITEMASK_Z), + ureg_scalar(const0124, TGSI_SWIZZLE_Y)); + + ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0)); + ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0)); + ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0)); + ureg_RCP(ureg, temp3, ureg_src(temp3)); + ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3)); + ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3)); + + ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_X), ureg_src(temp1)); + ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_Y), ureg_src(temp2)); + + ureg_MUL(ureg, temp0, ureg_scalar(coords, TGSI_SWIZZLE_Y), + ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y)); + ureg_MAD(ureg, temp1, + ureg_scalar(coords, TGSI_SWIZZLE_X), + ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X), ureg_src(temp0)); + ureg_ADD(ureg, temp1, ureg_src(temp1), ureg_src(temp1)); + ureg_MUL(ureg, temp3, + ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y), + ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y)); + ureg_MAD(ureg, temp4, + ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X), + ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X), ureg_src(temp3)); + ureg_MOV(ureg, temp4, ureg_negate(ureg_src(temp4))); + ureg_MUL(ureg, temp2, ureg_scalar(coords, TGSI_SWIZZLE_Z), ureg_src(temp4)); + ureg_MUL(ureg, temp0, + ureg_scalar(const0124, TGSI_SWIZZLE_W), ureg_src(temp2)); + ureg_MUL(ureg, temp3, ureg_src(temp1), ureg_src(temp1)); + ureg_SUB(ureg, temp2, ureg_src(temp3), ureg_src(temp0)); + ureg_RSQ(ureg, temp2, ureg_abs(ureg_src(temp2))); + ureg_RCP(ureg, temp2, ureg_src(temp2)); + ureg_SUB(ureg, temp1, ureg_src(temp2), ureg_src(temp1)); + ureg_ADD(ureg, temp0, + ureg_scalar(coords, TGSI_SWIZZLE_Z), + ureg_scalar(coords, TGSI_SWIZZLE_Z)); + ureg_RCP(ureg, temp0, ureg_src(temp0)); + ureg_MUL(ureg, temp2, ureg_src(temp1), ureg_src(temp0)); + ureg_TEX(ureg, out, TGSI_TEXTURE_1D, ureg_src(temp2), sampler); + + ureg_release_temporary(ureg, temp0); + ureg_release_temporary(ureg, temp1); + ureg_release_temporary(ureg, temp2); + ureg_release_temporary(ureg, temp3); + ureg_release_temporary(ureg, temp4); + ureg_release_temporary(ureg, temp5); +} + +static void * +create_vs(struct pipe_context *pipe, unsigned vs_traits) +{ + struct ureg_program *ureg; + struct ureg_src src; + struct ureg_dst dst; + struct ureg_src const0, const1; + boolean is_fill = (vs_traits & VS_FILL) != 0; + boolean is_composite = (vs_traits & VS_COMPOSITE) != 0; + boolean has_mask = (vs_traits & VS_MASK) != 0; + boolean is_yuv = (vs_traits & VS_YUV) != 0; + unsigned input_slot = 0; + + ureg = ureg_create(TGSI_PROCESSOR_VERTEX); + if (ureg == NULL) + return 0; + + const0 = ureg_DECL_constant(ureg, 0); + const1 = ureg_DECL_constant(ureg, 1); + + /* it has to be either a fill or a composite op */ + debug_assert((is_fill ^ is_composite) ^ is_yuv); + + src = ureg_DECL_vs_input(ureg, input_slot++); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); + src = vs_normalize_coords(ureg, src, const0, const1); + ureg_MOV(ureg, dst, src); + + if (is_yuv) { + src = ureg_DECL_vs_input(ureg, input_slot++); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0); + ureg_MOV(ureg, dst, src); + } + + if (is_composite) { + src = ureg_DECL_vs_input(ureg, input_slot++); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0); + ureg_MOV(ureg, dst, src); + } + + if (is_fill) { + src = ureg_DECL_vs_input(ureg, input_slot++); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); + ureg_MOV(ureg, dst, src); + } + + if (has_mask) { + src = ureg_DECL_vs_input(ureg, input_slot++); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1); + ureg_MOV(ureg, dst, src); + } + + ureg_END(ureg); + + return ureg_create_shader_and_destroy(ureg, pipe); +} + +static void * +create_yuv_shader(struct pipe_context *pipe, struct ureg_program *ureg) +{ + struct ureg_src y_sampler, u_sampler, v_sampler; + struct ureg_src pos; + struct ureg_src matrow0, matrow1, matrow2; + struct ureg_dst y, u, v, rgb; + struct ureg_dst out = ureg_DECL_output(ureg, + TGSI_SEMANTIC_COLOR, + 0); + + pos = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_GENERIC, 0, + TGSI_INTERPOLATE_PERSPECTIVE); + + rgb = ureg_DECL_temporary(ureg); + y = ureg_DECL_temporary(ureg); + u = ureg_DECL_temporary(ureg); + v = ureg_DECL_temporary(ureg); + + y_sampler = ureg_DECL_sampler(ureg, 0); + u_sampler = ureg_DECL_sampler(ureg, 1); + v_sampler = ureg_DECL_sampler(ureg, 2); + + matrow0 = ureg_DECL_constant(ureg, 0); + matrow1 = ureg_DECL_constant(ureg, 1); + matrow2 = ureg_DECL_constant(ureg, 2); + + ureg_TEX(ureg, y, TGSI_TEXTURE_2D, pos, y_sampler); + ureg_TEX(ureg, u, TGSI_TEXTURE_2D, pos, u_sampler); + ureg_TEX(ureg, v, TGSI_TEXTURE_2D, pos, v_sampler); + + ureg_SUB(ureg, u, ureg_src(u), ureg_scalar(matrow0, TGSI_SWIZZLE_W)); + ureg_SUB(ureg, v, ureg_src(v), ureg_scalar(matrow0, TGSI_SWIZZLE_W)); + + ureg_MUL(ureg, rgb, ureg_scalar(ureg_src(y), TGSI_SWIZZLE_X), matrow0); + ureg_MAD(ureg, rgb, + ureg_scalar(ureg_src(u), TGSI_SWIZZLE_X), matrow1, ureg_src(rgb)); + ureg_MAD(ureg, rgb, + ureg_scalar(ureg_src(v), TGSI_SWIZZLE_X), matrow2, ureg_src(rgb)); + + /* rgb.a = 1; */ + ureg_MOV(ureg, ureg_writemask(rgb, TGSI_WRITEMASK_W), + ureg_scalar(matrow0, TGSI_SWIZZLE_X)); + + ureg_MOV(ureg, out, ureg_src(rgb)); + + ureg_release_temporary(ureg, rgb); + ureg_release_temporary(ureg, y); + ureg_release_temporary(ureg, u); + ureg_release_temporary(ureg, v); + + ureg_END(ureg); + + return ureg_create_shader_and_destroy(ureg, pipe); +} + +static INLINE void +xrender_tex(struct ureg_program *ureg, + struct ureg_dst dst, + struct ureg_src coords, + struct ureg_src sampler, + struct ureg_src imm0, + boolean repeat_none, boolean swizzle, boolean set_alpha) +{ + if (repeat_none) { + struct ureg_dst tmp0 = ureg_DECL_temporary(ureg); + struct ureg_dst tmp1 = ureg_DECL_temporary(ureg); + + ureg_SGT(ureg, tmp1, ureg_swizzle(coords, + TGSI_SWIZZLE_X, + TGSI_SWIZZLE_Y, + TGSI_SWIZZLE_X, + TGSI_SWIZZLE_Y), ureg_scalar(imm0, + TGSI_SWIZZLE_X)); + ureg_SLT(ureg, tmp0, + ureg_swizzle(coords, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, + TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y), ureg_scalar(imm0, + TGSI_SWIZZLE_W)); + ureg_MIN(ureg, tmp0, ureg_src(tmp0), ureg_src(tmp1)); + ureg_MIN(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X), + ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_Y)); + ureg_TEX(ureg, tmp1, TGSI_TEXTURE_2D, coords, sampler); + if (swizzle) + ureg_MOV(ureg, tmp1, ureg_swizzle(ureg_src(tmp1), + TGSI_SWIZZLE_Z, + TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, + TGSI_SWIZZLE_W)); + if (set_alpha) + ureg_MOV(ureg, + ureg_writemask(tmp1, TGSI_WRITEMASK_W), + ureg_scalar(imm0, TGSI_SWIZZLE_W)); + ureg_MUL(ureg, dst, ureg_src(tmp1), ureg_src(tmp0)); + ureg_release_temporary(ureg, tmp0); + ureg_release_temporary(ureg, tmp1); + } else { + if (swizzle) { + struct ureg_dst tmp = ureg_DECL_temporary(ureg); + + ureg_TEX(ureg, tmp, TGSI_TEXTURE_2D, coords, sampler); + ureg_MOV(ureg, dst, ureg_swizzle(ureg_src(tmp), + TGSI_SWIZZLE_Z, + TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, + TGSI_SWIZZLE_W)); + ureg_release_temporary(ureg, tmp); + } else { + ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler); + } + if (set_alpha) + ureg_MOV(ureg, + ureg_writemask(dst, TGSI_WRITEMASK_W), + ureg_scalar(imm0, TGSI_SWIZZLE_W)); + } +} + +static void * +create_fs(struct pipe_context *pipe, unsigned fs_traits) +{ + struct ureg_program *ureg; + struct ureg_src /*dst_sampler, */ src_sampler, mask_sampler; + struct ureg_src /*dst_pos, */ src_input, mask_pos; + struct ureg_dst src, mask; + struct ureg_dst out; + struct ureg_src imm0 = { 0 }; + unsigned has_mask = (fs_traits & FS_MASK) != 0; + unsigned is_fill = (fs_traits & FS_FILL) != 0; + unsigned is_composite = (fs_traits & FS_COMPOSITE) != 0; + unsigned is_solid = (fs_traits & FS_SOLID_FILL) != 0; + unsigned is_lingrad = (fs_traits & FS_LINGRAD_FILL) != 0; + unsigned is_radgrad = (fs_traits & FS_RADGRAD_FILL) != 0; + unsigned comp_alpha_mask = fs_traits & FS_COMPONENT_ALPHA; + unsigned is_yuv = (fs_traits & FS_YUV) != 0; + unsigned src_repeat_none = (fs_traits & FS_SRC_REPEAT_NONE) != 0; + unsigned mask_repeat_none = (fs_traits & FS_MASK_REPEAT_NONE) != 0; + unsigned src_swizzle = (fs_traits & FS_SRC_SWIZZLE_RGB) != 0; + unsigned mask_swizzle = (fs_traits & FS_MASK_SWIZZLE_RGB) != 0; + unsigned src_set_alpha = (fs_traits & FS_SRC_SET_ALPHA) != 0; + unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0; + unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0; + unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0; + +#if 0 + print_fs_traits(fs_traits); +#else + (void)print_fs_traits; +#endif + + ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); + if (ureg == NULL) + return 0; + + /* it has to be either a fill, a composite op or a yuv conversion */ + debug_assert((is_fill ^ is_composite) ^ is_yuv); + (void)is_yuv; + + out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); + + if (src_repeat_none || mask_repeat_none || + src_set_alpha || mask_set_alpha || src_luminance) { + imm0 = ureg_imm4f(ureg, 0, 0, 0, 1); + } + if (is_composite) { + src_sampler = ureg_DECL_sampler(ureg, 0); + src_input = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_GENERIC, 0, + TGSI_INTERPOLATE_PERSPECTIVE); + } else if (is_fill) { + if (is_solid) + src_input = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_COLOR, 0, + TGSI_INTERPOLATE_PERSPECTIVE); + else + src_input = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_POSITION, 0, + TGSI_INTERPOLATE_PERSPECTIVE); + } else { + debug_assert(is_yuv); + return create_yuv_shader(pipe, ureg); + } + + if (has_mask) { + mask_sampler = ureg_DECL_sampler(ureg, 1); + mask_pos = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_GENERIC, 1, + TGSI_INTERPOLATE_PERSPECTIVE); + } +#if 0 /* unused right now */ + dst_sampler = ureg_DECL_sampler(ureg, 2); + dst_pos = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_POSITION, 2, + TGSI_INTERPOLATE_PERSPECTIVE); +#endif + + if (is_composite) { + if (has_mask || src_luminance) + src = ureg_DECL_temporary(ureg); + else + src = out; + xrender_tex(ureg, src, src_input, src_sampler, imm0, + src_repeat_none, src_swizzle, src_set_alpha); + } else if (is_fill) { + if (is_solid) { + if (has_mask || src_luminance) + src = ureg_dst(src_input); + else + ureg_MOV(ureg, out, src_input); + } else if (is_lingrad || is_radgrad) { + struct ureg_src coords, const0124, matrow0, matrow1, matrow2; + + if (has_mask || src_luminance) + src = ureg_DECL_temporary(ureg); + else + src = out; + + coords = ureg_DECL_constant(ureg, 0); + const0124 = ureg_DECL_constant(ureg, 1); + matrow0 = ureg_DECL_constant(ureg, 2); + matrow1 = ureg_DECL_constant(ureg, 3); + matrow2 = ureg_DECL_constant(ureg, 4); + + if (is_lingrad) { + linear_gradient(ureg, src, + src_input, src_sampler, + coords, const0124, matrow0, matrow1, matrow2); + } else if (is_radgrad) { + radial_gradient(ureg, src, + src_input, src_sampler, + coords, const0124, matrow0, matrow1, matrow2); + } + } else + debug_assert(!"Unknown fill type!"); + } + if (src_luminance) { + ureg_MOV(ureg, src, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X)); + ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ), + ureg_scalar(imm0, TGSI_SWIZZLE_X)); + if (!has_mask) + ureg_MOV(ureg, out, ureg_src(src)); + } + + if (has_mask) { + mask = ureg_DECL_temporary(ureg); + xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0, + mask_repeat_none, mask_swizzle, mask_set_alpha); + /* src IN mask */ + src_in_mask(ureg, out, ureg_src(src), ureg_src(mask), + comp_alpha_mask, mask_luminance); + ureg_release_temporary(ureg, mask); + } + + ureg_END(ureg); + + return ureg_create_shader_and_destroy(ureg, pipe); +} + +struct xa_shaders * +xa_shaders_create(struct xa_context *r) +{ + struct xa_shaders *sc = CALLOC_STRUCT(xa_shaders); + + sc->r = r; + sc->vs_hash = cso_hash_create(); + sc->fs_hash = cso_hash_create(); + + return sc; +} + +static void +cache_destroy(struct cso_context *cso, + struct cso_hash *hash, unsigned processor) +{ + struct cso_hash_iter iter = cso_hash_first_node(hash); + + while (!cso_hash_iter_is_null(iter)) { + void *shader = (void *)cso_hash_iter_data(iter); + + if (processor == PIPE_SHADER_FRAGMENT) { + cso_delete_fragment_shader(cso, shader); + } else if (processor == PIPE_SHADER_VERTEX) { + cso_delete_vertex_shader(cso, shader); + } + iter = cso_hash_erase(hash, iter); + } + cso_hash_delete(hash); +} + +void +xa_shaders_destroy(struct xa_shaders *sc) +{ + cache_destroy(sc->r->cso, sc->vs_hash, PIPE_SHADER_VERTEX); + cache_destroy(sc->r->cso, sc->fs_hash, PIPE_SHADER_FRAGMENT); + + FREE(sc); +} + +static INLINE void * +shader_from_cache(struct pipe_context *pipe, + unsigned type, struct cso_hash *hash, unsigned key) +{ + void *shader = 0; + + struct cso_hash_iter iter = cso_hash_find(hash, key); + + if (cso_hash_iter_is_null(iter)) { + if (type == PIPE_SHADER_VERTEX) + shader = create_vs(pipe, key); + else + shader = create_fs(pipe, key); + cso_hash_insert(hash, key, shader); + } else + shader = (void *)cso_hash_iter_data(iter); + + return shader; +} + +struct xa_shader +xa_shaders_get(struct xa_shaders *sc, unsigned vs_traits, unsigned fs_traits) +{ + struct xa_shader shader = { NULL, NULL }; + void *vs, *fs; + + vs = shader_from_cache(sc->r->pipe, PIPE_SHADER_VERTEX, + sc->vs_hash, vs_traits); + fs = shader_from_cache(sc->r->pipe, PIPE_SHADER_FRAGMENT, + sc->fs_hash, fs_traits); + + debug_assert(vs && fs); + if (!vs || !fs) + return shader; + + shader.vs = vs; + shader.fs = fs; + + return shader; +} diff --git a/src/gallium/state_trackers/xa/xa_tracker.c b/src/gallium/state_trackers/xa/xa_tracker.c new file mode 100644 index 00000000000..50922d38378 --- /dev/null +++ b/src/gallium/state_trackers/xa/xa_tracker.c @@ -0,0 +1,448 @@ +/********************************************************** + * Copyright 2009-2011 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice 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: + * Thomas Hellstrom <thellstrom-at-vmware-dot-com> + */ + +#include "xa_tracker.h" +#include "xa_priv.h" +#include "pipe/p_state.h" +#include "pipe/p_format.h" +#include "state_tracker/drm_driver.h" +#include "util/u_inlines.h" + +/* + * format_map [xa_surface_type][first..last in list]. + * Needs to be updated when enum xa_formats is updated. + */ + +static const enum xa_formats preferred_a[] = { xa_format_a8 }; + +static const enum xa_formats preferred_argb[] = + { xa_format_a8r8g8b8, xa_format_x8r8g8b8, xa_format_r5g6b5, + xa_format_x1r5g5b5 +}; +static const enum xa_formats preferred_z[] = + { xa_format_z32, xa_format_z24, xa_format_z16 }; +static const enum xa_formats preferred_sz[] = + { xa_format_x8z24, xa_format_s8z24 }; +static const enum xa_formats preferred_zs[] = + { xa_format_z24x8, xa_format_z24s8 }; +static const enum xa_formats preferred_yuv[] = { xa_format_yuv8 }; + +static const enum xa_formats *preferred[] = + { NULL, preferred_a, preferred_argb, NULL, NULL, + preferred_z, preferred_zs, preferred_sz, preferred_yuv +}; + +static const unsigned int num_preferred[] = { 0, + sizeof(preferred_a) / sizeof(enum xa_formats), + sizeof(preferred_argb) / sizeof(enum xa_formats), + 0, + 0, + sizeof(preferred_z) / sizeof(enum xa_formats), + sizeof(preferred_zs) / sizeof(enum xa_formats), + sizeof(preferred_sz) / sizeof(enum xa_formats), + sizeof(preferred_yuv) / sizeof(enum xa_formats) +}; + +static const unsigned int stype_bind[XA_LAST_SURFACE_TYPE] = { 0, + PIPE_BIND_SAMPLER_VIEW, + PIPE_BIND_SAMPLER_VIEW, + PIPE_BIND_SAMPLER_VIEW, + PIPE_BIND_SAMPLER_VIEW, + PIPE_BIND_DEPTH_STENCIL, + PIPE_BIND_DEPTH_STENCIL, + PIPE_BIND_DEPTH_STENCIL, + PIPE_BIND_SAMPLER_VIEW +}; + +static struct xa_format_descriptor +xa_get_pipe_format(enum xa_formats xa_format) +{ + struct xa_format_descriptor fdesc; + + fdesc.xa_format = xa_format; + + switch (xa_format) { + case xa_format_a8r8g8b8: + fdesc.format = PIPE_FORMAT_B8G8R8A8_UNORM; + break; + case xa_format_x8r8g8b8: + fdesc.format = PIPE_FORMAT_B8G8R8X8_UNORM; + break; + case xa_format_r5g6b5: + fdesc.format = PIPE_FORMAT_B5G6R5_UNORM; + break; + case xa_format_x1r5g5b5: + fdesc.format = PIPE_FORMAT_B5G5R5A1_UNORM; + break; + case xa_format_a8: + fdesc.format = PIPE_FORMAT_L8_UNORM; + break; + case xa_format_z24: + fdesc.format = PIPE_FORMAT_Z24X8_UNORM; + break; + case xa_format_z16: + fdesc.format = PIPE_FORMAT_Z16_UNORM; + break; + case xa_format_z32: + fdesc.format = PIPE_FORMAT_Z32_UNORM; + break; + case xa_format_x8z24: + fdesc.format = PIPE_FORMAT_Z24X8_UNORM; + break; + case xa_format_z24x8: + fdesc.format = PIPE_FORMAT_X8Z24_UNORM; + break; + case xa_format_s8z24: + fdesc.format = PIPE_FORMAT_Z24_UNORM_S8_USCALED; + break; + case xa_format_z24s8: + fdesc.format = PIPE_FORMAT_S8_USCALED_Z24_UNORM; + break; + case xa_format_yuv8: + fdesc.format = PIPE_FORMAT_L8_UNORM; + break; + default: + fdesc.xa_format = xa_format_unknown; + break; + } + return fdesc; +} + +struct xa_tracker * +xa_tracker_create(int drm_fd) +{ + struct xa_tracker *xa = calloc(1, sizeof(struct xa_tracker)); + enum xa_surface_type stype; + unsigned int num_formats; + + if (!xa) + return NULL; + + xa->screen = driver_descriptor.create_screen(drm_fd); + if (!xa->screen) + goto out_no_screen; + + xa->default_ctx = xa_context_create(xa); + if (!xa->default_ctx) + goto out_no_pipe; + + num_formats = 0; + for (stype = 0; stype < XA_LAST_SURFACE_TYPE; ++stype) + num_formats += num_preferred[stype]; + + num_formats += 1; + xa->supported_formats = calloc(num_formats, sizeof(*xa->supported_formats)); + if (!xa->supported_formats) + goto out_sf_alloc_fail; + + xa->supported_formats[0] = xa_format_unknown; + num_formats = 1; + memset(xa->format_map, 0, sizeof(xa->format_map)); + + for (stype = 0; stype < XA_LAST_SURFACE_TYPE; ++stype) { + unsigned int bind = stype_bind[stype]; + enum xa_formats xa_format; + int i; + + for (i = 0; i < num_preferred[stype]; ++i) { + xa_format = preferred[stype][i]; + + struct xa_format_descriptor fdesc = xa_get_pipe_format(xa_format); + + if (xa->screen->is_format_supported(xa->screen, fdesc.format, + PIPE_TEXTURE_2D, 0, bind)) { + if (xa->format_map[stype][0] == 0) + xa->format_map[stype][0] = num_formats; + xa->format_map[stype][1] = num_formats; + xa->supported_formats[num_formats++] = xa_format; + } + } + } + return xa; + + out_sf_alloc_fail: + xa_context_destroy(xa->default_ctx); + out_no_pipe: + xa->screen->destroy(xa->screen); + out_no_screen: + free(xa); + return NULL; +} + +void +xa_tracker_destroy(struct xa_tracker *xa) +{ + free(xa->supported_formats); + xa_context_destroy(xa->default_ctx); + xa->screen->destroy(xa->screen); + free(xa); +} + +static int +xa_flags_compat(unsigned int old_flags, unsigned int new_flags) +{ + unsigned int flag_diff = (old_flags ^ new_flags); + + if (flag_diff == 0) + return 1; + + if (flag_diff & XA_FLAG_SHARED) + return 0; + /* + * Don't recreate if we're dropping the render target flag. + */ + if (flag_diff & XA_FLAG_RENDER_TARGET) + return ((new_flags & XA_FLAG_RENDER_TARGET) == 0); + + /* + * Always recreate for unknown / unimplemented flags. + */ + return 0; +} + +static struct xa_format_descriptor +xa_get_format_stype_depth(struct xa_tracker *xa, + enum xa_surface_type stype, unsigned int depth) +{ + unsigned int i; + struct xa_format_descriptor fdesc; + int found = 0; + + for (i = xa->format_map[stype][0]; i <= xa->format_map[stype][1]; ++i) { + fdesc = xa_get_pipe_format(xa->supported_formats[i]); + if (fdesc.xa_format != xa_format_unknown && + xa_format_depth(fdesc.xa_format) == depth) { + found = 1; + break; + } + } + + if (!found) + fdesc.xa_format = xa_format_unknown; + + return fdesc; +} + +int +xa_format_check_supported(struct xa_tracker *xa, + enum xa_formats xa_format, unsigned int flags) +{ + struct xa_format_descriptor fdesc = xa_get_pipe_format(xa_format); + unsigned int bind; + + if (fdesc.xa_format == xa_format_unknown) + return -XA_ERR_INVAL; + + bind = stype_bind[xa_format_type(fdesc.xa_format)]; + if (flags & XA_FLAG_SHARED) + bind |= PIPE_BIND_SHARED; + if (flags & XA_FLAG_RENDER_TARGET) + bind |= PIPE_BIND_RENDER_TARGET; + + if (!xa->screen->is_format_supported(xa->screen, fdesc.format, + PIPE_TEXTURE_2D, 0, bind)) + return -XA_ERR_INVAL; + + return XA_ERR_NONE; +} + +struct xa_surface * +xa_surface_create(struct xa_tracker *xa, + int width, + int height, + int depth, + enum xa_surface_type stype, + enum xa_formats xa_format, unsigned int flags) +{ + struct pipe_resource *template; + struct xa_surface *srf; + struct xa_format_descriptor fdesc; + + if (xa_format == xa_format_unknown) + fdesc = xa_get_format_stype_depth(xa, stype, depth); + else + fdesc = xa_get_pipe_format(xa_format); + + if (fdesc.xa_format == xa_format_unknown) + return NULL; + + srf = calloc(1, sizeof(*srf)); + if (!srf) + return NULL; + + template = &srf->template; + template->format = fdesc.format; + template->target = PIPE_TEXTURE_2D; + template->width0 = width; + template->height0 = height; + template->depth0 = 1; + template->array_size = 1; + template->last_level = 0; + template->bind = stype_bind[xa_format_type(fdesc.xa_format)]; + + if (flags & XA_FLAG_SHARED) + template->bind |= PIPE_BIND_SHARED; + if (flags & XA_FLAG_RENDER_TARGET) + template->bind |= PIPE_BIND_RENDER_TARGET; + + srf->tex = xa->screen->resource_create(xa->screen, template); + if (!srf->tex) + goto out_no_tex; + + srf->srf = NULL; + srf->xa = xa; + srf->flags = flags; + srf->fdesc = fdesc; + + return srf; + out_no_tex: + free(srf); + return NULL; +} + +int +xa_surface_redefine(struct xa_surface *srf, + int width, + int height, + int depth, + enum xa_surface_type stype, + enum xa_formats xa_format, + unsigned int new_flags, + int copy_contents) +{ + struct pipe_resource *template = &srf->template; + struct pipe_resource *texture; + struct pipe_box src_box; + struct xa_tracker *xa = srf->xa; + int save_width; + int save_height; + struct xa_format_descriptor fdesc; + + if (xa_format == xa_format_unknown) + fdesc = xa_get_format_stype_depth(xa, stype, depth); + else + fdesc = xa_get_pipe_format(xa_format); + + if (width == template->width0 && height == template->height0 && + template->format == fdesc.format && + xa_flags_compat(srf->flags, new_flags)) + return XA_ERR_NONE; + + template->bind = stype_bind[xa_format_type(fdesc.xa_format)]; + if (new_flags & XA_FLAG_SHARED) + template->bind |= PIPE_BIND_SHARED; + if (new_flags & XA_FLAG_RENDER_TARGET) + template->bind |= PIPE_BIND_RENDER_TARGET; + + if (copy_contents) { + if (!xa_format_type_is_color(fdesc.xa_format) || + xa_format_type(fdesc.xa_format) == xa_type_a) + return -XA_ERR_INVAL; + + if (!xa->screen->is_format_supported(xa->screen, fdesc.format, + PIPE_TEXTURE_2D, 0, + template->bind | + PIPE_BIND_RENDER_TARGET)) + return -XA_ERR_INVAL; + } + + save_width = template->width0; + save_height = template->height0; + + template->width0 = width; + template->height0 = height; + + texture = xa->screen->resource_create(xa->screen, template); + if (!texture) { + template->width0 = save_width; + template->height0 = save_height; + return -XA_ERR_NORES; + } + + pipe_surface_reference(&srf->srf, NULL); + + if (copy_contents) { + struct pipe_context *pipe = xa->default_ctx->pipe; + + u_box_origin_2d(xa_min(save_width, template->width0), + xa_min(save_height, template->height0), &src_box); + pipe->resource_copy_region(pipe, texture, + 0, 0, 0, 0, srf->tex, 0, &src_box); + pipe->flush(pipe, &xa->default_ctx->last_fence); + } + + pipe_resource_reference(&srf->tex, texture); + pipe_resource_reference(&texture, NULL); + srf->fdesc = fdesc; + srf->flags = new_flags; + + return XA_ERR_NONE; +} + +void +xa_surface_destroy(struct xa_surface *srf) +{ + pipe_surface_reference(&srf->srf, NULL); + pipe_resource_reference(&srf->tex, NULL); + free(srf); +} + +extern void +xa_tracker_version(int *major, int *minor, int *patch) +{ + *major = XA_TRACKER_VERSION_MAJOR; + *minor = XA_TRACKER_VERSION_MINOR; + *patch = XA_TRACKER_VERSION_PATCH; +} + +extern int +xa_surface_handle(struct xa_surface *srf, + uint32_t * handle, unsigned int *stride) +{ + struct winsys_handle whandle; + + struct pipe_screen *screen = srf->xa->screen; + boolean res; + + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_SHARED; + res = screen->resource_get_handle(screen, srf->tex, &whandle); + if (!res) + return -XA_ERR_INVAL; + + *handle = whandle.handle; + *stride = whandle.stride; + + return XA_ERR_NONE; +} + +enum xa_formats +xa_surface_format(const struct xa_surface *srf) +{ + return srf->fdesc.xa_format; +} diff --git a/src/gallium/state_trackers/xa/xa_tracker.h b/src/gallium/state_trackers/xa/xa_tracker.h new file mode 100644 index 00000000000..62f8a210fb6 --- /dev/null +++ b/src/gallium/state_trackers/xa/xa_tracker.h @@ -0,0 +1,178 @@ +/********************************************************** + * Copyright 2009-2011 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice 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. + * + * The format encoding idea is partially borrowed from libpixman, but it is not + * considered a "substantial part of the software", so the pixman copyright + * is left out for simplicity, and acknowledgment is instead given in this way. + * + ********************************************************* + * Authors: + * Zack Rusin <zackr-at-vmware-dot-com> + * Thomas Hellstrom <thellstrom-at-vmware-dot-com> + */ + +#ifndef _XA_TRACKER_H_ +#define _XA_TRACKER_H_ + +#include <stdint.h> + +#define XA_TRACKER_VERSION_MAJOR 0 +#define XA_TRACKER_VERSION_MINOR 4 +#define XA_TRACKER_VERSION_PATCH 0 + +#define XA_FLAG_SHARED (1 << 0) +#define XA_FLAG_RENDER_TARGET (1 << 1) + +#define XA_MAP_READ (1 << 0) +#define XA_MAP_WRITE (1 << 1) + +#define XA_ERR_NONE 0 +#define XA_ERR_NORES 1 +#define XA_ERR_INVAL 2 +#define XA_ERR_BUSY 3 + +enum xa_surface_type { + xa_type_other, + xa_type_a, + xa_type_argb, + xa_type_abgr, + xa_type_bgra, + xa_type_z, + xa_type_zs, + xa_type_sz, + xa_type_yuv_component +}; + +/* + * Note that these formats should not be assumed to be binary compatible with + * pixman formats, but with the below macros and a format type map, + * conversion should be simple. Macros for now. We might replace with + * inline functions. + */ + +#define xa_format(bpp,type,a,r,g,b) (((bpp) << 24) | \ + ((type) << 16) | \ + ((a) << 12) | \ + ((r) << 8) | \ + ((g) << 4) | \ + ((b))) +/* + * Non-RGBA one- and two component formats. + */ + +#define xa_format_c(bpp,type,c1,c2) (((bpp) << 24) | \ + ((type) << 16) | \ + ((c1) << 8) | \ + ((c2))) +#define xa_format_bpp(f) (((f) >> 24) ) +#define xa_format_type(f) (((f) >> 16) & 0xff) +#define xa_format_a(f) (((f) >> 12) & 0x0f) +#define xa_format_r(f) (((f) >> 8) & 0x0f) +#define xa_format_g(f) (((f) >> 4) & 0x0f) +#define xa_format_b(f) (((f) ) & 0x0f) +#define xa_format_rgb(f) (((f) ) & 0xfff) +#define xa_format_c1(f) (((f) >> 8 ) & 0xff) +#define xa_format_c2(f) (((f) ) & 0xff) +#define xa_format_argb_depth(f) (xa_format_a(f) + \ + xa_format_r(f) + \ + xa_format_g(f) + \ + xa_format_b(f)) +#define xa_format_c_depth(f) (xa_format_c1(f) + \ + xa_format_c2(f)) + +static inline int +xa_format_type_is_color(uint32_t xa_format) +{ + return (xa_format_type(xa_format) < xa_type_z); +} + +static inline unsigned int +xa_format_depth(uint32_t xa_format) +{ + return ((xa_format_type_is_color(xa_format)) ? + xa_format_argb_depth(xa_format) : xa_format_c_depth(xa_format)); +} + +enum xa_formats { + xa_format_unknown = 0, + xa_format_a8 = xa_format(8, xa_type_a, 8, 0, 0, 0), + + xa_format_a8r8g8b8 = xa_format(32, xa_type_argb, 8, 8, 8, 8), + xa_format_x8r8g8b8 = xa_format(32, xa_type_argb, 0, 8, 8, 8), + xa_format_r5g6b5 = xa_format(16, xa_type_argb, 0, 5, 6, 5), + xa_format_x1r5g5b5 = xa_format(16, xa_type_argb, 0, 5, 5, 5), + + xa_format_z16 = xa_format_c(16, xa_type_z, 16, 0), + xa_format_z32 = xa_format_c(32, xa_type_z, 32, 0), + xa_format_z24 = xa_format_c(32, xa_type_z, 24, 0), + + xa_format_x8z24 = xa_format_c(32, xa_type_sz, 24, 0), + xa_format_s8z24 = xa_format_c(32, xa_type_sz, 24, 8), + xa_format_z24x8 = xa_format_c(32, xa_type_zs, 24, 0), + xa_format_z24s8 = xa_format_c(32, xa_type_zs, 24, 8), + + xa_format_yuv8 = xa_format_c(8, xa_type_yuv_component, 8, 0) +}; + +struct xa_tracker; +struct xa_surface; + +struct xa_box { + uint16_t x1, y1, x2, y2; +}; + +extern void xa_tracker_version(int *major, int *minor, int *patch); + +extern struct xa_tracker *xa_tracker_create(int drm_fd); + +extern void xa_tracker_destroy(struct xa_tracker *xa); + +extern int xa_format_check_supported(struct xa_tracker *xa, + enum xa_formats xa_format, + unsigned int flags); + +extern struct xa_surface *xa_surface_create(struct xa_tracker *xa, + int width, + int height, + int depth, + enum xa_surface_type stype, + enum xa_formats pform, + unsigned int flags); + +enum xa_formats xa_surface_format(const struct xa_surface *srf); + +extern void xa_surface_destroy(struct xa_surface *srf); + +extern int xa_surface_redefine(struct xa_surface *srf, + int width, + int height, + int depth, + enum xa_surface_type stype, + enum xa_formats rgb_format, + unsigned int new_flags, + int copy_contents); + +extern int xa_surface_handle(struct xa_surface *srf, + uint32_t * handle, unsigned int *byte_stride); + +#endif diff --git a/src/gallium/state_trackers/xa/xa_yuv.c b/src/gallium/state_trackers/xa/xa_yuv.c new file mode 100644 index 00000000000..66cbc5393b5 --- /dev/null +++ b/src/gallium/state_trackers/xa/xa_yuv.c @@ -0,0 +1,179 @@ +/********************************************************** + * Copyright 2009-2011 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice 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: + * Zack Rusin <zackr-at-vmware-dot-com> + * Thomas Hellstrom <thellstrom-at-vmware-dot-com> + */ + +#include "xa_context.h" +#include "xa_priv.h" +#include "util/u_inlines.h" +#include "util/u_sampler.h" +#include "util/u_surface.h" +#include "cso_cache/cso_context.h" + +static void +xa_yuv_bind_blend_state(struct xa_context *r) +{ + struct pipe_blend_state blend; + + memset(&blend, 0, sizeof(struct pipe_blend_state)); + blend.rt[0].blend_enable = 0; + blend.rt[0].colormask = PIPE_MASK_RGBA; + + /* porter&duff src */ + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + + cso_set_blend(r->cso, &blend); +} + +static void +xa_yuv_bind_shaders(struct xa_context *r) +{ + unsigned vs_traits = 0, fs_traits = 0; + struct xa_shader shader; + + vs_traits |= VS_YUV; + fs_traits |= FS_YUV; + + shader = xa_shaders_get(r->shaders, vs_traits, fs_traits); + cso_set_vertex_shader_handle(r->cso, shader.vs); + cso_set_fragment_shader_handle(r->cso, shader.fs); +} + +static void +xa_yuv_bind_samplers(struct xa_context *r, struct xa_surface *yuv[]) +{ + struct pipe_sampler_state *samplers[3]; + struct pipe_sampler_state sampler; + struct pipe_sampler_view *views[3]; + struct pipe_sampler_view view_templ; + unsigned int i; + + memset(&sampler, 0, sizeof(struct pipe_sampler_state)); + + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP; + sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; + sampler.normalized_coords = 1; + + for (i = 0; i < 3; ++i) { + samplers[i] = &sampler; + if (!yuv[i]->view) { + u_sampler_view_default_template(&view_templ, + yuv[i]->tex, yuv[i]->tex->format); + + yuv[i]->view = r->pipe->create_sampler_view(r->pipe, + yuv[i]->tex, + &view_templ); + } + views[i] = yuv[i]->view; + } + + cso_set_samplers(r->cso, 3, (const struct pipe_sampler_state **)samplers); + cso_set_fragment_sampler_views(r->cso, 3, views); +} + +static void +xa_yuv_fs_constants(struct xa_context *r, const float conversion_matrix[]) +{ + const int param_bytes = 12 * sizeof(float); + + renderer_set_constants(r, PIPE_SHADER_FRAGMENT, + conversion_matrix, param_bytes); +} + +static void +xa_yuv_destroy_sampler_views(struct xa_surface *yuv[]) +{ + unsigned int i; + + for (i = 0; i < 3; ++i) { + pipe_sampler_view_reference(&yuv[i]->view, NULL); + } +} + +extern int +xa_yuv_planar_blit(struct xa_context *r, + int src_x, + int src_y, + int src_w, + int src_h, + int dst_x, + int dst_y, + int dst_w, + int dst_h, + struct xa_box *box, + unsigned int num_boxes, + const float conversion_matrix[], + struct xa_surface *dst, struct xa_surface *yuv[]) +{ + float scale_x; + float scale_y; + struct pipe_surface srf_templ; + + if (dst_w == 0 || dst_h == 0) + return XA_ERR_NONE; + + memset(&srf_templ, 0, sizeof(srf_templ)); + u_surface_default_template(&srf_templ, dst->tex, PIPE_BIND_RENDER_TARGET); + dst->srf = r->pipe->create_surface(r->pipe, dst->tex, &srf_templ); + if (!dst->srf) + return -XA_ERR_NORES; + + renderer_bind_destination(r, dst->srf, dst->srf->width, dst->srf->height); + xa_yuv_bind_blend_state(r); + xa_yuv_bind_shaders(r); + xa_yuv_bind_samplers(r, yuv); + xa_yuv_fs_constants(r, conversion_matrix); + + scale_x = (float)src_w / (float)dst_w; + scale_y = (float)src_h / (float)dst_h; + + while (num_boxes--) { + int x = box->x1; + int y = box->y1; + int w = box->x2 - box->x1; + int h = box->y2 - box->y1; + + renderer_draw_yuv(r, + (float)src_x + scale_x * (x - dst_x), + (float)src_y + scale_y * (y - dst_y), + scale_x * w, scale_y * h, x, y, w, h, yuv); + box++; + } + + r->pipe->flush(r->pipe, &r->last_fence); + + xa_yuv_destroy_sampler_views(yuv); + pipe_surface_reference(&dst->srf, NULL); + + return XA_ERR_NONE; +} diff --git a/src/gallium/state_trackers/xorg/SConscript b/src/gallium/state_trackers/xorg/SConscript index 19315694b7c..4ea4ec4ee8b 100644 --- a/src/gallium/state_trackers/xorg/SConscript +++ b/src/gallium/state_trackers/xorg/SConscript @@ -9,10 +9,11 @@ env.Append(CPPPATH = [ '#/src/mesa', ]) -env.ParseConfig('pkg-config --cflags --libs libdrm xorg-server') +env.PkgUseModules(['DRM', 'XORG']) -if env['kms']: +if env['HAVE_KMS']: env.Append(CPPDEFINES = ['HAVE_LIBKMS']) + env.PkgUseModules(['KMS']) conf = env.Configure() diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c index d4dc84a122b..f696b72e1e3 100644 --- a/src/gallium/state_trackers/xorg/xorg_composite.c +++ b/src/gallium/state_trackers/xorg/xorg_composite.c @@ -237,7 +237,7 @@ picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, bool boolean swizzle = FALSE; unsigned ret = 0; - if (pSrc->picture_format == pSrcPicture->format) { + if (pSrc && pSrc->picture_format == pSrcPicture->format) { if (pSrc->picture_format == PICT_a8) { if (mask) return FS_MASK_LUMINANCE; @@ -252,7 +252,7 @@ picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, bool return 0; } - if (pSrc->picture_format != PICT_a8r8g8b8) { + if (pSrc && pSrc->picture_format != PICT_a8r8g8b8) { assert(!"can not handle formats"); return 0; } @@ -355,7 +355,7 @@ bind_samplers(struct exa_context *exa, int op, struct exa_pixmap_priv *pMask, struct exa_pixmap_priv *pDst) { - struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS] = {0}; struct pipe_sampler_state src_sampler, mask_sampler; struct pipe_sampler_view view_templ; struct pipe_sampler_view *src_view; diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index 0499ed1ea0b..22e61cf7081 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -122,6 +122,7 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, drm_mode.hskew = mode->HSkew; drm_mode.vscan = mode->VScan; drm_mode.vrefresh = mode->VRefresh; + drm_mode.type = 0; if (!mode->name) xf86SetModeDefaultName(mode); strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN - 1); diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c index 234574b968e..af4992fc2ed 100644 --- a/src/gallium/state_trackers/xorg/xorg_xv.c +++ b/src/gallium/state_trackers/xorg/xorg_xv.c @@ -466,7 +466,6 @@ bind_samplers(struct xorg_xv_port_priv *port) { struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS]; struct pipe_sampler_state sampler; - struct pipe_resource **dst = port->yuv[port->current_set]; struct pipe_sampler_view **dst_views = port->yuv_views[port->current_set]; memset(&sampler, 0, sizeof(struct pipe_sampler_state)); diff --git a/src/gallium/targets/Makefile.xorg b/src/gallium/targets/Makefile.xorg index 47040bb14c8..6fad7109f29 100644 --- a/src/gallium/targets/Makefile.xorg +++ b/src/gallium/targets/Makefile.xorg @@ -41,7 +41,7 @@ endif default: depend $(TOP)/$(LIB_DIR)/gallium $(LIBNAME) $(LIBNAME_STAGING) -$(LIBNAME): $(OBJECTS) Makefile ../Makefile.xorg $(LIBS) $(DRIVER_PIPES) +$(LIBNAME): $(OBJECTS) Makefile ../Makefile.xorg $(LIBS) $(DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $(MKLIB) -linker '$(CC)' -noprefix -o $@ $(LDFLAGS) $(OBJECTS) $(DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $(DRIVER_LINKS) depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) $(GENERATED_SOURCES) diff --git a/src/gallium/targets/SConscript.dri b/src/gallium/targets/SConscript.dri index 101863a6848..5ad17f8b3ae 100644 --- a/src/gallium/targets/SConscript.dri +++ b/src/gallium/targets/SConscript.dri @@ -29,7 +29,7 @@ drienv.Replace(CPPPATH = [ '#src/egl/drivers/dri', ]) -drienv.ParseConfig('pkg-config --cflags --libs libdrm') +drienv.PkgUseModules('DRM') dri_common_utils = drienv.SharedObject( target = 'utils.o', diff --git a/src/gallium/targets/dri-i915/SConscript b/src/gallium/targets/dri-i915/SConscript index ab60013830e..b3bd3dd5826 100644 --- a/src/gallium/targets/dri-i915/SConscript +++ b/src/gallium/targets/dri-i915/SConscript @@ -2,7 +2,7 @@ Import('*') env = drienv.Clone() -env.ParseConfig('pkg-config --cflags --libs libdrm_intel') +env.PkgUseModules('DRM_INTEL') env.Append(CPPDEFINES = ['GALLIUM_RBUG', 'GALLIUM_TRACE', 'GALLIUM_GALAHAD']) @@ -26,4 +26,4 @@ module = env.LoadableModule( SHLIBPREFIX = '', ) -env.Alias('dri-i915', module)
\ No newline at end of file +env.Alias('dri-i915', module) diff --git a/src/gallium/targets/dri-i965/SConscript b/src/gallium/targets/dri-i965/SConscript index 669f70d6b8d..01a458db228 100644 --- a/src/gallium/targets/dri-i965/SConscript +++ b/src/gallium/targets/dri-i965/SConscript @@ -2,7 +2,7 @@ Import('*') env = drienv.Clone() -env.ParseConfig('pkg-config --cflags --libs libdrm_intel') +env.PkgUseModules('DRM_INTEL') env.Append(CPPDEFINES = [ 'GALLIUM_SOFTPIPE', @@ -29,4 +29,4 @@ module = env.LoadableModule( SHLIBPREFIX = '', ) -env.Alias('dri-i965', module)
\ No newline at end of file +env.Alias('dri-i965', module) diff --git a/src/gallium/targets/dri-r300/Makefile b/src/gallium/targets/dri-r300/Makefile index cc77a4bc20d..a1bb753f859 100644 --- a/src/gallium/targets/dri-r300/Makefile +++ b/src/gallium/targets/dri-r300/Makefile @@ -6,7 +6,6 @@ LIBNAME = r300_dri.so PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \ $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/galahad/libgalahad.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/rbug/librbug.a \ diff --git a/src/gallium/targets/dri-r600/Makefile b/src/gallium/targets/dri-r600/Makefile index c8fae2d8585..0c4de203d35 100644 --- a/src/gallium/targets/dri-r600/Makefile +++ b/src/gallium/targets/dri-r600/Makefile @@ -7,7 +7,6 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/r600/libr600.a \ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \ $(TOP)/src/gallium/winsys/r600/drm/libr600winsys.a \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/noop/libnoop.a diff --git a/src/gallium/targets/dri-r600/target.c b/src/gallium/targets/dri-r600/target.c index 2fe345402de..8753e2bab17 100644 --- a/src/gallium/targets/dri-r600/target.c +++ b/src/gallium/targets/dri-r600/target.c @@ -1,5 +1,5 @@ #include "state_tracker/drm_driver.h" -#include "target-helpers/inline_noop_helper.h" +#include "target-helpers/inline_debug_helper.h" #include "r600/drm/r600_drm_public.h" #include "r600/r600_public.h" diff --git a/src/gallium/targets/dri-swrast/SConscript b/src/gallium/targets/dri-swrast/SConscript index b67483800e4..33acc614e76 100644 --- a/src/gallium/targets/dri-swrast/SConscript +++ b/src/gallium/targets/dri-swrast/SConscript @@ -39,4 +39,6 @@ module = env.LoadableModule( SHLIBPREFIX = '', ) +module = env.InstallSharedLibrary(module) + env.Alias('dri-swrast', module) diff --git a/src/gallium/targets/dri-vmwgfx/target.c b/src/gallium/targets/dri-vmwgfx/target.c index 1362851d6be..da50b8b8bda 100644 --- a/src/gallium/targets/dri-vmwgfx/target.c +++ b/src/gallium/targets/dri-vmwgfx/target.c @@ -19,6 +19,7 @@ create_screen(int fd) if (!screen) return NULL; + vmw_winsys_screen_set_throttling(screen, 10); screen = sw_screen_wrap(screen); screen = debug_screen_wrap(screen); diff --git a/src/gallium/targets/egl-static/Makefile b/src/gallium/targets/egl-static/Makefile new file mode 100644 index 00000000000..832d7ba438f --- /dev/null +++ b/src/gallium/targets/egl-static/Makefile @@ -0,0 +1,201 @@ +# src/gallium/targets/egl-static/Makefile +# +# This is Makefile for egl_gallium.so. It is static in that all state trackers +# and pipe drivers are linked statically when possible. +# +# The following variables are examined +# +# EGL_PLATFORMS - platforms to support +# EGL_CLIENT_APIS - state trackers to support +# GALLIUM_WINSYS_DIRS - pipe drivers to support +# SHARED_GLAPI - st/mesa can be statically linked or not +# + +TOP = ../../../.. +include $(TOP)/configs/current + +OUTPUTS := egl_gallium + +egl_CPPFLAGS := \ + -I$(TOP)/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/winsys +egl_LIBS := \ + $(TOP)/src/gallium/drivers/identity/libidentity.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ + $(GALLIUM_AUXILIARIES) +egl_SYS := + +egl_SOURCES := \ + egl.c \ + egl_pipe.c \ + egl_st.c + +egl_OBJECTS := $(egl_SOURCES:%.c=%.o) + +# st/egl +egl_CPPFLAGS += \ + -I$(TOP)/src/gallium/state_trackers/egl \ + -I$(TOP)/src/egl/main \ + -D_EGL_MAIN=_eglMain +egl_LIBS += $(TOP)/src/gallium/state_trackers/egl/libegl.a +egl_SYS += $(LIBUDEV_LIBS) $(DLOPEN_LIBS) -lEGL -lm + +# EGL platforms +ifneq ($(findstring x11, $(EGL_PLATFORMS)),) +egl_CPPFLAGS += $(LIBDRM_CFLAGS) +egl_LIBS += $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a +egl_SYS += -lX11 -lXext -lXfixes $(LIBDRM_LIB) +endif +ifneq ($(findstring wayland, $(EGL_PLATFORMS)),) +egl_CPPFLAGS += $(LIBDRM_CFLAGS) +egl_LIBS += $(TOP)/src/gallium/winsys/sw/wayland/libws_wayland.a +egl_LIBS += $(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a +egl_SYS += $(LIBDRM_LIB) $(WAYLAND_LIBS) +endif +ifneq ($(findstring drm, $(EGL_PLATFORMS)),) +egl_CPPFLAGS += $(LIBDRM_CFLAGS) +egl_SYS += $(LIBDRM_LIB) -lgbm +endif +ifneq ($(findstring fbdev, $(EGL_PLATFORMS)),) +egl_LIBS += $(TOP)/src/gallium/winsys/sw/fbdev/libfbdev.a +endif + +# st/mesa +ifneq ($(filter $(GL_LIB), $(EGL_CLIENT_APIS)),) +egl_CPPFLAGS += -I$(TOP)/src/mesa $(API_DEFINES) +# make st/mesa built-in when there is a single glapi provider +ifeq ($(SHARED_GLAPI),1) +egl_LIBS += $(TOP)/src/mesa/libmesagallium.a +egl_SYS += -lm -lpthread $(DLOPEN_LIBS) -l$(GLAPI_LIB) +else +egl_CPPFLAGS += -D_EGL_EXTERNAL_GL=1 +OUTPUTS += st_GL +endif # SHARED_GLAPI +endif + +# st/vega +ifneq ($(filter $(VG_LIB), $(EGL_CLIENT_APIS)),) +egl_CPPFLAGS += -I$(TOP)/src/gallium/state_trackers/vega -DFEATURE_VG=1 +egl_LIBS += $(TOP)/src/gallium/state_trackers/vega/libvega.a +egl_SYS += -lm -l$(VG_LIB) +endif + +# i915 +ifneq ($(findstring i915/drm,$(GALLIUM_WINSYS_DIRS)),) +egl_CPPFLAGS += -D_EGL_PIPE_I915=1 +egl_LIBS += \ + $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \ + $(TOP)/src/gallium/drivers/i915/libi915.a +egl_SYS += -ldrm_intel +endif + +# i965 +ifneq ($(findstring i965/drm,$(GALLIUM_WINSYS_DIRS)),) +egl_CPPFLAGS += -D_EGL_PIPE_I995=1 +egl_LIBS += \ + $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \ + $(TOP)/src/gallium/drivers/i965/libi965.a \ + $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a +egl_SYS += -ldrm_intel +endif + +# nouveau +ifneq ($(findstring nouveau/drm,$(GALLIUM_WINSYS_DIRS)),) +egl_CPPFLAGS += -D_EGL_PIPE_NOUVEAU=1 +egl_LIBS += \ + $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \ + $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \ + $(TOP)/src/gallium/drivers/nv50/libnv50.a \ + $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \ + $(TOP)/src/gallium/drivers/nouveau/libnouveau.a +egl_SYS += -ldrm_nouveau +endif + +# r300 +ifneq ($(findstring radeon/drm,$(GALLIUM_WINSYS_DIRS)),) +egl_CPPFLAGS += -D_EGL_PIPE_R300=1 +egl_LIBS += \ + $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \ + $(TOP)/src/gallium/drivers/r300/libr300.a +egl_SYS += -ldrm_radeon +endif + +# r600 +ifneq ($(findstring r600/drm,$(GALLIUM_WINSYS_DIRS)),) +egl_CPPFLAGS += -D_EGL_PIPE_R600=1 +egl_LIBS += \ + $(TOP)/src/gallium/winsys/r600/drm/libr600winsys.a \ + $(TOP)/src/gallium/drivers/r600/libr600.a +egl_SYS += -ldrm_radeon +endif + +# vmwgfx +ifneq ($(findstring svga/drm,$(GALLIUM_WINSYS_DIRS)),) +egl_CPPFLAGS += -D_EGL_PIPE_VMWGFX=1 +egl_LIBS += \ + $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \ + $(TOP)/src/gallium/drivers/svga/libsvga.a +endif + +# swrast +egl_CPPFLAGS += -DGALLIUM_SOFTPIPE -DGALLIUM_RBUG -DGALLIUM_TRACE +egl_LIBS += $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a +egl_SYS += -lm + +# sort to remove duplicates +egl_CPPFLAGS := $(sort $(egl_CPPFLAGS)) +egl_LIBS := $(sort $(egl_LIBS)) +egl_SYS := $(sort $(egl_SYS)) + +# st_GL, built only when shared glapi is not enabled +st_GL_CPPFLAGS := -I $(TOP)/src/mesa -I$(TOP)/src/gallium/include +st_GL_LIBS := $(TOP)/src/mesa/libmesagallium.a $(GALLIUM_AUXILIARIES) +st_GL_SYS := -lm -lpthread $(DLOPEN_LIBS) + +# LLVM +ifeq ($(MESA_LLVM),1) +egl_CPPFLAGS += -DGALLIUM_LLVMPIPE +egl_LIBS += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a +egl_SYS += $(LLVM_LIBS) +LDFLAGS += $(LLVM_LDFLAGS) + +st_GL_SYS += $(LLVM_LIBS) +endif + +OUTPUT_PATH := $(TOP)/$(LIB_DIR)/egl +OUTPUTS := $(addprefix $(OUTPUT_PATH)/, $(addsuffix .so, $(OUTPUTS))) + +default: $(OUTPUTS) + +$(OUTPUT_PATH)/egl_gallium.so: $(egl_OBJECTS) $(egl_LIBS) + $(MKLIB) -o $(notdir $@) -noprefix -linker '$(CXX)' \ + -ldflags '-L$(TOP)/$(LIB_DIR) -Wl,--no-undefined $(LDFLAGS)' \ + -cplusplus -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) \ + $(egl_OBJECTS) -Wl,--start-group $(egl_LIBS) -Wl,--end-group \ + $(egl_SYS) + +$(OUTPUT_PATH)/st_GL.so: st_GL.o $(st_GL_LIBS) + $(MKLIB) -o $(notdir $@) -noprefix -linker '$(CXX)' \ + -ldflags '-L$(TOP)/$(LIB_DIR) $(LDFLAGS)' \ + -cplusplus -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) \ + $< -Wl,--start-group $(st_GL_LIBS) -Wl,--end-group \ + $(st_GL_SYS) + +$(egl_OBJECTS): %.o: %.c + $(CC) -c -o $@ $< $(egl_CPPFLAGS) $(DEFINES) $(CFLAGS) + +st_GL.o: st_GL.c + $(CC) -c -o $@ $< $(st_GL_CPPFLAGS) $(DEFINES) $(CFLAGS) + +install: $(OUTPUTS) + $(INSTALL) -d $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR) + for out in $(OUTPUTS); do \ + $(MINSTALL) -m 755 "$$out" $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR); \ + done + +clean: + rm -f *.o diff --git a/src/gallium/targets/egl-static/SConscript b/src/gallium/targets/egl-static/SConscript index cbd98cc416a..dfd05437231 100644 --- a/src/gallium/targets/egl-static/SConscript +++ b/src/gallium/targets/egl-static/SConscript @@ -79,21 +79,17 @@ if True: openvg_name = 'OpenVG' if env['platform'] != 'windows' else 'libOpenVG' env.Prepend(LIBS = [openvg_name, st_vega]) -if env['x11']: +if env['HAVE_X11']: env.Prepend(LIBS = [ ws_xlib, - env['X11_LIBS'], ]) - -if env['dri']: - env.ParseConfig('pkg-config --cflags --libs xfixes') + env.PkgUseModules('X11') # pipe drivers -if env['drm']: - env.ParseConfig('pkg-config --cflags --libs libdrm') +if env['HAVE_DRM']: + env.PkgUseModules('DRM') - if env['drm_intel']: - env.ParseConfig('pkg-config --cflags --libs libdrm_intel') + if env['HAVE_DRM_INTEL']: env.Append(CPPDEFINES = ['_EGL_PIPE_I915', '_EGL_PIPE_I965']) env.Prepend(LIBS = [ i915drm, @@ -103,7 +99,7 @@ if env['drm']: ws_wrapper, ]) - if env['drm_radeon']: + if env['HAVE_DRM_RADEON']: env.Append(CPPDEFINES = ['_EGL_PIPE_R300', '_EGL_PIPE_R600']) env.Prepend(LIBS = [ radeonwinsys, diff --git a/src/gallium/targets/egl-static/egl.c b/src/gallium/targets/egl-static/egl.c index e617ff50208..568f5498dd4 100644 --- a/src/gallium/targets/egl-static/egl.c +++ b/src/gallium/targets/egl-static/egl.c @@ -28,6 +28,15 @@ #include "common/egl_g3d_loader.h" #include "egldriver.h" +#include "egllog.h" + +#ifdef HAVE_LIBUDEV +#include <stdio.h> /* for sscanf */ +#include <libudev.h> +#endif + +#define DRIVER_MAP_GALLIUM_ONLY +#include "pci_ids/pci_id_driver_map.h" #include "egl_pipe.h" #include "egl_st.h" @@ -52,15 +61,108 @@ get_st_api(enum st_api_type api) return stmod->stapi; } -static struct st_api * -guess_gl_api(enum st_profile_type profile) +#ifdef HAVE_LIBUDEV + +static boolean +drm_fd_get_pci_id(int fd, int *vendor_id, int *chip_id) { - return get_st_api(ST_API_OPENGL); + struct udev *udev = NULL; + struct udev_device *device = NULL, *parent; + struct stat buf; + const char *pci_id; + + *chip_id = -1; + + udev = udev_new(); + if (fstat(fd, &buf) < 0) { + _eglLog(_EGL_WARNING, "failed to stat fd %d", fd); + goto out; + } + + device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev); + if (device == NULL) { + _eglLog(_EGL_WARNING, + "could not create udev device for fd %d", fd); + goto out; + } + + parent = udev_device_get_parent(device); + if (parent == NULL) { + _eglLog(_EGL_WARNING, "could not get parent device"); + goto out; + } + + pci_id = udev_device_get_property_value(parent, "PCI_ID"); + if (pci_id == NULL || + sscanf(pci_id, "%x:%x", vendor_id, chip_id) != 2) { + _eglLog(_EGL_WARNING, "malformed or no PCI ID"); + *chip_id = -1; + goto out; + } + +out: + if (device) + udev_device_unref(device); + if (udev) + udev_unref(udev); + + return (*chip_id >= 0); +} + +#else + +static boolean +drm_fd_get_pci_id(int fd, int *vendor_id, int *chip_id) +{ + return FALSE; +} + +#endif /* HAVE_LIBUDEV */ + +static const char * +drm_fd_get_screen_name(int fd) +{ + int vendor_id, chip_id; + int idx, i; + + if (!drm_fd_get_pci_id(fd, &vendor_id, &chip_id)) { + _eglLog(_EGL_WARNING, "failed to get driver name for fd %d", fd); + return NULL; + } + + for (idx = 0; driver_map[idx].driver; idx++) { + if (vendor_id != driver_map[idx].vendor_id) + continue; + + /* done if no chip id */ + if (driver_map[idx].num_chips_ids == -1) + break; + + for (i = 0; i < driver_map[idx].num_chips_ids; i++) { + if (driver_map[idx].chip_ids[i] == chip_id) + break; + } + /* matched! */ + if (i < driver_map[idx].num_chips_ids) + break; + } + + _eglLog((driver_map[idx].driver) ? _EGL_INFO : _EGL_WARNING, + "pci id for fd %d: %04x:%04x, driver %s", + fd, vendor_id, chip_id, driver_map[idx].driver); + + return driver_map[idx].driver; } static struct pipe_screen * create_drm_screen(const char *name, int fd) { + if (!name) { + name = drm_fd_get_screen_name(fd); + if (!name) + return NULL; + } + return egl_pipe_create_drm_screen(name, fd); } @@ -79,7 +181,6 @@ loader_init(void) egl_g3d_loader.profile_masks[i] = egl_st_get_profile_mask(i); egl_g3d_loader.get_st_api = get_st_api; - egl_g3d_loader.guess_gl_api = guess_gl_api; egl_g3d_loader.create_drm_screen = create_drm_screen; egl_g3d_loader.create_sw_screen = create_sw_screen; @@ -95,7 +196,7 @@ loader_fini(void) struct st_module *stmod = &st_modules[i]; if (stmod->stapi) { - stmod->stapi->destroy(stmod->stapi); + egl_st_destroy_api(stmod->stapi); stmod->stapi = NULL; } stmod->initialized = FALSE; diff --git a/src/gallium/targets/egl-static/egl_st.c b/src/gallium/targets/egl-static/egl_st.c index 3db52621def..81d7bb47568 100644 --- a/src/gallium/targets/egl-static/egl_st.c +++ b/src/gallium/targets/egl-static/egl_st.c @@ -29,52 +29,143 @@ #include "state_tracker/st_api.h" #include "egl_st.h" -/* for st/mesa */ +#if FEATURE_GL || FEATURE_ES1 || FEATURE_ES2 #include "state_tracker/st_gl_api.h" -/* for st/vega */ +#endif + +#if FEATURE_VG #include "vg_api.h" +#endif + +#if _EGL_EXTERNAL_GL + +#include "util/u_string.h" +#include "util/u_dl.h" +#include "egldriver.h" +#include "egllog.h" + +static struct util_dl_library *egl_st_gl_lib; + +static EGLBoolean +dlopen_gl_lib_cb(const char *dir, size_t len, void *callback_data) +{ + const char *name = (const char *) callback_data; + char path[1024]; + int ret; + + if (len) { + ret = util_snprintf(path, sizeof(path), "%.*s/%s" UTIL_DL_EXT, + len, dir, name); + } + else { + ret = util_snprintf(path, sizeof(path), "%s" UTIL_DL_EXT, name); + } + + if (ret > 0 && ret < sizeof(path)) { + egl_st_gl_lib = util_dl_open(path); + if (egl_st_gl_lib) + _eglLog(_EGL_DEBUG, "loaded %s", path); + } + + return !egl_st_gl_lib; +} static struct st_api * -st_GL_create_api(void) +load_gl(const char *name, const char *procname) { -#if FEATURE_GL || FEATURE_ES1 || FEATURE_ES2 - return st_gl_api_create(); -#else - return NULL; -#endif + struct st_api *(*create_api)(void); + struct st_api *stapi = NULL; + + _eglSearchPathForEach(dlopen_gl_lib_cb, (void *) name); + if (!egl_st_gl_lib) + return NULL; + + create_api = (struct st_api *(*)(void)) + util_dl_get_proc_address(egl_st_gl_lib, procname); + if (create_api) + stapi = create_api(); + + if (!stapi) { + util_dl_close(egl_st_gl_lib); + egl_st_gl_lib = NULL; + } + + return stapi; } static struct st_api * -st_OpenVG_create_api(void) +egl_st_load_gl(void) { -#if FEATURE_VG - return (struct st_api *) vg_api_get(); -#else - return NULL; -#endif + const char module[] = "st_GL"; + const char symbol[] = "st_api_create_OpenGL"; + struct st_api *stapi; + + stapi = load_gl(module, symbol); + + /* try again with libglapi.so loaded */ + if (!stapi) { + struct util_dl_library *glapi = util_dl_open("libglapi" UTIL_DL_EXT); + + if (glapi) { + _eglLog(_EGL_DEBUG, "retry with libglapi" UTIL_DL_EXT " loaded"); + + stapi = load_gl(module, symbol); + util_dl_close(glapi); + } + } + if (!stapi) + _eglLog(_EGL_WARNING, "unable to load %s" UTIL_DL_EXT, module); + + return stapi; } +#endif /* _EGL_EXTERNAL_GL */ + struct st_api * egl_st_create_api(enum st_api_type api) { - struct st_api *stapi; + struct st_api *stapi = NULL; switch (api) { case ST_API_OPENGL: - stapi = st_GL_create_api(); +#if FEATURE_GL || FEATURE_ES1 || FEATURE_ES2 +#if _EGL_EXTERNAL_GL + stapi = egl_st_load_gl(); +#else + stapi = st_gl_api_create(); +#endif +#endif break; case ST_API_OPENVG: - stapi = st_OpenVG_create_api(); +#if FEATURE_VG + stapi = (struct st_api *) vg_api_get(); +#endif break; default: assert(!"Unknown API Type\n"); - stapi = NULL; break; } return stapi; } +void +egl_st_destroy_api(struct st_api *stapi) +{ +#if _EGL_EXTERNAL_GL + boolean is_gl = (stapi->api == ST_API_OPENGL); + + stapi->destroy(stapi); + + if (is_gl) { + util_dl_close(egl_st_gl_lib); + egl_st_gl_lib = NULL; + } +#else + stapi->destroy(stapi); +#endif +} + uint egl_st_get_profile_mask(enum st_api_type api) { diff --git a/src/gallium/targets/egl-static/egl_st.h b/src/gallium/targets/egl-static/egl_st.h index ba82faf0b0e..7a3773c6ba2 100644 --- a/src/gallium/targets/egl-static/egl_st.h +++ b/src/gallium/targets/egl-static/egl_st.h @@ -34,6 +34,9 @@ struct st_api * egl_st_create_api(enum st_api_type api); +void +egl_st_destroy_api(struct st_api *stapi); + uint egl_st_get_profile_mask(enum st_api_type api); diff --git a/src/gallium/targets/egl/egl.h b/src/gallium/targets/egl-static/st_GL.c index 5fd06785407..3f4b7a09fa4 100644 --- a/src/gallium/targets/egl/egl.h +++ b/src/gallium/targets/egl-static/st_GL.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 7.9 + * Version: 7.10 * - * Copyright (C) 2010 LunarG Inc. + * Copyright (C) 2011 LunarG Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -25,20 +25,14 @@ * Authors: * Chia-I Wu <[email protected]> */ - -#ifndef _EGL_H_ -#define _EGL_H_ - +#include "state_tracker/st_gl_api.h" #include "pipe/p_compiler.h" -#include "state_tracker/st_api.h" - -#define ST_CREATE_OPENGL_SYMBOL "st_api_create_OpenGL" -#define ST_CREATE_OPENVG_SYMBOL "st_api_create_OpenVG" PUBLIC struct st_api * st_api_create_OpenGL(void); -PUBLIC struct st_api * -st_api_create_OpenVG(void); - -#endif /* _EGL_H_ */ +struct st_api * +st_api_create_OpenGL(void) +{ + return st_gl_api_create(); +} diff --git a/src/gallium/targets/egl/Makefile b/src/gallium/targets/egl/Makefile deleted file mode 100644 index dd566bd9a06..00000000000 --- a/src/gallium/targets/egl/Makefile +++ /dev/null @@ -1,242 +0,0 @@ -# src/gallium/targets/egl/Makefile -# -# This is the Makefile for EGL Gallium driver package. The package consists of -# -# egl_gallium.so - EGL driver -# pipe_<HW>.so - pipe drivers -# st_<API>.so - client API state trackers -# -# The following variables are examined -# -# EGL_PLATFORMS - platforms to support -# GALLIUM_WINSYS_DIRS - pipe drivers to support -# EGL_CLIENT_APIS - state trackers to support -# - -TOP = ../../../.. -include $(TOP)/configs/current - -ST_PREFIX := st_ -PIPE_PREFIX := pipe_ - -common_CPPFLAGS := \ - -I$(TOP)/include \ - -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/winsys \ - $(LIBDRM_CFLAGS) - -common_SYS := -common_LIBS := \ - $(TOP)/src/gallium/drivers/identity/libidentity.a \ - $(TOP)/src/gallium/drivers/trace/libtrace.a \ - $(TOP)/src/gallium/drivers/rbug/librbug.a \ - $(GALLIUM_AUXILIARIES) - -# EGL driver -egl_CPPFLAGS := \ - -I$(TOP)/src/gallium/state_trackers/egl \ - -I$(TOP)/src/egl/main \ - -DPIPE_PREFIX=\"$(PIPE_PREFIX)\" -DST_PREFIX=\"$(ST_PREFIX)\" -egl_SYS := -lm $(DLOPEN_LIBS) -lEGL -egl_LIBS := $(TOP)/src/gallium/state_trackers/egl/libegl.a - -ifneq ($(findstring x11, $(EGL_PLATFORMS)),) -egl_SYS += -lX11 -lXext -lXfixes $(LIBDRM_LIB) -egl_LIBS += $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a -endif -ifneq ($(findstring wayland, $(EGL_PLATFORMS)),) -egl_SYS += $(WAYLAND_LIBS) $(LIBDRM_LIB) -egl_LIBS += $(TOP)/src/gallium/winsys/sw/wayland/libws_wayland.a -egl_LIBS += $(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a -endif -ifneq ($(findstring drm, $(EGL_PLATFORMS)),) -egl_SYS += $(LIBUDEV_LIBS) $(LIBDRM_LIB) -endif -ifneq ($(findstring fbdev, $(EGL_PLATFORMS)),) -egl_LIBS += $(TOP)/src/gallium/winsys/sw/fbdev/libfbdev.a -endif - -# EGL_RENDERABLE_TYPE is a compile time attribute -ifneq ($(filter $(GL_LIB), $(EGL_CLIENT_APIS)),) -egl_CPPFLAGS += $(API_DEFINES) -endif -ifneq ($(filter $(VG_LIB), $(EGL_CLIENT_APIS)),) -egl_CPPFLAGS += -DFEATURE_VG=1 -endif -egl_CPPFLAGS := $(sort $(egl_CPPFLAGS)) - -# i915 pipe driver -i915_CPPFLAGS := -i915_SYS := -ldrm_intel -i915_LIBS := \ - $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \ - $(TOP)/src/gallium/drivers/i915/libi915.a - -# i965 pipe driver -i965_CPPFLAGS := -i965_SYS := -ldrm_intel -i965_LIBS := \ - $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \ - $(TOP)/src/gallium/drivers/i965/libi965.a \ - $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a - -# nouveau pipe driver -nouveau_CPPFLAGS := -nouveau_SYS := -ldrm_nouveau -nouveau_LIBS := \ - $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \ - $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \ - $(TOP)/src/gallium/drivers/nv50/libnv50.a \ - $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \ - $(TOP)/src/gallium/drivers/nouveau/libnouveau.a - -# r300 pipe driver -r300_CPPFLAGS := -r300_SYS := -ldrm -r300_LIBS := \ - $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \ - $(TOP)/src/gallium/drivers/r300/libr300.a - -# r600 pipe driver -r600_CPPFLAGS := -r600_SYS := -ldrm -ldrm_radeon -r600_LIBS := \ - $(TOP)/src/gallium/winsys/r600/drm/libr600winsys.a \ - $(TOP)/src/gallium/drivers/r600/libr600.a - -# vmwgfx pipe driver -vmwgfx_CPPFLAGS := -vmwgfx_SYS := -vmwgfx_LIBS := \ - $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \ - $(TOP)/src/gallium/drivers/svga/libsvga.a - -# swrast (pseudo) pipe driver -swrast_CPPFLAGS := -DGALLIUM_SOFTPIPE -DGALLIUM_RBUG -DGALLIUM_TRACE -swrast_SYS := -lm -swrast_LIBS := $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a - -# LLVM -ifeq ($(MESA_LLVM),1) -common_SYS += $(LLVM_LIBS) -swrast_CPPFLAGS += -DGALLIUM_LLVMPIPE -swrast_LIBS += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a -LDFLAGS += $(LLVM_LDFLAGS) -endif - -# OpenGL state tracker -GL_CPPFLAGS := -I$(TOP)/src/mesa $(API_DEFINES) -ifeq ($(SHARED_GLAPI),1) -GL_SYS := $(DRI_LIB_DEPS) -l$(GLAPI_LIB) -else -# cannot link to $(GL_LIB) as the app might want GL or GLES -GL_SYS := $(DRI_LIB_DEPS) -endif -GL_LIBS := $(TOP)/src/mesa/libmesagallium.a - -# OpenVG state tracker -OpenVG_CPPFLAGS := -I$(TOP)/src/gallium/state_trackers/vega -OpenVG_SYS := -lm -l$(VG_LIB) -OpenVG_LIBS := $(TOP)/src/gallium/state_trackers/vega/libvega.a - - -OUTPUT_PATH := $(TOP)/$(LIB_DIR)/egl - -# determine the outputs -ifneq ($(findstring i915/drm,$(GALLIUM_WINSYS_DIRS)),) -OUTPUTS += i915 -endif -ifneq ($(findstring i965/drm,$(GALLIUM_WINSYS_DIRS)),) -OUTPUTS += i965 -endif -ifneq ($(findstring nouveau/drm,$(GALLIUM_WINSYS_DIRS)),) -OUTPUTS += nouveau -endif -ifneq ($(findstring radeon/drm,$(GALLIUM_WINSYS_DIRS)),) -OUTPUTS += r300 -endif -ifneq ($(findstring r600/drm,$(GALLIUM_WINSYS_DIRS)),) -OUTPUTS += r600 -endif -ifneq ($(findstring svga/drm,$(GALLIUM_WINSYS_DIRS)),) -OUTPUTS += vmwgfx -endif -OUTPUTS += swrast -OUTPUTS := $(addprefix $(PIPE_PREFIX), $(OUTPUTS)) - -# EGL driver and state trackers -OUTPUTS += egl_gallium $(addprefix $(ST_PREFIX), $(EGL_CLIENT_APIS)) - -OUTPUTS := $(addsuffix .so, $(OUTPUTS)) -OUTPUTS := $(addprefix $(OUTPUT_PATH)/, $(OUTPUTS)) - -default: $(OUTPUTS) - -define mklib -$(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' \ - -L$(TOP)/$(LIB_DIR) -ldflags '$(LDFLAGS)' \ - -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) $< \ - -Wl,--start-group $(common_LIBS) $($(1)_LIBS) -Wl,--end-group \ - $(common_SYS) $($(1)_SYS) -endef - -define mklib-cxx -$(MKLIB) -o $(notdir $@) -noprefix -linker '$(CXX)' \ - -L$(TOP)/$(LIB_DIR) -ldflags '$(LDFLAGS)' \ - -cplusplus -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) $< \ - -Wl,--start-group $(common_LIBS) $($(1)_LIBS) -Wl,--end-group \ - $(common_SYS) $($(1)_SYS) -endef - -# EGL driver -$(OUTPUT_PATH)/egl_gallium.so: egl.o $(egl_LIBS) - $(call mklib,egl) - -# pipe drivers -$(OUTPUT_PATH)/$(PIPE_PREFIX)i915.so: pipe_i915.o $(i915_LIBS) - $(call mklib,i915) - -$(OUTPUT_PATH)/$(PIPE_PREFIX)i965.so: pipe_i965.o $(i965_LIBS) - $(call mklib,i965) - -$(OUTPUT_PATH)/$(PIPE_PREFIX)nouveau.so: pipe_nouveau.o $(nouveau_LIBS) - $(call mklib,nouveau) - -$(OUTPUT_PATH)/$(PIPE_PREFIX)r300.so: pipe_r300.o $(r300_LIBS) - $(call mklib,r300) - -$(OUTPUT_PATH)/$(PIPE_PREFIX)r600.so: pipe_r600.o $(r600_LIBS) - $(call mklib,r600) - -$(OUTPUT_PATH)/$(PIPE_PREFIX)vmwgfx.so: pipe_vmwgfx.o $(vmwgfx_LIBS) - $(call mklib,vmwgfx) - -$(OUTPUT_PATH)/$(PIPE_PREFIX)swrast.so: pipe_swrast.o $(swrast_LIBS) - $(call mklib,swrast) - -# state trackers -$(OUTPUT_PATH)/$(ST_PREFIX)$(GL_LIB).so: st_GL.o $(GL_LIBS) - $(call mklib-cxx,GL) - -$(OUTPUT_PATH)/$(ST_PREFIX)$(VG_LIB).so: st_OpenVG.o $(OpenVG_LIBS) - $(call mklib,OpenVG) - -egl.o: egl.c - $(CC) -c -o $@ $< $(common_CPPFLAGS) $(egl_CPPFLAGS) $(DEFINES) $(CFLAGS) - -pipe_%.o: pipe_%.c - $(CC) -c -o $@ $< $(common_CPPFLAGS) $($*_CPPFLAGS) $(DEFINES) $(CFLAGS) - -st_%.o: st_%.c - $(CC) -c -o $@ $< $(common_CPPFLAGS) $($*_CPPFLAGS) $(DEFINES) $(CFLAGS) - -install: $(OUTPUTS) - $(INSTALL) -d $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR) - for out in $(OUTPUTS); do \ - $(MINSTALL) -m 755 "$$out" $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR); \ - done - -clean: - rm -f *.o diff --git a/src/gallium/targets/egl/egl.c b/src/gallium/targets/egl/egl.c deleted file mode 100644 index 3467aea9991..00000000000 --- a/src/gallium/targets/egl/egl.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.9 - * - * Copyright (C) 2010 LunarG Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Chia-I Wu <[email protected]> - */ - -#include "util/u_debug.h" -#include "util/u_string.h" -#include "util/u_memory.h" -#include "util/u_dl.h" -#include "egldriver.h" -#include "egllog.h" - -#include "state_tracker/st_api.h" -#include "state_tracker/drm_driver.h" -#include "common/egl_g3d_loader.h" - -#ifdef HAVE_LIBUDEV -#include <libudev.h> -#define DRIVER_MAP_GALLIUM_ONLY -#include "pci_ids/pci_id_driver_map.h" -#endif - -#include "egl.h" - -struct egl_g3d_loader egl_g3d_loader; - -static struct st_module { - boolean initialized; - char *name; - struct util_dl_library *lib; - struct st_api *stapi; -} st_modules[ST_API_COUNT]; - -static struct pipe_module { - boolean initialized; - char *name; - struct util_dl_library *lib; - const struct drm_driver_descriptor *drmdd; - struct pipe_screen *(*swrast_create_screen)(struct sw_winsys *); -} pipe_modules[16]; - -static char * -loader_strdup(const char *s) -{ - size_t len = (s) ? strlen(s) : 0; - char *t = MALLOC(len + 1); - if (t) { - memcpy(t, s, len); - t[len] = '\0'; - } - return t; -} - -static EGLBoolean -dlopen_st_module_cb(const char *dir, size_t len, void *callback_data) -{ - struct st_module *stmod = - (struct st_module *) callback_data; - char path[1024]; - int ret; - - if (len) { - ret = util_snprintf(path, sizeof(path), - "%.*s/" ST_PREFIX "%s" UTIL_DL_EXT, len, dir, stmod->name); - } - else { - ret = util_snprintf(path, sizeof(path), - ST_PREFIX "%s" UTIL_DL_EXT, stmod->name); - } - - if (ret > 0 && ret < sizeof(path)) { - stmod->lib = util_dl_open(path); - if (stmod->lib) - _eglLog(_EGL_DEBUG, "loaded %s", path); - } - - return !(stmod->lib); -} - -static boolean -load_st_module(struct st_module *stmod, - const char *name, const char *procname) -{ - struct st_api *(*create_api)(void); - - if (name) { - _eglLog(_EGL_DEBUG, "searching for st module %s", name); - stmod->name = loader_strdup(name); - } - else { - stmod->name = NULL; - } - - if (stmod->name) - _eglSearchPathForEach(dlopen_st_module_cb, (void *) stmod); - else - stmod->lib = util_dl_open(NULL); - - if (stmod->lib) { - create_api = (struct st_api *(*)(void)) - util_dl_get_proc_address(stmod->lib, procname); - if (create_api) - stmod->stapi = create_api(); - - if (!stmod->stapi) { - util_dl_close(stmod->lib); - stmod->lib = NULL; - } - } - - if (!stmod->stapi) { - FREE(stmod->name); - stmod->name = NULL; - } - - return (stmod->stapi != NULL); -} - -static EGLBoolean -dlopen_pipe_module_cb(const char *dir, size_t len, void *callback_data) -{ - struct pipe_module *pmod = (struct pipe_module *) callback_data; - char path[1024]; - int ret; - - if (len) { - ret = util_snprintf(path, sizeof(path), - "%.*s/" PIPE_PREFIX "%s" UTIL_DL_EXT, len, dir, pmod->name); - } - else { - ret = util_snprintf(path, sizeof(path), - PIPE_PREFIX "%s" UTIL_DL_EXT, pmod->name); - } - if (ret > 0 && ret < sizeof(path)) { - pmod->lib = util_dl_open(path); - if (pmod->lib) - _eglLog(_EGL_DEBUG, "loaded %s", path); - } - - return !(pmod->lib); -} - -static boolean -load_pipe_module(struct pipe_module *pmod, const char *name) -{ - pmod->name = loader_strdup(name); - if (!pmod->name) - return FALSE; - - _eglLog(_EGL_DEBUG, "searching for pipe module %s", pmod->name); - _eglSearchPathForEach(dlopen_pipe_module_cb, (void *) pmod); - if (pmod->lib) { - pmod->drmdd = (const struct drm_driver_descriptor *) - util_dl_get_proc_address(pmod->lib, "driver_descriptor"); - - /* sanity check on the name */ - if (pmod->drmdd && strcmp(pmod->drmdd->name, pmod->name) != 0) - pmod->drmdd = NULL; - - /* swrast */ - if (pmod->drmdd && !pmod->drmdd->driver_name) { - pmod->swrast_create_screen = - (struct pipe_screen *(*)(struct sw_winsys *)) - util_dl_get_proc_address(pmod->lib, "swrast_create_screen"); - if (!pmod->swrast_create_screen) - pmod->drmdd = NULL; - } - - if (!pmod->drmdd) { - util_dl_close(pmod->lib); - pmod->lib = NULL; - } - } - - return (pmod->drmdd != NULL); -} - -static struct st_api * -get_st_api_full(enum st_api_type api, enum st_profile_type profile) -{ - struct st_module *stmod = &st_modules[api]; - const char *names[8], *symbol; - int i, count = 0; - - if (stmod->initialized) - return stmod->stapi; - - switch (api) { - case ST_API_OPENGL: - symbol = ST_CREATE_OPENGL_SYMBOL; - names[count++] = "GL"; - break; - case ST_API_OPENVG: - symbol = ST_CREATE_OPENVG_SYMBOL; - names[count++] = "OpenVG"; - break; - default: - symbol = NULL; - assert(!"Unknown API Type\n"); - break; - } - - /* NULL means the process itself */ - names[count++] = NULL; - - for (i = 0; i < count; i++) { - if (load_st_module(stmod, names[i], symbol)) - break; - } - - /* try again with libGL.so loaded */ - if (!stmod->stapi && api == ST_API_OPENGL) { - struct util_dl_library *glapi = util_dl_open("libGL" UTIL_DL_EXT); - - if (glapi) { - _eglLog(_EGL_DEBUG, "retry with libGL" UTIL_DL_EXT " loaded"); - /* skip the last name (which is NULL) */ - for (i = 0; i < count - 1; i++) { - if (load_st_module(stmod, names[i], symbol)) - break; - } - util_dl_close(glapi); - } - } - - if (!stmod->stapi) { - EGLint level = (egl_g3d_loader.profile_masks[api]) ? - _EGL_WARNING : _EGL_DEBUG; - _eglLog(level, "unable to load " ST_PREFIX "%s" UTIL_DL_EXT, names[0]); - } - - stmod->initialized = TRUE; - - return stmod->stapi; -} - -static struct st_api * -get_st_api(enum st_api_type api) -{ - enum st_profile_type profile = ST_PROFILE_DEFAULT; - - /* determine the profile from the linked libraries */ - if (api == ST_API_OPENGL) { - struct util_dl_library *self; - - self = util_dl_open(NULL); - if (self) { - if (util_dl_get_proc_address(self, "glColor4x")) - profile = ST_PROFILE_OPENGL_ES1; - else if (util_dl_get_proc_address(self, "glShaderBinary")) - profile = ST_PROFILE_OPENGL_ES2; - util_dl_close(self); - } - } - - return get_st_api_full(api, profile); -} - -static struct st_api * -guess_gl_api(enum st_profile_type profile) -{ - return get_st_api_full(ST_API_OPENGL, profile); -} - -static struct pipe_module * -get_pipe_module(const char *name) -{ - struct pipe_module *pmod = NULL; - int i; - - if (!name) - return NULL; - - for (i = 0; i < Elements(pipe_modules); i++) { - if (!pipe_modules[i].initialized || - strcmp(pipe_modules[i].name, name) == 0) { - pmod = &pipe_modules[i]; - break; - } - } - if (!pmod) - return NULL; - - if (!pmod->initialized) { - load_pipe_module(pmod, name); - pmod->initialized = TRUE; - } - - return pmod; -} - -static char * -drm_fd_get_screen_name(int fd) -{ - char *driver = NULL; -#ifdef HAVE_LIBUDEV - struct udev *udev; - struct udev_device *device, *parent; - struct stat buf; - const char *pci_id; - int vendor_id, chip_id, i, j; - - udev = udev_new(); - if (fstat(fd, &buf) < 0) { - _eglLog(_EGL_WARNING, "failed to stat fd %d", fd); - return NULL; - } - - device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev); - if (device == NULL) { - _eglLog(_EGL_WARNING, - "could not create udev device for fd %d", fd); - return NULL; - } - - parent = udev_device_get_parent(device); - if (parent == NULL) { - _eglLog(_EGL_WARNING, "could not get parent device"); - goto out; - } - - pci_id = udev_device_get_property_value(parent, "PCI_ID"); - if (pci_id == NULL || - sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) != 2) { - _eglLog(_EGL_WARNING, "malformed or no PCI ID"); - goto out; - } - - for (i = 0; driver_map[i].driver; i++) { - if (vendor_id != driver_map[i].vendor_id) - continue; - if (driver_map[i].num_chips_ids == -1) { - driver = strdup(driver_map[i].driver); - _eglLog(_EGL_WARNING, - "pci id for %d: %04x:%04x, driver %s", - fd, vendor_id, chip_id, driver); - goto out; - } - - for (j = 0; j < driver_map[i].num_chips_ids; j++) - if (driver_map[i].chip_ids[j] == chip_id) { - driver = strdup(driver_map[i].driver); - _eglLog(_EGL_WARNING, - "pci id for %d: %04x:%04x, driver %s", - fd, vendor_id, chip_id, driver); - goto out; - } - } - -out: - udev_device_unref(device); - udev_unref(udev); - -#endif - return driver; -} - -static struct pipe_screen * -create_drm_screen(const char *name, int fd) -{ - struct pipe_module *pmod; - const char *screen_name = name; - - if (screen_name == NULL) - if ((screen_name = drm_fd_get_screen_name(fd)) == NULL) - return NULL; - pmod = get_pipe_module(screen_name); - - return (pmod && pmod->drmdd && pmod->drmdd->create_screen) ? - pmod->drmdd->create_screen(fd) : NULL; -} - -static struct pipe_screen * -create_sw_screen(struct sw_winsys *ws) -{ - struct pipe_module *pmod = get_pipe_module("swrast"); - return (pmod && pmod->swrast_create_screen) ? - pmod->swrast_create_screen(ws) : NULL; -} - -static const struct egl_g3d_loader * -loader_init(void) -{ - /* TODO detect at runtime? */ -#if FEATURE_GL - egl_g3d_loader.profile_masks[ST_API_OPENGL] |= ST_PROFILE_DEFAULT_MASK; -#endif -#if FEATURE_ES1 - egl_g3d_loader.profile_masks[ST_API_OPENGL] |= ST_PROFILE_OPENGL_ES1_MASK; -#endif -#if FEATURE_ES2 - egl_g3d_loader.profile_masks[ST_API_OPENGL] |= ST_PROFILE_OPENGL_ES2_MASK; -#endif -#if FEATURE_VG - egl_g3d_loader.profile_masks[ST_API_OPENVG] |= ST_PROFILE_DEFAULT_MASK; -#endif - - egl_g3d_loader.get_st_api = get_st_api; - egl_g3d_loader.guess_gl_api = guess_gl_api; - egl_g3d_loader.create_drm_screen = create_drm_screen; - egl_g3d_loader.create_sw_screen = create_sw_screen; - - return &egl_g3d_loader; -} - -static void -loader_fini(void) -{ - int i; - - for (i = 0; i < ST_API_COUNT; i++) { - struct st_module *stmod = &st_modules[i]; - - if (stmod->stapi) { - stmod->stapi->destroy(stmod->stapi); - stmod->stapi = NULL; - } - if (stmod->lib) { - util_dl_close(stmod->lib); - stmod->lib = NULL; - } - if (stmod->name) { - FREE(stmod->name); - stmod->name = NULL; - } - stmod->initialized = FALSE; - } - for (i = 0; i < Elements(pipe_modules); i++) { - struct pipe_module *pmod = &pipe_modules[i]; - - if (!pmod->initialized) - break; - - pmod->drmdd = NULL; - pmod->swrast_create_screen = NULL; - if (pmod->lib) { - util_dl_close(pmod->lib); - pmod->lib = NULL; - } - if (pmod->name) { - FREE(pmod->name); - pmod->name = NULL; - } - pmod->initialized = FALSE; - } -} - -static void -egl_g3d_unload(_EGLDriver *drv) -{ - egl_g3d_destroy_driver(drv); - loader_fini(); -} - -_EGLDriver * -_eglMain(const char *args) -{ - const struct egl_g3d_loader *loader; - _EGLDriver *drv; - - loader = loader_init(); - drv = egl_g3d_create_driver(loader); - if (!drv) { - loader_fini(); - return NULL; - } - - drv->Name = "Gallium"; - drv->Unload = egl_g3d_unload; - - return drv; -} diff --git a/src/gallium/targets/egl/st_GL.c b/src/gallium/targets/egl/st_GL.c deleted file mode 100644 index c1df844aa43..00000000000 --- a/src/gallium/targets/egl/st_GL.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "state_tracker/st_gl_api.h" -#include "egl.h" - -PUBLIC struct st_api * -st_api_create_OpenGL(void) -{ - return st_gl_api_create(); -} diff --git a/src/gallium/targets/egl/st_OpenVG.c b/src/gallium/targets/egl/st_OpenVG.c deleted file mode 100644 index d0bf4dbae91..00000000000 --- a/src/gallium/targets/egl/st_OpenVG.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "vg_api.h" -#include "egl.h" - -PUBLIC struct st_api * -st_api_create_OpenVG(void) -{ - return (struct st_api *) vg_api_get(); -} diff --git a/src/gallium/targets/gbm/Makefile b/src/gallium/targets/gbm/Makefile new file mode 100644 index 00000000000..53104253d4f --- /dev/null +++ b/src/gallium/targets/gbm/Makefile @@ -0,0 +1,169 @@ +# src/gallium/targets/gbm/Makefile + +TOP = ../../../.. +include $(TOP)/configs/current + +PIPE_PREFIX := pipe_ + +GBM_BACKEND = gbm_gallium_drm +GBM_SOURCES = gbm.c pipe_loader.c + +GBM_INCLUDES = \ + -I$(TOP)/include \ + -I$(TOP)/src/gallium/state_trackers/gbm \ + -I$(TOP)/src/gbm/main \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/include \ + +GBM_LIBS = $(LIBUDEV_LIBS) $(LIBDRM_LIB) \ + $(TOP)/src/gallium/state_trackers/gbm/libgbm.a \ + $(TOP)/src/gallium/drivers/identity/libidentity.a \ + $(TOP)/src/gallium/drivers/galahad/libgalahad.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ + $(GALLIUM_AUXILIARIES) + + +GBM_CFLAGS = \ + -DGBM_BACKEND_SEARCH_DIR=\"$(GBM_BACKEND_INSTALL_DIR)\" \ + -DPIPE_PREFIX=\"$(PIPE_PREFIX)\" \ + $(LIBUDEV_CFLAGS) \ + $(LIBDRM_CFLAGS) + + +pipe_INCLUDES = \ + -I$(TOP)/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/winsys + +pipe_LIBS = \ + $(TOP)/src/gallium/drivers/identity/libidentity.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ + $(GALLIUM_AUXILIARIES) + +# as if we are DRI modules +pipe_SYS = $(DRI_LIB_DEPS) + +pipe_CLFLAGS = \ + -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_GALAHAD \ + $(LIBDRM_CFLAGS) + +pipe_LDFLAGS = -Wl,--no-undefined + +# i915 pipe driver +i915_LIBS = \ + $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \ + $(TOP)/src/gallium/drivers/i915/libi915.a +i915_SYS = -ldrm_intel + +# i965 pipe driver +i965_LIBS = \ + $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \ + $(TOP)/src/gallium/drivers/i965/libi965.a \ + $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a +i965_SYS = -ldrm_intel + +# nouveau pipe driver +nouveau_LIBS = \ + $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \ + $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \ + $(TOP)/src/gallium/drivers/nv50/libnv50.a \ + $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \ + $(TOP)/src/gallium/drivers/nouveau/libnouveau.a +nouveau_SYS = -ldrm_nouveau + +# r300 pipe driver +r300_LIBS = \ + $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \ + $(TOP)/src/gallium/drivers/r300/libr300.a +r300_SYS = -ldrm_radeon + +# r600 pipe driver +r600_LIBS = \ + $(TOP)/src/gallium/winsys/r600/drm/libr600winsys.a \ + $(TOP)/src/gallium/drivers/r600/libr600.a +r600_SYS = -ldrm_radeon + +# vmwgfx pipe driver +vmwgfx_LIBS = \ + $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \ + $(TOP)/src/gallium/drivers/svga/libsvga.a + +# LLVM +ifeq ($(MESA_LLVM),1) +pipe_LIBS += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a +pipe_SYS += $(LLVM_LIBS) +pipe_LDFLAGS += $(LLVM_LDFLAGS) +endif + +# determine the targets/sources +pipe_TARGETS = +pipe_SOURCES = + +ifneq ($(findstring i915/drm,$(GALLIUM_WINSYS_DIRS)),) +pipe_TARGETS += $(PIPE_PREFIX)i915.so +pipe_SOURCES += pipe_i915.c +endif + +ifneq ($(findstring i965/drm,$(GALLIUM_WINSYS_DIRS)),) +pipe_TARGETS += $(PIPE_PREFIX)i965.so +pipe_SOURCES += pipe_i965.c +endif + +ifneq ($(findstring nouveau/drm,$(GALLIUM_WINSYS_DIRS)),) +pipe_TARGETS += $(PIPE_PREFIX)nouveau.so +pipe_SOURCES += pipe_nouveau.c +endif + +ifneq ($(findstring radeon/drm,$(GALLIUM_WINSYS_DIRS)),) +pipe_TARGETS += $(PIPE_PREFIX)r300.so +pipe_SOURCES += pipe_r300.c +endif + +ifneq ($(findstring r600/drm,$(GALLIUM_WINSYS_DIRS)),) +pipe_TARGETS += $(PIPE_PREFIX)r600.so +pipe_SOURCES += pipe_r600.c +endif + +ifneq ($(findstring svga/drm,$(GALLIUM_WINSYS_DIRS)),) +pipe_TARGETS += $(PIPE_PREFIX)vmwgfx.so +pipe_SOURCES += pipe_vmwgfx.c +endif + +pipe_OBJECTS = $(pipe_SOURCES:.c=.o) + + +GBM_EXTRA_TARGETS = $(addprefix $(TOP)/$(LIB_DIR)/gbm/, $(pipe_TARGETS)) +GBM_EXTRA_INSTALL = install-pipes +GBM_EXTRA_CLEAN = clean-pipes +GBM_EXTRA_SOURCES = $(pipe_SOURCES) + +include $(TOP)/src/gbm/backends/Makefile.template + + +$(GBM_EXTRA_TARGETS): $(TOP)/$(LIB_DIR)/gbm/%: % + @$(INSTALL) -d $(dir $@) + $(INSTALL) $< $(dir $@) + +$(pipe_TARGETS): $(PIPE_PREFIX)%.so: pipe_%.o + $(MKLIB) -o $@ -noprefix -linker '$(CC)' \ + -ldflags '-L$(TOP)/$(LIB_DIR) $(pipe_LDFLAGS) $(LDFLAGS)' \ + $(MKLIB_OPTIONS) $< \ + -Wl,--start-group $(pipe_LIBS) $($*_LIBS) -Wl,--end-group \ + $(pipe_SYS) $($*_SYS) + +$(pipe_OBJECTS): %.o: %.c + $(CC) -c -o $@ $< $(pipe_INCLUDES) $(pipe_CFLAGS) $(CFLAGS) + +install-pipes: $(GBM_EXTRA_TARGETS) + $(INSTALL) -d $(DESTDIR)$(GBM_BACKEND_INSTALL_DIR) + for tgt in $(GBM_EXTRA_TARGETS); do \ + $(MINSTALL) "$$tgt" $(DESTDIR)$(GBM_BACKEND_INSTALL_DIR); \ + done + +clean-pipes: + rm -f $(pipe_TARGETS) + rm -f $(pipe_OBJECTS) diff --git a/src/gallium/targets/gbm/gbm.c b/src/gallium/targets/gbm/gbm.c new file mode 100644 index 00000000000..e840fc5fa1a --- /dev/null +++ b/src/gallium/targets/gbm/gbm.c @@ -0,0 +1,61 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#include "util/u_inlines.h" + +#include "gbm_gallium_drmint.h" +#include "pipe_loader.h" + +static struct pipe_screen * +create_drm_screen(const char *name, int fd) +{ + struct pipe_module *pmod = get_pipe_module(name); + + return (pmod && pmod->drmdd && pmod->drmdd->create_screen) ? + pmod->drmdd->create_screen(fd) : NULL; +} + +int +gallium_screen_create(struct gbm_gallium_drm_device *gdrm) +{ + gdrm->base.driver_name = drm_fd_get_screen_name(gdrm->base.base.fd); + if (gdrm->base.driver_name == NULL) + return -1; + + gdrm->screen = create_drm_screen(gdrm->base.driver_name, gdrm->base.base.fd); + if (gdrm->screen == NULL) { + debug_printf("failed to load driver: %s\n", gdrm->base.driver_name); + return -1; + }; + + return 0; +} + +GBM_EXPORT struct gbm_backend gbm_backend = { + .backend_name = "gallium_drm", + .create_device = gbm_gallium_drm_device_create, +}; diff --git a/src/gallium/targets/egl/pipe_i915.c b/src/gallium/targets/gbm/pipe_i915.c index cd74044d8c1..cd74044d8c1 100644 --- a/src/gallium/targets/egl/pipe_i915.c +++ b/src/gallium/targets/gbm/pipe_i915.c diff --git a/src/gallium/targets/egl/pipe_i965.c b/src/gallium/targets/gbm/pipe_i965.c index f810ecffb0a..f810ecffb0a 100644 --- a/src/gallium/targets/egl/pipe_i965.c +++ b/src/gallium/targets/gbm/pipe_i965.c diff --git a/src/gallium/targets/gbm/pipe_loader.c b/src/gallium/targets/gbm/pipe_loader.c new file mode 100644 index 00000000000..6200541dbf0 --- /dev/null +++ b/src/gallium/targets/gbm/pipe_loader.c @@ -0,0 +1,192 @@ +/* + * Copyright © 2011 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: + * Kristian Høgsberg <[email protected]> + * Benjamin Franzke <[email protected]> + */ + +#include <stdio.h> +#include "util/u_string.h" +#include "util/u_memory.h" + +#include <libudev.h> + +#include "gbm_gallium_drmint.h" +#include "pipe_loader.h" +#define DRIVER_MAP_GALLIUM_ONLY +#include "pci_ids/pci_id_driver_map.h" + +static struct pipe_module pipe_modules[16]; + +static INLINE char * +loader_strdup(const char *str) +{ + return mem_dup(str, strlen(str) + 1); +} + +char * +drm_fd_get_screen_name(int fd) +{ + struct udev *udev; + struct udev_device *device, *parent; + const char *pci_id; + char *driver = NULL; + int vendor_id, chip_id, i, j; + + udev = udev_new(); + device = _gbm_udev_device_new_from_fd(udev, fd); + if (device == NULL) + return NULL; + + parent = udev_device_get_parent(device); + if (parent == NULL) { + fprintf(stderr, "gbm: could not get parent device"); + goto out; + } + + pci_id = udev_device_get_property_value(parent, "PCI_ID"); + if (pci_id == NULL || + sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) != 2) { + fprintf(stderr, "gbm: malformed or no PCI ID"); + goto out; + } + + for (i = 0; driver_map[i].driver; i++) { + if (vendor_id != driver_map[i].vendor_id) + continue; + if (driver_map[i].num_chips_ids == -1) { + driver = loader_strdup(driver_map[i].driver); + _gbm_log("pci id for %d: %04x:%04x, driver %s", + fd, vendor_id, chip_id, driver); + goto out; + } + + for (j = 0; j < driver_map[i].num_chips_ids; j++) + if (driver_map[i].chip_ids[j] == chip_id) { + driver = loader_strdup(driver_map[i].driver); + _gbm_log("pci id for %d: %04x:%04x, driver %s", + fd, vendor_id, chip_id, driver); + goto out; + } + } + +out: + udev_device_unref(device); + udev_unref(udev); + + return driver; +} + +static void +find_pipe_module(struct pipe_module *pmod, const char *name) +{ + char *search_paths, *end, *next, *p; + char path[PATH_MAX]; + int ret; + + search_paths = NULL; + if (geteuid() == getuid()) { + /* don't allow setuid apps to use GBM_BACKENDS_PATH */ + search_paths = getenv("GBM_BACKENDS_PATH"); + } + if (search_paths == NULL) + search_paths = GBM_BACKEND_SEARCH_DIR; + + end = search_paths + strlen(search_paths); + for (p = search_paths; p < end && pmod->lib == NULL; p = next + 1) { + int len; + next = strchr(p, ':'); + if (next == NULL) + next = end; + + len = next - p; + + if (len) { + ret = util_snprintf(path, sizeof(path), + "%.*s/" PIPE_PREFIX "%s" UTIL_DL_EXT, len, p, pmod->name); + } + else { + ret = util_snprintf(path, sizeof(path), + PIPE_PREFIX "%s" UTIL_DL_EXT, pmod->name); + } + if (ret > 0 && ret < sizeof(path)) { + pmod->lib = util_dl_open(path); + debug_printf("loaded %s\n", path); + } + + } +} + +static boolean +load_pipe_module(struct pipe_module *pmod, const char *name) +{ + pmod->name = loader_strdup(name); + if (!pmod->name) + return FALSE; + + find_pipe_module(pmod, name); + + if (pmod->lib) { + pmod->drmdd = (const struct drm_driver_descriptor *) + util_dl_get_proc_address(pmod->lib, "driver_descriptor"); + + /* sanity check on the name */ + if (pmod->drmdd && strcmp(pmod->drmdd->name, pmod->name) != 0) + pmod->drmdd = NULL; + + if (!pmod->drmdd) { + util_dl_close(pmod->lib); + pmod->lib = NULL; + } + } + + return (pmod->drmdd != NULL); +} + +struct pipe_module * +get_pipe_module(const char *name) +{ + struct pipe_module *pmod = NULL; + int i; + + if (!name) + return NULL; + + for (i = 0; i < Elements(pipe_modules); i++) { + if (!pipe_modules[i].initialized || + strcmp(pipe_modules[i].name, name) == 0) { + pmod = &pipe_modules[i]; + break; + } + } + if (!pmod) + return NULL; + + if (!pmod->initialized) { + load_pipe_module(pmod, name); + pmod->initialized = TRUE; + } + + return pmod; +} diff --git a/src/gallium/targets/gbm/pipe_loader.h b/src/gallium/targets/gbm/pipe_loader.h new file mode 100644 index 00000000000..2e4cd9906b7 --- /dev/null +++ b/src/gallium/targets/gbm/pipe_loader.h @@ -0,0 +1,48 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#ifndef _PIPE_LOADER_H_ +#define _PIPE_LOADER_H_ + +#include "pipe/p_compiler.h" +#include "util/u_dl.h" +#include "state_tracker/drm_driver.h" + +struct pipe_module { + boolean initialized; + char *name; + struct util_dl_library *lib; + const struct drm_driver_descriptor *drmdd; +}; + +struct pipe_module * +get_pipe_module(const char *name); + +char * +drm_fd_get_screen_name(int fd); + +#endif diff --git a/src/gallium/targets/egl/pipe_nouveau.c b/src/gallium/targets/gbm/pipe_nouveau.c index 0c9081bc713..0c9081bc713 100644 --- a/src/gallium/targets/egl/pipe_nouveau.c +++ b/src/gallium/targets/gbm/pipe_nouveau.c diff --git a/src/gallium/targets/egl/pipe_r300.c b/src/gallium/targets/gbm/pipe_r300.c index 09940f0a194..09940f0a194 100644 --- a/src/gallium/targets/egl/pipe_r300.c +++ b/src/gallium/targets/gbm/pipe_r300.c diff --git a/src/gallium/targets/egl/pipe_r600.c b/src/gallium/targets/gbm/pipe_r600.c index 486a6592585..486a6592585 100644 --- a/src/gallium/targets/egl/pipe_r600.c +++ b/src/gallium/targets/gbm/pipe_r600.c diff --git a/src/gallium/targets/egl/pipe_swrast.c b/src/gallium/targets/gbm/pipe_swrast.c index b2e3289c5d3..b2e3289c5d3 100644 --- a/src/gallium/targets/egl/pipe_swrast.c +++ b/src/gallium/targets/gbm/pipe_swrast.c diff --git a/src/gallium/targets/egl/pipe_vmwgfx.c b/src/gallium/targets/gbm/pipe_vmwgfx.c index 22a28fa858a..22a28fa858a 100644 --- a/src/gallium/targets/egl/pipe_vmwgfx.c +++ b/src/gallium/targets/gbm/pipe_vmwgfx.c diff --git a/src/gallium/targets/libgl-xlib/SConscript b/src/gallium/targets/libgl-xlib/SConscript index ca15372f1d9..7d5d9bc47a9 100644 --- a/src/gallium/targets/libgl-xlib/SConscript +++ b/src/gallium/targets/libgl-xlib/SConscript @@ -54,7 +54,7 @@ libgl = env.SharedLibrary( source = sources, ) -if True: +if False: # XXX: Only install this libGL.so if DRI not enabled libgl = env.InstallSharedLibrary(libgl, version=(1, 5)) diff --git a/src/gallium/targets/xa-vmwgfx/Makefile b/src/gallium/targets/xa-vmwgfx/Makefile new file mode 100644 index 00000000000..fecdba695c7 --- /dev/null +++ b/src/gallium/targets/xa-vmwgfx/Makefile @@ -0,0 +1,101 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +##### MACROS ##### + +XA_MAJOR = 0 +XA_MINOR = 4 +XA_TINY = 0 +XA_CFLAGS = -g -fPIC + +XA_INCLUDES= -I$(TOP)/src/gallium/ \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/winsys \ + -I$(TOP)/src/gallium/drivers + +XA_LIB = xatracker +XA_LIB_NAME = lib$(XA_LIB).so +XA_LIB_GLOB = lib$(XA_LIB)*.so* +XA_LIB_DEPS = \ + $(TOP)/src/gallium/state_trackers/xa/libxatracker.o \ + $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \ + $(TOP)/src/gallium/drivers/svga/libsvga.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a + + +COMMON_GALLIUM_SOURCES= + +SOURCES = vmw_target.c +OBJECTS = $(SOURCES:.c=.o) + +ifeq ($(MESA_LLVM),1) +LDFLAGS += $(LLVM_LDFLAGS) +GALLIUM_AUXILIARIES += $(LLVM_LIBS) +else +LDFLAGS += -lstdc++ +endif + +##### RULES ##### + +.c.o: + $(CC) -c $(XA_CFLAGS) $(XA_INCLUDES) $< + + +##### TARGETS ##### + +default: $(TOP)/$(LIB_DIR)/gallium/$(XA_LIB_NAME) + + +# Make the library +$(TOP)/$(LIB_DIR)/gallium/$(XA_LIB_NAME): depend $(OBJECTS) $(XA_LIB_DEPS) + $(MKLIB) -o $(XA_LIB) -linker $(CC) -ldflags '$(LDFLAGS)' \ + -major $(XA_MAJOR) -minor $(XA_MINOR) -patch $(XA_TINY) \ + $(MKLIB_OPTIONS) \ + -exports $(TOP)/src/gallium/state_trackers/xa/xa_symbols\ + -install $(TOP)/$(LIB_DIR)/gallium \ + $(OBJECTS) $(XA_LIB_DEPS) $(GALLIUM_AUXILIARIES) + +# xa pkgconfig file +pcedit = sed \ + -e 's,@INSTALL_DIR@,$(INSTALL_DIR),g' \ + -e 's,@INSTALL_LIB_DIR@,$(INSTALL_LIB_DIR),g' \ + -e 's,@INSTALL_INC_DIR@,$(INSTALL_INC_DIR),g' \ + -e 's,@VERSION@,$(XA_MAJOR).$(XA_MINOR).$(XA_TINY),g' \ + -e 's,@XA_PC_REQ_PRIV@,$(XA_PC_REQ_PRIV),g' \ + -e 's,@XA_PC_LIB_PRIV@,$(XA_PC_LIB_PRIV),g' \ + -e 's,@XA_PC_CFLAGS@,$(XA_PC_CFLAGS),g' \ + -e 's,@XA_LIB@,$(XA_LIB),g' +xatracker.pc: xatracker.pc.in + $(pcedit) $< > $@ + +install: xatracker.pc + $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig + $(INSTALL) -m 644 $(TOP)/src/gallium/state_trackers/xa/xa_tracker.h $(DESTDIR)$(INSTALL_INC_DIR) + $(INSTALL) -m 644 $(TOP)/src/gallium/state_trackers/xa/xa_context.h $(DESTDIR)$(INSTALL_INC_DIR) + $(INSTALL) -m 644 $(TOP)/src/gallium/state_trackers/xa/xa_composite.h $(DESTDIR)$(INSTALL_INC_DIR) + $(MINSTALL) -m 755 $(TOP)/$(LIB_DIR)/gallium/$(XA_LIB_GLOB) $(DESTDIR)$(INSTALL_LIB_DIR) + $(INSTALL) -m 644 xatracker.pc $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig + +clean: + -rm -f *.o *~ + -rm -f *.lo + -rm -f *.la + -rm -f *.pc + -rm -rf .libs + -rm -f depend depend.bak exptmp + + +depend: $(SOURCES) + @ echo "running $(MKDEP)" + @ rm -f depend + @ touch depend + @ $(MKDEP) $(MKDEP_OPTIONS) -I$(TOP)/include $(XA_INCLUDES) $(SOURCES) \ + > /dev/null + +-include depend + +FORCE: diff --git a/src/gallium/targets/xa-vmwgfx/vmw_target.c b/src/gallium/targets/xa-vmwgfx/vmw_target.c new file mode 100644 index 00000000000..15089d6db26 --- /dev/null +++ b/src/gallium/targets/xa-vmwgfx/vmw_target.c @@ -0,0 +1,26 @@ + +#include "target-helpers/inline_debug_helper.h" +#include "state_tracker/drm_driver.h" +#include "svga/drm/svga_drm_public.h" +#include "svga/svga_public.h" + +static struct pipe_screen * +create_screen(int fd) +{ + struct svga_winsys_screen *sws; + struct pipe_screen *screen; + + sws = svga_drm_winsys_screen_create(fd); + if (!sws) + return NULL; + + screen = svga_screen_create(sws); + if (!screen) + return NULL; + + screen = debug_screen_wrap(screen); + + return screen; +} + +DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen) diff --git a/src/gallium/targets/xa-vmwgfx/xatracker.pc.in b/src/gallium/targets/xa-vmwgfx/xatracker.pc.in new file mode 100644 index 00000000000..4ea2f4057d7 --- /dev/null +++ b/src/gallium/targets/xa-vmwgfx/xatracker.pc.in @@ -0,0 +1,13 @@ +prefix=@INSTALL_DIR@ +exec_prefix=${prefix} +libdir=@INSTALL_LIB_DIR@ +includedir=@INSTALL_INC_DIR@ + +Name: xatracker +Description: Xorg Gallium3D acceleration library +Requires: +Requires.private: @XA_PC_REQ_PRIV@ +Version: @VERSION@ +Libs: -L${libdir} -l@XA_LIB@ +Libs.private: @XA_PC_LIB_PRIV@ +Cflags: -I${includedir} @XA_PC_CFLAGS@ diff --git a/src/gallium/targets/xorg-nouveau/Makefile b/src/gallium/targets/xorg-nouveau/Makefile index 5a2cdb1b0ef..755969cae27 100644 --- a/src/gallium/targets/xorg-nouveau/Makefile +++ b/src/gallium/targets/xorg-nouveau/Makefile @@ -1,7 +1,7 @@ TOP = ../../../.. include $(TOP)/configs/current -LIBNAME = modesetting_drv.so +LIBNAME = nouveau2_drv.so C_SOURCES = \ nouveau_target.c \ @@ -23,4 +23,7 @@ DRIVER_PIPES = \ DRIVER_LINKS = \ $(shell pkg-config --libs libdrm libdrm_nouveau) +DRIVER_INCLUDES = \ + $(shell pkg-config --cflags-only-I libdrm libdrm_nouveau xf86driproto) + include ../Makefile.xorg diff --git a/src/gallium/targets/xorg-nouveau/nouveau_xorg.c b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c index f0d64925c73..43470a1656b 100644 --- a/src/gallium/targets/xorg-nouveau/nouveau_xorg.c +++ b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c @@ -29,6 +29,9 @@ */ #include "../../state_trackers/xorg/xorg_winsys.h" +#include <nouveau_drmif.h> +#include <xorg/dri.h> +#include <xf86drmMode.h> static void nouveau_xorg_identify(int flags); static Bool nouveau_xorg_pci_probe(DriverPtr driver, int entity_num, @@ -38,23 +41,16 @@ static Bool nouveau_xorg_pci_probe(DriverPtr driver, int entity_num, static const struct pci_id_match nouveau_xorg_device_match[] = { { 0x10de, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0x00030000, 0x00ffffff, 0 }, - { 0x12d2, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, - 0x00030000, 0x00ffffff, 0 }, {0, 0, 0}, }; -static SymTabRec nouveau_xorg_chipsets[] = { - {PCI_MATCH_ANY, "NVIDIA Graphics Device"}, - {-1, NULL} -}; - static PciChipsets nouveau_xorg_pci_devices[] = { {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL}, {-1, -1, NULL} }; static XF86ModuleVersionInfo nouveau_xorg_version = { - "modesetting", + "nouveau2", MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, @@ -70,9 +66,9 @@ static XF86ModuleVersionInfo nouveau_xorg_version = { * Xorg driver exported structures */ -_X_EXPORT DriverRec modesetting = { +_X_EXPORT DriverRec nouveau2 = { 1, - "modesetting", + "nouveau2", nouveau_xorg_identify, NULL, xorg_tracker_available_options, @@ -85,7 +81,7 @@ _X_EXPORT DriverRec modesetting = { static MODULESETUPPROTO(nouveau_xorg_setup); -_X_EXPORT XF86ModuleData modesettingModuleData = { +_X_EXPORT XF86ModuleData nouveau2ModuleData = { &nouveau_xorg_version, nouveau_xorg_setup, NULL @@ -104,7 +100,7 @@ nouveau_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin) */ if (!setupDone) { setupDone = 1; - xf86AddDriver(&modesetting, module, HaveDriverFuncs); + xf86AddDriver(&nouveau2, module, HaveDriverFuncs); /* * The return value must be non-NULL on success even though there @@ -121,8 +117,7 @@ nouveau_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin) static void nouveau_xorg_identify(int flags) { - xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers", - nouveau_xorg_chipsets); + xf86DrvMsg(0, X_INFO, "nouveau2: Gallium3D based 2D driver for NV30+ NVIDIA chipsets\n"); } static Bool @@ -131,13 +126,63 @@ nouveau_xorg_pci_probe(DriverPtr driver, { ScrnInfoPtr scrn = NULL; EntityInfoPtr entity; + struct nouveau_device *dev = NULL; + char *busid; + int chipset, ret; + + if (device->vendor_id != 0x10DE) + return FALSE; + + if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) { + xf86DrvMsg(-1, X_ERROR, "[drm] No DRICreatePCIBusID symbol\n"); + return FALSE; + } + busid = DRICreatePCIBusID(device); + + ret = nouveau_device_open(&dev, busid); + if (ret) { + xf86DrvMsg(-1, X_ERROR, "[drm] failed to open device\n"); + free(busid); + return FALSE; + } + + chipset = dev->chipset; + nouveau_device_close(&dev); + + ret = drmCheckModesettingSupported(busid); + free(busid); + if (ret) { + xf86DrvMsg(-1, X_ERROR, "[drm] KMS not enabled\n"); + return FALSE; + } + + switch (chipset & 0xf0) { + case 0x00: + case 0x10: + case 0x20: + xf86DrvMsg(-1, X_NOTICE, "Too old chipset: NV%02x\n", chipset); + return FALSE; + case 0x30: + case 0x40: + case 0x60: + case 0x50: + case 0x80: + case 0x90: + case 0xa0: + case 0xc0: + xf86DrvMsg(-1, X_INFO, "Detected chipset: NV%02x\n", chipset); + break; + default: + xf86DrvMsg(-1, X_ERROR, "Unknown chipset: NV%02x\n", chipset); + return FALSE; + } scrn = xf86ConfigPciEntity(scrn, 0, entity_num, nouveau_xorg_pci_devices, NULL, NULL, NULL, NULL, NULL); if (scrn != NULL) { scrn->driverVersion = 1; scrn->driverName = "nouveau"; - scrn->name = "modesetting"; + scrn->name = "nouveau2"; scrn->Probe = NULL; entity = xf86GetEntityInfo(entity_num); diff --git a/src/gallium/targets/xorg-radeon/Makefile b/src/gallium/targets/xorg-r300/Makefile index 6d5f2c3d16e..195ab817ad0 100644 --- a/src/gallium/targets/xorg-radeon/Makefile +++ b/src/gallium/targets/xorg-r300/Makefile @@ -1,11 +1,11 @@ TOP = ../../../.. include $(TOP)/configs/current -LIBNAME = radeon_drv.so +LIBNAME = r300_drv.so C_SOURCES = \ - radeon_target.c \ - radeon_xorg.c + target.c \ + xorg.c DRIVER_DEFINES = \ -DHAVE_CONFIG_H -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_GALAHAD diff --git a/src/gallium/targets/xorg-radeon/radeon_target.c b/src/gallium/targets/xorg-r300/target.c index b8410efbd89..b48bcad3710 100644 --- a/src/gallium/targets/xorg-radeon/radeon_target.c +++ b/src/gallium/targets/xorg-r300/target.c @@ -23,4 +23,4 @@ create_screen(int fd) return screen; } -DRM_DRIVER_DESCRIPTOR("radeon", "radeon", create_screen) +DRM_DRIVER_DESCRIPTOR("r300", "radeon", create_screen) diff --git a/src/gallium/targets/xorg-radeon/radeon_xorg.c b/src/gallium/targets/xorg-r300/xorg.c index 0d6aa567229..933bfb8a07c 100644 --- a/src/gallium/targets/xorg-radeon/radeon_xorg.c +++ b/src/gallium/targets/xorg-r300/xorg.c @@ -31,29 +31,29 @@ #include "../../state_trackers/xorg/xorg_winsys.h" -static void radeon_xorg_identify(int flags); -static Bool radeon_xorg_pci_probe(DriverPtr driver, +static void r300_xorg_identify(int flags); +static Bool r300_xorg_pci_probe(DriverPtr driver, int entity_num, struct pci_device *device, intptr_t match_data); -static const struct pci_id_match radeon_xorg_device_match[] = { +static const struct pci_id_match r300_xorg_device_match[] = { {0x1002, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0}, {0, 0, 0}, }; -static SymTabRec radeon_xorg_chipsets[] = { - {PCI_MATCH_ANY, "ATI/AMD Radeon Graphics Chipset"}, +static SymTabRec r300_xorg_chipsets[] = { + {PCI_MATCH_ANY, "ATI R300 Graphics Chipset"}, {-1, NULL} }; -static PciChipsets radeon_xorg_pci_devices[] = { +static PciChipsets r300_xorg_pci_devices[] = { {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL}, {-1, -1, NULL} }; -static XF86ModuleVersionInfo radeon_xorg_version = { - "radeong", +static XF86ModuleVersionInfo r300_xorg_version = { + "r300", MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, @@ -69,24 +69,24 @@ static XF86ModuleVersionInfo radeon_xorg_version = { * Xorg driver exported structures */ -_X_EXPORT DriverRec radeong = { +_X_EXPORT DriverRec r300_driver = { 1, - "radeong", - radeon_xorg_identify, + "r300", + r300_xorg_identify, NULL, xorg_tracker_available_options, NULL, 0, NULL, - radeon_xorg_device_match, - radeon_xorg_pci_probe + r300_xorg_device_match, + r300_xorg_pci_probe }; -static MODULESETUPPROTO(radeon_xorg_setup); +static MODULESETUPPROTO(r300_xorg_setup); -_X_EXPORT XF86ModuleData radeongModuleData = { - &radeon_xorg_version, - radeon_xorg_setup, +_X_EXPORT XF86ModuleData r300ModuleData = { + &r300_xorg_version, + r300_xorg_setup, NULL }; @@ -95,7 +95,7 @@ _X_EXPORT XF86ModuleData radeongModuleData = { */ static pointer -radeon_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin) +r300_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin) { static Bool setupDone = 0; @@ -103,7 +103,7 @@ radeon_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin) */ if (!setupDone) { setupDone = 1; - xf86AddDriver(&radeong, module, HaveDriverFuncs); + xf86AddDriver(&r300_driver, module, HaveDriverFuncs); /* * The return value must be non-NULL on success even though there @@ -118,25 +118,25 @@ radeon_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin) } static void -radeon_xorg_identify(int flags) +r300_xorg_identify(int flags) { - xf86PrintChipsets("radeong", "Driver for Radeon Gallium with KMS", - radeon_xorg_chipsets); + xf86PrintChipsets("r300", "Driver for Radeon Gallium with KMS", + r300_xorg_chipsets); } static Bool -radeon_xorg_pci_probe(DriverPtr driver, +r300_xorg_pci_probe(DriverPtr driver, int entity_num, struct pci_device *device, intptr_t match_data) { ScrnInfoPtr scrn = NULL; EntityInfoPtr entity; - scrn = xf86ConfigPciEntity(scrn, 0, entity_num, radeon_xorg_pci_devices, + scrn = xf86ConfigPciEntity(scrn, 0, entity_num, r300_xorg_pci_devices, NULL, NULL, NULL, NULL, NULL); if (scrn != NULL) { scrn->driverVersion = 1; - scrn->driverName = "radeong"; - scrn->name = "radeong"; + scrn->driverName = "r300"; + scrn->name = "r300"; scrn->Probe = NULL; entity = xf86GetEntityInfo(entity_num); diff --git a/src/gallium/targets/xorg-vmwgfx/SConscript b/src/gallium/targets/xorg-vmwgfx/SConscript index 099d49cf1b7..41f4326ee86 100644 --- a/src/gallium/targets/xorg-vmwgfx/SConscript +++ b/src/gallium/targets/xorg-vmwgfx/SConscript @@ -4,10 +4,10 @@ Import('*') env = env.Clone() -env.ParseConfig('pkg-config --cflags --libs libdrm xorg-server') +env.PkgUseModules(['DRM', 'XORG']) if env['kms']: - env.ParseConfig('pkg-config --cflags --libs libkms') + env.PkgUseModules(['KMS']) env.Prepend(CPPPATH = [ '#/include', diff --git a/src/gallium/tests/trivial/Makefile b/src/gallium/tests/trivial/Makefile new file mode 100644 index 00000000000..4ddbb0b73dc --- /dev/null +++ b/src/gallium/tests/trivial/Makefile @@ -0,0 +1,54 @@ +# src/gallium/tests/trivial/Makefile + +TOP = ../../../.. +include $(TOP)/configs/current + +INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/winsys \ + $(PROG_INCLUDES) + +ifeq ($(MESA_LLVM),1) +LINKS = $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a +LDFLAGS += $(LLVM_LDFLAGS) +endif + +LINKS += \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/galahad/libgalahad.a \ + $(TOP)/src/gallium/winsys/sw/null/libws_null.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(GALLIUM_AUXILIARIES) \ + $(PROG_LINKS) + +SOURCES = \ + tri.c \ + quad-tex.c + +OBJECTS = $(SOURCES:.c=.o) + +PROGS = $(OBJECTS:.o=) + +PROG_DEFINES = \ + -DGALLIUM_SOFTPIPE -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_GALAHAD + +##### TARGETS ##### + +default: $(PROGS) + +clean: + -rm -f $(PROGS) + -rm -f *.o + -rm -f result.bmp + +##### RULES ##### + +$(OBJECTS): %.o: %.c + $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $(PROG_DEFINES) $< -o $@ + +$(PROGS): %: %.o $(LINKS) + $(CXX) $(LDFLAGS) $< $(LINKS) $(LLVM_LIBS) -lm -lpthread -ldl -o $@ diff --git a/src/gallium/tests/trivial/quad-tex.c b/src/gallium/tests/trivial/quad-tex.c index 3a64b1c8d96..6c38b1096c1 100644 --- a/src/gallium/tests/trivial/quad-tex.c +++ b/src/gallium/tests/trivial/quad-tex.c @@ -212,7 +212,7 @@ static void init_prog(struct program *p) p->sampler.mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR; p->sampler.normalized_coords = 1; - surf_tmpl.format = templat.format; + surf_tmpl.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* All drivers support this */ surf_tmpl.usage = PIPE_BIND_RENDER_TARGET; surf_tmpl.u.tex.level = 0; surf_tmpl.u.tex.first_layer = 0; @@ -329,7 +329,7 @@ static void draw(struct program *p) /* vertex element data */ cso_set_vertex_elements(p->cso, 2, p->velem); - util_draw_vertex_buffer(p->pipe, + util_draw_vertex_buffer(p->pipe, p->cso, p->vbuf, 0, PIPE_PRIM_QUADS, 4, /* verts */ diff --git a/src/gallium/tests/trivial/tri.c b/src/gallium/tests/trivial/tri.c index bfd2f3ca9a3..656e92ee886 100644 --- a/src/gallium/tests/trivial/tri.c +++ b/src/gallium/tests/trivial/tri.c @@ -153,7 +153,7 @@ static void init_prog(struct program *p) p->rasterizer.cull_face = PIPE_FACE_NONE; p->rasterizer.gl_rasterization_rules = 1; - surf_tmpl.format = templat.format; + surf_tmpl.format = PIPE_FORMAT_B8G8R8A8_UNORM; surf_tmpl.usage = PIPE_BIND_RENDER_TARGET; surf_tmpl.u.tex.level = 0; surf_tmpl.u.tex.first_layer = 0; @@ -258,7 +258,7 @@ static void draw(struct program *p) /* vertex element data */ cso_set_vertex_elements(p->cso, 2, p->velem); - util_draw_vertex_buffer(p->pipe, + util_draw_vertex_buffer(p->pipe, p->cso, p->vbuf, 0, PIPE_PRIM_TRIANGLES, 3, /* verts */ diff --git a/src/gallium/winsys/i915/drm/SConscript b/src/gallium/winsys/i915/drm/SConscript index d8f5885b62c..15c97998fd8 100644 --- a/src/gallium/winsys/i915/drm/SConscript +++ b/src/gallium/winsys/i915/drm/SConscript @@ -2,7 +2,7 @@ Import('*') env = env.Clone() -env.ParseConfig('pkg-config --cflags libdrm') +env.PkgUseModules('DRM') i915drm_sources = [ 'i915_drm_batchbuffer.c', diff --git a/src/gallium/winsys/i915/drm/i915_drm_fence.c b/src/gallium/winsys/i915/drm/i915_drm_fence.c index 30ebf4835ea..650ccfcd876 100644 --- a/src/gallium/winsys/i915/drm/i915_drm_fence.c +++ b/src/gallium/winsys/i915/drm/i915_drm_fence.c @@ -52,9 +52,13 @@ static int i915_drm_fence_signalled(struct i915_winsys *iws, struct pipe_fence_handle *fence) { - assert(0); + struct i915_drm_fence *f = (struct i915_drm_fence *)fence; - return 0; + /* fence already expired */ + if (!f->bo) + return 1; + + return !drm_intel_bo_busy(f->bo); } static int diff --git a/src/gallium/winsys/i965/drm/SConscript b/src/gallium/winsys/i965/drm/SConscript index 785be449f70..a0f32ded402 100644 --- a/src/gallium/winsys/i965/drm/SConscript +++ b/src/gallium/winsys/i965/drm/SConscript @@ -2,7 +2,7 @@ Import('*') env = env.Clone() -env.ParseConfig('pkg-config --cflags libdrm') +env.PkgUseModules('DRM') i965drm_sources = [ 'i965_drm_buffer.c', diff --git a/src/gallium/winsys/r600/drm/SConscript b/src/gallium/winsys/r600/drm/SConscript index cc9a06a2393..f55bb265226 100644 --- a/src/gallium/winsys/r600/drm/SConscript +++ b/src/gallium/winsys/r600/drm/SConscript @@ -13,11 +13,7 @@ r600_sources = [ 'r600_bomgr.c', ] -try: - env.ParseConfig('pkg-config --cflags libdrm_radeon') -except OSError: - print 'warning: not building r600g' - Return() +env.PkgUseModules('DRM_RADEON') env.Append(CPPPATH = '#/src/gallium/drivers/r600') diff --git a/src/gallium/winsys/r600/drm/evergreen_hw_context.c b/src/gallium/winsys/r600/drm/evergreen_hw_context.c index e4ab690c560..4d9dd505c41 100644 --- a/src/gallium/winsys/r600/drm/evergreen_hw_context.c +++ b/src/gallium/winsys/r600/drm/evergreen_hw_context.c @@ -42,34 +42,34 @@ static const struct r600_reg evergreen_config_reg_list[] = { {R_008958_VGT_PRIMITIVE_TYPE, 0, 0, 0}, - {R_008A14_PA_CL_ENHANCE, 0, 0, 0}, - {R_008C00_SQ_CONFIG, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C04_SQ_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C08_SQ_GPR_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C0C_SQ_THREAD_RESOURCE_MGMT, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C10_SQ_GLOBAL_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C14_SQ_GLOBAL_GPR_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C18_SQ_THREAD_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C1C_SQ_THREAD_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C20_SQ_STACK_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C24_SQ_STACK_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C28_SQ_STACK_RESOURCE_MGMT_3, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_009100_SPI_CONFIG_CNTL, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_00913C_SPI_CONFIG_CNTL_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008A14_PA_CL_ENHANCE, REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C00_SQ_CONFIG, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C04_SQ_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C08_SQ_GPR_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C0C_SQ_THREAD_RESOURCE_MGMT, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C10_SQ_GLOBAL_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C14_SQ_GLOBAL_GPR_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C18_SQ_THREAD_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C1C_SQ_THREAD_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C20_SQ_STACK_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C24_SQ_STACK_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C28_SQ_STACK_RESOURCE_MGMT_3, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_009100_SPI_CONFIG_CNTL, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_00913C_SPI_CONFIG_CNTL_1, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, }; static const struct r600_reg cayman_config_reg_list[] = { {R_008958_VGT_PRIMITIVE_TYPE, 0, 0, 0}, - {R_008A14_PA_CL_ENHANCE, 0, 0, 0}, - {R_008C00_SQ_CONFIG, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C04_SQ_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C10_SQ_GLOBAL_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C14_SQ_GLOBAL_GPR_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_009100_SPI_CONFIG_CNTL, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_00913C_SPI_CONFIG_CNTL_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008A14_PA_CL_ENHANCE, REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C00_SQ_CONFIG, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C04_SQ_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C10_SQ_GLOBAL_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C14_SQ_GLOBAL_GPR_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_009100_SPI_CONFIG_CNTL, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_00913C_SPI_CONFIG_CNTL_1, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, }; static const struct r600_reg evergreen_ctl_const_list[] = { @@ -856,7 +856,7 @@ static int r600_state_sampler_init(struct r600_context *ctx, u32 offset) return r600_context_add_block(ctx, r600_shader_sampler, nreg, PKT3_SET_SAMPLER, EVERGREEN_SAMPLER_OFFSET); } -/* SHADER SAMPLER BORDER R600/R700 */ +/* SHADER SAMPLER BORDER EG/CM */ static int evergreen_state_sampler_border_init(struct r600_context *ctx, u32 offset, unsigned id) { struct r600_reg r600_shader_sampler_border[] = { @@ -1121,7 +1121,6 @@ static inline void evergreen_context_pipe_state_set_sampler_border(struct r600_c * will end up using the new border color. */ if (dirty & R600_BLOCK_STATUS_DIRTY) evergreen_context_ps_partial_flush(ctx); - if (dirty) r600_context_dirty_block(ctx, block, dirty, 4); } diff --git a/src/gallium/winsys/r600/drm/r600_bo.c b/src/gallium/winsys/r600/drm/r600_bo.c index d7e27e07e3b..4098a6e1998 100644 --- a/src/gallium/winsys/r600/drm/r600_bo.c +++ b/src/gallium/winsys/r600/drm/r600_bo.c @@ -38,31 +38,39 @@ struct r600_bo *r600_bo(struct radeon *radeon, { struct r600_bo *bo; struct radeon_bo *rbo; - uint32_t initial_domain; + uint32_t initial_domain, domains; + /* Staging resources particpate in transfers and blits only + * and are used for uploads and downloads from regular + * resources. We generate them internally for some transfers. + */ + if (usage == PIPE_USAGE_STAGING) + domains = RADEON_GEM_DOMAIN_CPU | RADEON_GEM_DOMAIN_GTT; + else + domains = (RADEON_GEM_DOMAIN_CPU | + RADEON_GEM_DOMAIN_GTT | + RADEON_GEM_DOMAIN_VRAM); + if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) { bo = r600_bomgr_bo_create(radeon->bomgr, size, alignment, *radeon->cfence); if (bo) { + bo->domains = domains; return bo; } } - if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) { + switch(usage) { + case PIPE_USAGE_DYNAMIC: + case PIPE_USAGE_STREAM: + case PIPE_USAGE_STAGING: initial_domain = RADEON_GEM_DOMAIN_GTT; - } else { - switch(usage) { - case PIPE_USAGE_DYNAMIC: - case PIPE_USAGE_STREAM: - case PIPE_USAGE_STAGING: - initial_domain = RADEON_GEM_DOMAIN_GTT; - break; - case PIPE_USAGE_DEFAULT: - case PIPE_USAGE_STATIC: - case PIPE_USAGE_IMMUTABLE: - default: - initial_domain = RADEON_GEM_DOMAIN_VRAM; - break; - } + break; + case PIPE_USAGE_DEFAULT: + case PIPE_USAGE_STATIC: + case PIPE_USAGE_IMMUTABLE: + default: + initial_domain = RADEON_GEM_DOMAIN_VRAM; + break; } rbo = radeon_bo(radeon, 0, size, alignment, initial_domain); if (rbo == NULL) { @@ -72,35 +80,12 @@ struct r600_bo *r600_bo(struct radeon *radeon, bo = calloc(1, sizeof(struct r600_bo)); bo->size = size; bo->alignment = alignment; + bo->domains = domains; bo->bo = rbo; if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) { r600_bomgr_bo_init(radeon->bomgr, bo); } - /* Staging resources particpate in transfers and blits only - * and are used for uploads and downloads from regular - * resources. We generate them internally for some transfers. - */ - switch (usage) { - case PIPE_USAGE_DEFAULT: - bo->domains = RADEON_GEM_DOMAIN_CPU | - RADEON_GEM_DOMAIN_GTT | - RADEON_GEM_DOMAIN_VRAM; - break; - - case PIPE_USAGE_DYNAMIC: - case PIPE_USAGE_STREAM: - case PIPE_USAGE_STAGING: - bo->domains = RADEON_GEM_DOMAIN_CPU | - RADEON_GEM_DOMAIN_GTT; - break; - - case PIPE_USAGE_STATIC: - case PIPE_USAGE_IMMUTABLE: - bo->domains = RADEON_GEM_DOMAIN_VRAM; - break; - } - pipe_reference_init(&bo->reference, 1); return bo; } diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c index 03fe385334c..4602f7f2a4b 100644 --- a/src/gallium/winsys/r600/drm/r600_drm.c +++ b/src/gallium/winsys/r600/drm/r600_drm.c @@ -156,7 +156,20 @@ static int eg_interpret_tiling(struct radeon *radeon, uint32_t tiling_config) return -EINVAL; } - radeon->tiling_info.num_banks = (tiling_config & 0xf0) >> 4; + switch ((tiling_config & 0xf0) >> 4) { + case 0: + radeon->tiling_info.num_banks = 4; + break; + case 1: + radeon->tiling_info.num_banks = 8; + break; + case 2: + radeon->tiling_info.num_banks = 16; + break; + default: + return -EINVAL; + + } switch ((tiling_config & 0xf00) >> 8) { case 0: diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index 711ce18c6ca..a21beeeba3c 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -40,6 +40,17 @@ #define GROUP_FORCE_NEW_BLOCK 0 +static inline void r600_context_ps_partial_flush(struct r600_context *ctx) +{ + if (!(ctx->flags & R600_CONTEXT_DRAW_PENDING)) + return; + + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, 0); + ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4); + + ctx->flags &= ~R600_CONTEXT_DRAW_PENDING; +} + void r600_init_cs(struct r600_context *ctx) { /* R6xx requires this packet at the start of each command buffer */ @@ -51,6 +62,8 @@ void r600_init_cs(struct r600_context *ctx) ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_CONTEXT_CONTROL, 1, 0); ctx->pm4[ctx->pm4_cdwords++] = 0x80000000; ctx->pm4[ctx->pm4_cdwords++] = 0x80000000; + + ctx->init_dwords = ctx->pm4_cdwords; } static void INLINE r600_context_update_fenced_list(struct r600_context *ctx) @@ -116,6 +129,9 @@ static void r600_init_block(struct r600_context *ctx, LIST_ADDTAIL(&block->list,&ctx->dirty); } } + if (reg[i+j].flags & REG_FLAG_FLUSH_CHANGE) { + block->flags |= REG_FLAG_FLUSH_CHANGE; + } if (reg[i+j].flags & REG_FLAG_NEED_BO) { block->nbo++; @@ -206,17 +222,17 @@ int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, /* R600/R700 configuration */ static const struct r600_reg r600_config_reg_list[] = { {R_008958_VGT_PRIMITIVE_TYPE, 0, 0, 0}, - {R_008C00_SQ_CONFIG, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C04_SQ_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C08_SQ_GPR_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C0C_SQ_THREAD_RESOURCE_MGMT, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C10_SQ_STACK_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C14_SQ_STACK_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_009508_TA_CNTL_AUX, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_009714_VC_ENHANCE, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_009830_DB_DEBUG, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_009838_DB_WATERMARKS, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C00_SQ_CONFIG, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C04_SQ_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C08_SQ_GPR_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C0C_SQ_THREAD_RESOURCE_MGMT, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C10_SQ_STACK_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C14_SQ_STACK_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_009508_TA_CNTL_AUX, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_009714_VC_ENHANCE, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_009830_DB_DEBUG, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_009838_DB_WATERMARKS, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, }; static const struct r600_reg r600_ctl_const_list[] = { @@ -1008,6 +1024,10 @@ void r600_context_dirty_block(struct r600_context *ctx, LIST_ADDTAIL(&block->enable_list, &ctx->enable_list); } LIST_ADDTAIL(&block->list,&ctx->dirty); + + if (block->flags & REG_FLAG_FLUSH_CHANGE) { + r600_context_ps_partial_flush(ctx); + } } } @@ -1187,16 +1207,6 @@ static inline void r600_context_pipe_state_set_sampler(struct r600_context *ctx, r600_context_dirty_block(ctx, block, dirty, 2); } -static inline void r600_context_ps_partial_flush(struct r600_context *ctx) -{ - if (!(ctx->flags & R600_CONTEXT_DRAW_PENDING)) - return; - - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, 0); - ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4); - - ctx->flags &= ~R600_CONTEXT_DRAW_PENDING; -} static inline void r600_context_pipe_state_set_sampler_border(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset) { @@ -1490,7 +1500,7 @@ void r600_context_flush(struct r600_context *ctx) int r; struct r600_block *enable_block = NULL; - if (!ctx->pm4_cdwords) + if (ctx->pm4_cdwords == ctx->init_dwords) return; /* suspend queries */ diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index 45bc64fcf9a..69f7251c043 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -69,6 +69,7 @@ struct radeon { #define REG_FLAG_NOT_R600 8 #define REG_FLAG_ENABLE_ALWAYS 16 #define BLOCK_FLAG_RESOURCE 32 +#define REG_FLAG_FLUSH_CHANGE 64 struct r600_reg { unsigned offset; diff --git a/src/gallium/winsys/radeon/drm/SConscript b/src/gallium/winsys/radeon/drm/SConscript index 39a8c711b84..2edb1e94645 100644 --- a/src/gallium/winsys/radeon/drm/SConscript +++ b/src/gallium/winsys/radeon/drm/SConscript @@ -8,11 +8,7 @@ radeon_sources = [ 'radeon_drm_winsys.c', ] -try: - env.ParseConfig('pkg-config --cflags libdrm') -except: - print 'warning: not building Gallium Radeon' - Return() +env.PkgUseModules('DRM') radeonwinsys = env.ConvenienceLibrary( target ='radeonwinsys', diff --git a/src/gallium/winsys/svga/drm/SConscript b/src/gallium/winsys/svga/drm/SConscript index b049ea60aa8..3e25c8aa748 100644 --- a/src/gallium/winsys/svga/drm/SConscript +++ b/src/gallium/winsys/svga/drm/SConscript @@ -2,7 +2,7 @@ Import('*') env = env.Clone() -env.ParseConfig('pkg-config --cflags libdrm') +env.PkgUseModules('DRM') if env['gcc']: env.Append(CCFLAGS = ['-fvisibility=hidden']) diff --git a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c index f4f4cd7969b..38d88f63aa2 100644 --- a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c +++ b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c @@ -54,10 +54,8 @@ struct fbdev_sw_winsys struct sw_winsys base; int fd; - enum pipe_format format; struct fb_fix_screeninfo finfo; - void *fbmem; unsigned rows; unsigned stride; }; @@ -77,22 +75,53 @@ fbdev_sw_winsys(struct sw_winsys *ws) static void fbdev_displaytarget_display(struct sw_winsys *ws, struct sw_displaytarget *dt, - void *context_private) + void *winsys_private) { struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws); - struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt); - unsigned rows, len, i; + struct fbdev_sw_displaytarget *src = fbdev_sw_displaytarget(dt); + const struct fbdev_sw_drawable *dst = + (const struct fbdev_sw_drawable *) winsys_private; + unsigned height, row_offset, row_len, i; + void *fbmem; + + /* FIXME format conversion */ + if (dst->format != src->format) { + assert(0); + return; + } - rows = MIN2(fbdt->height, fbdev->rows); - len = util_format_get_stride(fbdt->format, fbdt->width); - len = MIN2(len, fbdev->stride); + height = dst->height; + if (dst->y + dst->height > fbdev->rows) { + /* nothing to copy */ + if (dst->y >= fbdev->rows) + return; - for (i = 0; i < rows; i++) { - void *dst = fbdev->fbmem + fbdev->stride * i; - void *src = fbdt->data + fbdt->stride * i; + height = fbdev->rows - dst->y; + } + + row_offset = util_format_get_stride(dst->format, dst->x); + row_len = util_format_get_stride(dst->format, dst->width); + if (row_offset + row_len > fbdev->stride) { + /* nothing to copy */ + if (row_offset >= fbdev->stride) + return; - memcpy(dst, src, len); + row_len = fbdev->stride - row_offset; } + + fbmem = mmap(0, fbdev->finfo.smem_len, + PROT_WRITE, MAP_SHARED, fbdev->fd, 0); + if (fbmem == MAP_FAILED) + return; + + for (i = 0; i < height; i++) { + char *from = (char *) src->data + src->stride * i; + char *to = (char *) fbmem + fbdev->stride * (dst->y + i) + row_offset; + + memcpy(to, from, row_len); + } + + munmap(fbmem, fbdev->finfo.smem_len); } static void @@ -133,13 +162,9 @@ fbdev_displaytarget_create(struct sw_winsys *ws, unsigned alignment, unsigned *stride) { - struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws); struct fbdev_sw_displaytarget *fbdt; unsigned nblocksy, size, format_stride; - if (fbdev->format != format) - return NULL; - fbdt = CALLOC_STRUCT(fbdev_sw_displaytarget); if (!fbdt) return NULL; @@ -170,8 +195,7 @@ fbdev_is_displaytarget_format_supported(struct sw_winsys *ws, unsigned tex_usage, enum pipe_format format) { - struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws); - return (fbdev->format == format); + return TRUE; } static void @@ -179,12 +203,11 @@ fbdev_destroy(struct sw_winsys *ws) { struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws); - munmap(fbdev->fbmem, fbdev->finfo.smem_len); FREE(fbdev); } struct sw_winsys * -fbdev_create_sw_winsys(int fd, enum pipe_format format) +fbdev_create_sw_winsys(int fd) { struct fbdev_sw_winsys *fbdev; @@ -193,19 +216,11 @@ fbdev_create_sw_winsys(int fd, enum pipe_format format) return NULL; fbdev->fd = fd; - fbdev->format = format; if (ioctl(fbdev->fd, FBIOGET_FSCREENINFO, &fbdev->finfo)) { FREE(fbdev); return NULL; } - fbdev->fbmem = mmap(0, fbdev->finfo.smem_len, - PROT_WRITE, MAP_SHARED, fbdev->fd, 0); - if (fbdev->fbmem == MAP_FAILED) { - FREE(fbdev); - return NULL; - } - fbdev->rows = fbdev->finfo.smem_len / fbdev->finfo.line_length; fbdev->stride = fbdev->finfo.line_length; diff --git a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h index d958ab9db3e..59d8a8f5cfe 100644 --- a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h +++ b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h @@ -32,7 +32,14 @@ struct sw_winsys; enum pipe_format; +/* for pipe_screen::flush_frontbuffer */ +struct fbdev_sw_drawable { + enum pipe_format format; + unsigned x, y; + unsigned width, height; +}; + struct sw_winsys * -fbdev_create_sw_winsys(int fd, enum pipe_format format); +fbdev_create_sw_winsys(int fd); #endif /* FBDEV_SW_WINSYS */ diff --git a/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h index 5e3cfd0bf23..bedd2408f05 100644 --- a/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h +++ b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h @@ -27,6 +27,7 @@ #define WAYLAND_SW_WINSYS struct sw_winsys; +struct wl_display; struct winsys_handle { int fd; diff --git a/src/gbm/Makefile b/src/gbm/Makefile new file mode 100644 index 00000000000..4769a97b699 --- /dev/null +++ b/src/gbm/Makefile @@ -0,0 +1,14 @@ +# src/gbm/Makefile + +TOP = ../.. +include $(TOP)/configs/current + +SUBDIRS = backends main + + +default install clean: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) $@) || exit 1 ; \ + fi \ + done diff --git a/src/gbm/backends/Makefile b/src/gbm/backends/Makefile new file mode 100644 index 00000000000..97eaac496d2 --- /dev/null +++ b/src/gbm/backends/Makefile @@ -0,0 +1,14 @@ +# src/gbm/backends/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + +SUBDIRS = $(GBM_BACKEND_DIRS) + + +default install clean: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir ; $(MAKE) $@) || exit 1 ; \ + fi \ + done diff --git a/src/gbm/backends/Makefile.template b/src/gbm/backends/Makefile.template new file mode 100644 index 00000000000..851e5c56217 --- /dev/null +++ b/src/gbm/backends/Makefile.template @@ -0,0 +1,65 @@ +# src/gbm/backends/Makefile.template +# +# Backends should define +# +# GBM_BACKEND, the driver name +# GBM_SOURCES, the driver sources +# GBM_INCLUDES, the include pathes +# GBM_CFLAGS, additional CFLAGS +# GBM_LIBS, additional LIBS +# +# before including this template. +# + + +GBM_BACKEND_PATH = $(TOP)/$(LIB_DIR)/gbm/$(GBM_BACKEND).so +GBM_OBJECTS = $(GBM_SOURCES:.c=.o) + +# built-in or external +ifeq ($(GBM_BUILTIN), true) +GBM_TARGET = lib$(GBM_BACKEND).a +GBM_INSTALL = +else +GBM_TARGET = $(GBM_BACKEND_PATH) +GBM_INSTALL = install-so +endif + +default: depend $(GBM_TARGET) $(GBM_EXTRA_TARGETS) + +$(GBM_BACKEND_PATH): $(GBM_BACKEND).so + @$(INSTALL) -d $(TOP)/$(LIB_DIR)/gbm + $(INSTALL) $< $(TOP)/$(LIB_DIR)/gbm + +$(GBM_BACKEND).so: $(GBM_OBJECTS) Makefile $(TOP)/src/gbm/backends/Makefile.template + @$(MKLIB) -o $(GBM_BACKEND).so -noprefix \ + -linker '$(CC)' -ldflags '-L$(TOP)/$(LIB_DIR) $(LDFLAGS)' \ + $(MKLIB_OPTIONS) \ + $(GBM_OBJECTS) $(GBM_LIBS) -l$(GBM_LIB) + +lib$(GBM_BACKEND).a: $(GBM_OBJECTS) Makefile $(TOP)/src/gbm/backends/Makefile.template + @$(MKLIB) -o $(GBM_BACKEND) -static $(GBM_OBJECTS) + +.c.o: + $(CC) -c $(GBM_INCLUDES) $(CFLAGS) $(GBM_CFLAGS) $< -o $@ + +install-so: $(GBM_BACKEND_PATH) + $(INSTALL) -d $(DESTDIR)$(GBM_BACKEND_INSTALL_DIR) + $(MINSTALL) $(GBM_BACKEND_PATH) $(DESTDIR)$(GBM_BACKEND_INSTALL_DIR) + +install: $(GBM_INSTALL) $(GBM_EXTRA_INSTALL) + +clean: $(GBM_EXTRA_CLEAN) + rm -f $(GBM_BACKEND).so + rm -f lib$(GBM_BACKEND).a + rm -f $(GBM_OBJECTS) + rm -f depend depend.bak + +depend: $(GBM_SOURCES) $(GBM_EXTRA_SOURCES) + @ echo "running $(MKDEP)" + @ rm -f depend + @ touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(GBM_INCLUDES) $(GBM_SOURCES) \ + $(GBM_EXTRA_SOURCES) >/dev/null 2>/dev/null + +sinclude depend +# DO NOT DELETE diff --git a/src/gbm/backends/dri/Makefile b/src/gbm/backends/dri/Makefile new file mode 100644 index 00000000000..78fb3291227 --- /dev/null +++ b/src/gbm/backends/dri/Makefile @@ -0,0 +1,22 @@ +# src/gbm/backends/dri/Makefile + +TOP = ../../../.. +include $(TOP)/configs/current + +GBM_BACKEND = gbm_dri +GBM_SOURCES = gbm_dri.c driver_name.c + +GBM_INCLUDES = \ + -I$(TOP)/include \ + -I$(TOP)/src/gbm/main \ + +GBM_LIBS = $(LIBUDEV_LIBS) $(LIBDRM_LIB) -L$(TOP)/lib -lglapi + +GBM_CFLAGS = \ + -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \ + $(LIBUDEV_CFLAGS) \ + $(LIBDRM_CFLAGS) + +GBM_BUILTIN=true + +include ../Makefile.template diff --git a/src/gbm/backends/dri/driver_name.c b/src/gbm/backends/dri/driver_name.c new file mode 100644 index 00000000000..2ed209fa438 --- /dev/null +++ b/src/gbm/backends/dri/driver_name.c @@ -0,0 +1,89 @@ +/* + * Copyright © 2011 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: + * Kristian Høgsberg <[email protected]> + * Benjamin Franzke <[email protected]> + */ + +#include <stdio.h> +#include <string.h> + +#include <libudev.h> + +#include "gbm_driint.h" +#define DRIVER_MAP_DRI2_ONLY +#include "pci_ids/pci_id_driver_map.h" + +char * +dri_fd_get_driver_name(int fd) +{ + struct udev *udev; + struct udev_device *device, *parent; + const char *pci_id; + char *driver = NULL; + int vendor_id, chip_id, i, j; + + udev = udev_new(); + device = _gbm_udev_device_new_from_fd(udev, fd); + if (device == NULL) + return NULL; + + parent = udev_device_get_parent(device); + if (parent == NULL) { + fprintf(stderr, "gbm: could not get parent device"); + goto out; + } + + pci_id = udev_device_get_property_value(parent, "PCI_ID"); + if (pci_id == NULL || + sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) != 2) { + fprintf(stderr, "gbm: malformed or no PCI ID"); + goto out; + } + + for (i = 0; driver_map[i].driver; i++) { + if (vendor_id != driver_map[i].vendor_id) + continue; + if (driver_map[i].num_chips_ids == -1) { + driver = strdup(driver_map[i].driver); + _gbm_log("pci id for %d: %04x:%04x, driver %s", + fd, vendor_id, chip_id, driver); + goto out; + } + + for (j = 0; j < driver_map[i].num_chips_ids; j++) + if (driver_map[i].chip_ids[j] == chip_id) { + driver = strdup(driver_map[i].driver); + _gbm_log("pci id for %d: %04x:%04x, driver %s", + fd, vendor_id, chip_id, driver); + goto out; + } + } + +out: + udev_device_unref(device); + udev_unref(udev); + + return driver; +} diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c new file mode 100644 index 00000000000..6bb7848d830 --- /dev/null +++ b/src/gbm/backends/dri/gbm_dri.c @@ -0,0 +1,378 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> +#include <limits.h> + +#include <sys/types.h> +#include <unistd.h> +#include <dlfcn.h> + +#include <GL/gl.h> /* dri_interface needs GL types */ +#include <GL/internal/dri_interface.h> + +#include "gbm_driint.h" + +#include "gbmint.h" + +static __DRIimage * +dri_lookup_egl_image(__DRIscreen *screen, void *image, void *data) +{ + struct gbm_dri_device *dri = data; + + if (dri->lookup_image == NULL) + return NULL; + + return dri->lookup_image(screen, image, dri->lookup_user_data); +} + +const __DRIuseInvalidateExtension use_invalidate = { + { __DRI_USE_INVALIDATE, 1 } +}; + +const __DRIimageLookupExtension image_lookup_extension = { + { __DRI_IMAGE_LOOKUP, 1 }, + dri_lookup_egl_image +}; + +struct dri_extension_match { + const char *name; + int version; + int offset; +}; + +static struct dri_extension_match dri_core_extensions[] = { + { __DRI_IMAGE, 1, offsetof(struct gbm_dri_device, image) }, + { NULL, 0, 0 } +}; + +static struct dri_extension_match gbm_dri_device_extensions[] = { + { __DRI_CORE, 1, offsetof(struct gbm_dri_device, core) }, + { __DRI_DRI2, 1, offsetof(struct gbm_dri_device, dri2) }, + { NULL, 0, 0 } +}; + +static int +dri_bind_extensions(struct gbm_dri_device *dri, + struct dri_extension_match *matches, + const __DRIextension **extensions) +{ + int i, j, ret = 0; + void *field; + + for (i = 0; extensions[i]; i++) { + for (j = 0; matches[j].name; j++) { + if (strcmp(extensions[i]->name, matches[j].name) == 0 && + extensions[i]->version >= matches[j].version) { + field = ((char *) dri + matches[j].offset); + *(const __DRIextension **) field = extensions[i]; + } + } + } + + for (j = 0; matches[j].name; j++) { + field = ((char *) dri + matches[j].offset); + if (*(const __DRIextension **) field == NULL) { + ret = -1; + } + } + + return ret; +} + +static int +dri_load_driver(struct gbm_dri_device *dri) +{ + const __DRIextension **extensions; + char path[PATH_MAX], *search_paths, *p, *next, *end; + + search_paths = NULL; + if (geteuid() == getuid()) { + /* don't allow setuid apps to use GBM_DRIVERS_PATH */ + search_paths = getenv("GBM_DRIVERS_PATH"); + } + if (search_paths == NULL) + search_paths = DEFAULT_DRIVER_DIR; + + dri->driver = NULL; + end = search_paths + strlen(search_paths); + for (p = search_paths; p < end && dri->driver == NULL; p = next + 1) { + int len; + next = strchr(p, ':'); + if (next == NULL) + next = end; + + len = next - p; +#if GLX_USE_TLS + snprintf(path, sizeof path, + "%.*s/tls/%s_dri.so", len, p, dri->base.driver_name); + dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); +#endif + if (dri->driver == NULL) { + snprintf(path, sizeof path, + "%.*s/%s_dri.so", len, p, dri->base.driver_name); + dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); + if (dri->driver == NULL) + fprintf(stderr, "failed to open %s: %s\n", path, dlerror()); + } + } + + if (dri->driver == NULL) { + fprintf(stderr, "gbm: failed to open any driver (search paths %s)", + search_paths); + return -1; + } + + extensions = dlsym(dri->driver, __DRI_DRIVER_EXTENSIONS); + if (extensions == NULL) { + fprintf(stderr, "gbm: driver exports no extensions (%s)", dlerror()); + dlclose(dri->driver); + return -1; + } + + + if (dri_bind_extensions(dri, gbm_dri_device_extensions, extensions) < 0) { + dlclose(dri->driver); + fprintf(stderr, "failed to bind extensions\n"); + return -1; + } + + return 0; +} + +static int +dri_screen_create(struct gbm_dri_device *dri) +{ + const __DRIextension **extensions; + int ret = 0; + + dri->base.driver_name = dri_fd_get_driver_name(dri->base.base.fd); + if (dri->base.driver_name == NULL) + return -1; + + ret = dri_load_driver(dri); + if (ret) { + fprintf(stderr, "failed to load driver: %s\n", dri->base.driver_name); + return ret; + }; + + dri->extensions[0] = &image_lookup_extension.base; + dri->extensions[1] = &use_invalidate.base; + dri->extensions[2] = NULL; + + if (dri->dri2 == NULL) + return -1; + + dri->screen = dri->dri2->createNewScreen(0, dri->base.base.fd, + dri->extensions, + &dri->driver_configs, dri); + + extensions = dri->core->getExtensions(dri->screen); + if (dri_bind_extensions(dri, dri_core_extensions, extensions) < 0) { + ret = -1; + goto free_screen; + } + + dri->lookup_image = NULL; + dri->lookup_user_data = NULL; + + return 0; + +free_screen: + dri->core->destroyScreen(dri->screen); + + return ret; +} + +static int +gbm_dri_is_format_supported(struct gbm_device *gbm, + enum gbm_bo_format format, + uint32_t usage) +{ + switch (format) { + case GBM_BO_FORMAT_XRGB8888: + break; + case GBM_BO_FORMAT_ARGB8888: + if (usage & GBM_BO_USE_SCANOUT) + return 0; + break; + default: + return 0; + } + + if (usage & GBM_BO_USE_CURSOR_64X64 && + usage & GBM_BO_USE_RENDERING) + return 0; + + return 1; +} + +static void +gbm_dri_bo_destroy(struct gbm_bo *_bo) +{ + struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm); + struct gbm_dri_bo *bo = gbm_dri_bo(_bo); + + dri->image->destroyImage(bo->image); + free(bo); +} + +static struct gbm_bo * +gbm_dri_bo_create_from_egl_image(struct gbm_device *gbm, + void *egl_dpy, void *egl_img, + uint32_t width, uint32_t height, + uint32_t usage) +{ + struct gbm_dri_device *dri = gbm_dri_device(gbm); + struct gbm_dri_bo *bo; + + (void) egl_dpy; + + if (dri->lookup_image == NULL) + return NULL; + + bo = calloc(1, sizeof *bo); + if (bo == NULL) + return NULL; + + bo->base.base.gbm = gbm; + bo->base.base.width = width; + bo->base.base.height = height; + + __DRIimage *tmp = dri->lookup_image(dri->screen, egl_img, + dri->lookup_user_data); + + bo->image = dri->image->dupImage(tmp, bo); + if (bo->image == NULL) + return NULL; + + dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, + &bo->base.base.handle.s32); + dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, + (int *) &bo->base.base.pitch); + + return &bo->base.base; +} + +static struct gbm_bo * +gbm_dri_bo_create(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, uint32_t usage) +{ + struct gbm_dri_device *dri = gbm_dri_device(gbm); + struct gbm_dri_bo *bo; + int dri_format; + unsigned dri_use = 0; + + bo = calloc(1, sizeof *bo); + if (bo == NULL) + return NULL; + + bo->base.base.gbm = gbm; + bo->base.base.width = width; + bo->base.base.height = height; + + switch (format) { + case GBM_BO_FORMAT_XRGB8888: + dri_format = __DRI_IMAGE_FORMAT_XRGB8888; + break; + case GBM_BO_FORMAT_ARGB8888: + dri_format = __DRI_IMAGE_FORMAT_ARGB8888; + break; + default: + return NULL; + } + + if (usage & GBM_BO_USE_SCANOUT) + dri_use |= __DRI_IMAGE_USE_SCANOUT; + if (usage & GBM_BO_USE_CURSOR_64X64) + dri_use |= __DRI_IMAGE_USE_CURSOR; + + bo->image = + dri->image->createImage(dri->screen, + width, height, + dri_format, dri_use, + bo); + if (bo->image == NULL) + return NULL; + + dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, + &bo->base.base.handle.s32); + dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, + (int *) &bo->base.base.pitch); + + return &bo->base.base; +} + +static void +dri_destroy(struct gbm_device *gbm) +{ + struct gbm_dri_device *dri = gbm_dri_device(gbm); + + dri->core->destroyScreen(dri->screen); + free(dri->driver_configs); + dlclose(dri->driver); + free(dri->base.driver_name); + + free(dri); +} + +static struct gbm_device * +dri_device_create(int fd) +{ + struct gbm_dri_device *dri; + int ret; + + dri = calloc(1, sizeof *dri); + + dri->base.base.fd = fd; + dri->base.base.bo_create = gbm_dri_bo_create; + dri->base.base.bo_create_from_egl_image = gbm_dri_bo_create_from_egl_image; + dri->base.base.is_format_supported = gbm_dri_is_format_supported; + dri->base.base.bo_destroy = gbm_dri_bo_destroy; + dri->base.base.destroy = dri_destroy; + + dri->base.type = GBM_DRM_DRIVER_TYPE_DRI; + dri->base.base.name = "drm"; + + ret = dri_screen_create(dri); + if (ret) { + free(dri); + return NULL; + } + + return &dri->base.base; +} + +struct gbm_backend gbm_dri_backend = { + .backend_name = "dri", + .create_device = dri_device_create, +}; diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h new file mode 100644 index 00000000000..c5b5e17a4ee --- /dev/null +++ b/src/gbm/backends/dri/gbm_driint.h @@ -0,0 +1,78 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#ifndef _GBM_DRI_INTERNAL_H_ +#define _GBM_DRI_INTERNAL_H_ + +#include "gbmint.h" + +#include "common.h" +#include "common_drm.h" + +#include <GL/gl.h> /* dri_interface needs GL types */ +#include "GL/internal/dri_interface.h" + +struct gbm_dri_device { + struct gbm_drm_device base; + + void *driver; + + __DRIscreen *screen; + + __DRIcoreExtension *core; + __DRIdri2Extension *dri2; + __DRIimageExtension *image; + + const __DRIconfig **driver_configs; + const __DRIextension *extensions[3]; + + __DRIimage *(*lookup_image)(__DRIscreen *screen, void *image, void *data); + void *lookup_user_data; +}; + +struct gbm_dri_bo { + struct gbm_drm_bo base; + + __DRIimage *image; +}; + +static inline struct gbm_dri_device * +gbm_dri_device(struct gbm_device *gbm) +{ + return (struct gbm_dri_device *) gbm; +} + +static inline struct gbm_dri_bo * +gbm_dri_bo(struct gbm_bo *bo) +{ + return (struct gbm_dri_bo *) bo; +} + +char * +dri_fd_get_driver_name(int fd); + +#endif diff --git a/src/gbm/main/Makefile b/src/gbm/main/Makefile new file mode 100644 index 00000000000..5130b9b5df2 --- /dev/null +++ b/src/gbm/main/Makefile @@ -0,0 +1,90 @@ +# src/gbm/main/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + +INCLUDE_DIRS = -I$(TOP)/include + +HEADERS = \ + common.h \ + backend.h \ + gbmint.h \ + gbm.h + +SOURCES = \ + gbm.c \ + backend.c \ + common.c + +OBJECTS = $(SOURCES:.c=.o) + +# use dl*() to load drivers +LOCAL_CFLAGS = $(LIBUDEV_CFLAGS) $(DLOPEN_CFLAGS) \ + -D_OS_UNIX=1 -DMODULEDIR='"$(GBM_BACKEND_INSTALL_DIR)"' +LOCAL_LIBS = + +# Builtin backends +ifeq ($(filter dri, $(GBM_BACKEND_DIRS)),dri) +LOCAL_LIBS += $(TOP)/src/gbm/backends/dri/libgbm_dri.a +endif + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@ + + +default: depend library + + +library: $(TOP)/$(LIB_DIR)/libgbm.so + +$(TOP)/$(LIB_DIR)/libgbm.so: $(OBJECTS) $(LOCAL_LIBS) + $(MKLIB) -o gbm -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + -major 1 -minor 0 \ + -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ + -L$(TOP)/$(LIB_DIR) $(GBM_LIB_DEPS) \ + $(OBJECTS) $(LOCAL_LIBS) + +install-headers: + $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/ + $(INSTALL) -m 644 $(TOP)/src/gbm/main/gbm.h \ + $(DESTDIR)$(INSTALL_INC_DIR) + + +PKG_CONFIG_DIR = $(INSTALL_LIB_DIR)/pkgconfig + +gbm_pcedit = sed \ + -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \ + -e 's,@INSTALL_LIB_DIR@,$(INSTALL_LIB_DIR),' \ + -e 's,@INSTALL_INC_DIR@,$(INSTALL_INC_DIR),' \ + -e 's,@VERSION@,0.0.0,' \ + -e 's,@GBM_PC_REQ_PRIV@,$(GBM_PC_REQ_PRIV),' \ + -e 's,@GBM_PC_LIB_PRIV@,$(GBM_PC_LIB_PRIV),' \ + -e 's,@GBM_PC_CFLAGS@,$(GBM_PC_CFLAGS),' \ + -e 's,@GBM_LIB@,$(GBM_LIB),' + +gbm.pc: gbm.pc.in + $(gbm_pcedit) $< > $@ + +install: default install-headers gbm.pc + $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/libgbm.so* \ + $(DESTDIR)$(INSTALL_LIB_DIR) + $(INSTALL) -d $(DESTDIR)$(PKG_CONFIG_DIR) + $(INSTALL) -m 644 gbm.pc $(DESTDIR)$(PKG_CONFIG_DIR) + +clean: + -rm -f *.o + -rm -f depend depend.bak + -rm -f gbm.pc + + +depend: $(SOURCES) $(HEADERS) + @ echo "running $(MKDEP)" + @ rm -f depend + @ touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \ + $(SOURCES) $(HEADERS) > /dev/null 2>/dev/null + + +-include depend +# DO NOT DELETE diff --git a/src/gbm/main/backend.c b/src/gbm/main/backend.c new file mode 100644 index 00000000000..aceb6621f96 --- /dev/null +++ b/src/gbm/main/backend.c @@ -0,0 +1,128 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <dlfcn.h> + +#include "backend.h" + +#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) + +extern const struct gbm_backend gbm_dri_backend; + +struct backend_desc { + const char *name; + const struct gbm_backend *builtin; +}; + +static const struct backend_desc backends[] = { + { "gbm_dri.so", &gbm_dri_backend }, + { "gbm_gallium_drm.so", NULL }, +}; + +static const void * +load_backend(const struct backend_desc *backend) +{ + char path[PATH_MAX]; + const void *init = NULL; + void *module; + const char *name; + const char *entrypoint = "gbm_backend"; + + if (backend == NULL) + return NULL; + + name = backend->name; + + if (backend->builtin) { + init = backend->builtin; + } else { + if (name[0] != '/') + snprintf(path, sizeof path, MODULEDIR "/%s", name); + else + snprintf(path, sizeof path, "%s", name); + + module = dlopen(path, RTLD_NOW | RTLD_GLOBAL); + if (!module) { + fprintf(stderr, + "failed to load module: %s\n", dlerror()); + return NULL; + } + + init = dlsym(module, entrypoint); + if (!init) + return NULL; + } + + return init; +} + +static const struct backend_desc * +find_backend(const char *name) +{ + const struct backend_desc *backend = NULL; + int i; + + for (i = 0; i < ARRAY_SIZE(backends); ++i) { + if (strcmp(backends[i].name, name) == 0) { + backend = &backends[i]; + break; + } + } + + return backend; +} + +struct gbm_device * +_gbm_create_device(int fd) +{ + const struct gbm_backend *backend = NULL; + struct gbm_device *dev = NULL; + int i; + const char *b; + + b = getenv("GBM_BACKEND"); + if (b) + backend = load_backend(find_backend(b)); + + if (backend) + dev = backend->create_device(fd); + + for (i = 0; i < ARRAY_SIZE(backends) && dev == NULL; ++i) { + backend = load_backend(&backends[i]); + if (backend == NULL) + continue; + + dev = backend->create_device(fd); + } + + return dev; +} diff --git a/src/gbm/main/backend.h b/src/gbm/main/backend.h new file mode 100644 index 00000000000..4a643750333 --- /dev/null +++ b/src/gbm/main/backend.h @@ -0,0 +1,36 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#ifndef MODULE_H_ +#define MODULE_H_ + +#include "gbmint.h" + +struct gbm_device * +_gbm_create_device(int fd); + +#endif diff --git a/src/gbm/main/common.c b/src/gbm/main/common.c new file mode 100644 index 00000000000..f02162df292 --- /dev/null +++ b/src/gbm/main/common.c @@ -0,0 +1,88 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#include <stdio.h> +#include <string.h> + +#include <libudev.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "common.h" +#include "gbmint.h" + +GBM_EXPORT struct udev_device * +_gbm_udev_device_new_from_fd(struct udev *udev, int fd) +{ + struct udev_device *device; + struct stat buf; + + if (fstat(fd, &buf) < 0) { + fprintf(stderr, "gbm: failed to stat fd %d", fd); + return NULL; + } + + device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev); + if (device == NULL) { + fprintf(stderr, + "gbm: could not create udev device for fd %d", fd); + return NULL; + } + + return device; +} + +GBM_EXPORT char * +_gbm_fd_get_device_name(int fd) +{ + struct udev *udev; + struct udev_device *device; + const char *const_device_name; + char *device_name = NULL; + + udev = udev_new(); + device = _gbm_udev_device_new_from_fd(udev, fd); + if (device == NULL) + return NULL; + + const_device_name = udev_device_get_devnode(device); + if (!const_device_name) + goto out; + device_name = strdup(const_device_name); + +out: + udev_device_unref(device); + udev_unref(udev); + + return device_name; +} + +GBM_EXPORT void +_gbm_log(const char *fmt_str, ...) +{ +} diff --git a/src/gbm/main/common.h b/src/gbm/main/common.h new file mode 100644 index 00000000000..1fcdfcac30d --- /dev/null +++ b/src/gbm/main/common.h @@ -0,0 +1,42 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#include <libudev.h> + +struct udev_device * +_gbm_udev_device_new_from_fd(struct udev *udev, int fd); + +char * +_gbm_fd_get_device_name(int fd); + +void +_gbm_log(const char *fmt_str, ...); + +#endif diff --git a/src/gbm/main/common_drm.h b/src/gbm/main/common_drm.h new file mode 100644 index 00000000000..d28c3f01f48 --- /dev/null +++ b/src/gbm/main/common_drm.h @@ -0,0 +1,48 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#ifndef _COMMON_DRM_H_ +#define _COMMON_DRM_H_ + +#include "gbmint.h" + +enum gbm_drm_driver_type { + GBM_DRM_DRIVER_TYPE_DRI, + GBM_DRM_DRIVER_TYPE_GALLIUM, +}; + +struct gbm_drm_device { + struct gbm_device base; + enum gbm_drm_driver_type type; + char *driver_name; +}; + +struct gbm_drm_bo { + struct gbm_bo base; +}; + +#endif diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c new file mode 100644 index 00000000000..8440b2c6ae3 --- /dev/null +++ b/src/gbm/main/gbm.c @@ -0,0 +1,190 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#define _BSD_SOURCE + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "gbm.h" +#include "gbmint.h" +#include "common.h" +#include "backend.h" + +#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) + +struct gbm_device *devices[16]; + +static int device_num = 0; + +GBM_EXPORT int +gbm_device_get_fd(struct gbm_device *gbm) +{ + return gbm->fd; +} + +/* FIXME: maybe superfluous, use udev subclass from the fd? */ +GBM_EXPORT const char * +gbm_device_get_backend_name(struct gbm_device *gbm) +{ + return gbm->name; +} + +int +gbm_device_is_format_supported(struct gbm_device *gbm, + enum gbm_bo_format format, + uint32_t usage) +{ + return gbm->is_format_supported(gbm, format, usage); +} + +GBM_EXPORT void +gbm_device_destroy(struct gbm_device *gbm) +{ + gbm->refcount--; + if (gbm->refcount == 0) + gbm->destroy(gbm); +} + +GBM_EXPORT struct gbm_device * +_gbm_mesa_get_device(int fd) +{ + struct gbm_device *gbm = NULL; + struct stat buf; + dev_t dev; + int i; + + if (fd < 0 || fstat(fd, &buf) < 0 || !S_ISCHR(buf.st_mode)) { + fprintf(stderr, "_gbm_mesa_get_device: invalid fd: %d\n", fd); + return NULL; + } + + for (i = 0; i < device_num; ++i) { + dev = devices[i]->stat.st_rdev; + if (major(dev) == major(buf.st_rdev) && + minor(dev) == minor(buf.st_rdev)) { + gbm = devices[i]; + gbm->refcount++; + break; + } + } + + return gbm; +} + +GBM_EXPORT struct gbm_device * +gbm_create_device(int fd) +{ + struct gbm_device *gbm = NULL; + struct stat buf; + + if (fd < 0 || fstat(fd, &buf) < 0 || !S_ISCHR(buf.st_mode)) { + fprintf(stderr, "gbm_create_device: invalid fd: %d\n", fd); + return NULL; + } + + if (device_num == 0) + memset(devices, 0, sizeof devices); + + gbm = _gbm_create_device(fd); + if (gbm == NULL) + return NULL; + + gbm->dummy = gbm_create_device; + gbm->stat = buf; + gbm->refcount = 1; + + if (device_num < ARRAY_SIZE(devices)-1) + devices[device_num++] = gbm; + + return gbm; +} + +GBM_EXPORT unsigned int +gbm_bo_get_width(struct gbm_bo *bo) +{ + return bo->width; +} + +GBM_EXPORT unsigned int +gbm_bo_get_height(struct gbm_bo *bo) +{ + return bo->height; +} + +GBM_EXPORT uint32_t +gbm_bo_get_pitch(struct gbm_bo *bo) +{ + return bo->pitch; +} + +GBM_EXPORT union gbm_bo_handle +gbm_bo_get_handle(struct gbm_bo *bo) +{ + return bo->handle; +} + +GBM_EXPORT void +gbm_bo_destroy(struct gbm_bo *bo) +{ + bo->gbm->bo_destroy(bo); +} + +GBM_EXPORT struct gbm_bo * +gbm_bo_create(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, uint32_t usage) +{ + if (width == 0 || height == 0) + return NULL; + + if (usage & GBM_BO_USE_CURSOR_64X64 && + (width != 64 || height != 64)) + return NULL; + + return gbm->bo_create(gbm, width, height, format, usage); +} + +GBM_EXPORT struct gbm_bo * +gbm_bo_create_from_egl_image(struct gbm_device *gbm, + void *egl_dpy, void *egl_image, + uint32_t width, uint32_t height, + uint32_t usage) +{ + if (width == 0 || height == 0) + return NULL; + + return gbm->bo_create_from_egl_image(gbm, egl_dpy, egl_image, + width, height, usage); +} diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h new file mode 100644 index 00000000000..d79a03e4b3f --- /dev/null +++ b/src/gbm/main/gbm.h @@ -0,0 +1,100 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#ifndef _GBM_H_ +#define _GBM_H_ + +#define __GBM__ 1 + +#include <stdint.h> + +struct gbm_device; +struct gbm_bo; + +union gbm_bo_handle { + void *ptr; + int32_t s32; + uint32_t u32; + int64_t s64; + uint64_t u64; +}; + +enum gbm_bo_format { + GBM_BO_FORMAT_XRGB8888, + GBM_BO_FORMAT_ARGB8888, +}; + +enum gbm_bo_flags { + GBM_BO_USE_SCANOUT = (1 << 0), + GBM_BO_USE_CURSOR_64X64 = (1 << 1), + GBM_BO_USE_RENDERING = (1 << 2), +}; + +int +gbm_device_get_fd(struct gbm_device *gbm); + +const char * +gbm_device_get_backend_name(struct gbm_device *gbm); + +int +gbm_device_is_format_supported(struct gbm_device *gbm, + enum gbm_bo_format format, + uint32_t usage); + +void +gbm_device_destroy(struct gbm_device *gbm); + +struct gbm_device * +gbm_create_device(int fd); + +struct gbm_bo * +gbm_bo_create(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, uint32_t flags); + +struct gbm_bo * +gbm_bo_create_from_egl_image(struct gbm_device *gbm, + void *egl_dpy, void *egl_img, + uint32_t width, uint32_t height, + uint32_t usage); + +uint32_t +gbm_bo_get_width(struct gbm_bo *bo); + +uint32_t +gbm_bo_get_height(struct gbm_bo *bo); + +uint32_t +gbm_bo_get_pitch(struct gbm_bo *bo); + +union gbm_bo_handle +gbm_bo_get_handle(struct gbm_bo *bo); + +void +gbm_bo_destroy(struct gbm_bo *bo); + +#endif diff --git a/src/gbm/main/gbm.pc.in b/src/gbm/main/gbm.pc.in new file mode 100644 index 00000000000..76299e77f83 --- /dev/null +++ b/src/gbm/main/gbm.pc.in @@ -0,0 +1,12 @@ +prefix=@INSTALL_DIR@ +exec_prefix=${prefix} +libdir=@INSTALL_LIB_DIR@ +includedir=@INSTALL_INC_DIR@ + +Name: gbm +Description: Mesa gbm library +Requires.private: @GBM_PC_REQ_PRIV@ +Version: @VERSION@ +Libs: -L${libdir} -l@GBM_LIB@ +Libs.private: @GBM_PC_LIB_PRIV@ +Cflags: -I${includedir} @GBM_PC_CFLAGS@ diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h new file mode 100644 index 00000000000..fb8db804c1b --- /dev/null +++ b/src/gbm/main/gbmint.h @@ -0,0 +1,82 @@ +/* + * Copyright © 2011 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: + * Benjamin Franzke <[email protected]> + */ + +#ifndef INTERNAL_H_ +#define INTERNAL_H_ + +#include "gbm.h" +#include <sys/stat.h> + +/* GCC visibility */ +#if defined(__GNUC__) && __GNUC__ >= 4 +#define GBM_EXPORT __attribute__ ((visibility("default"))) +#else +#define GBM_EXPORT +#endif + +struct gbm_device { + /* Hack to make a gbm_device detectable by its first element. */ + struct gbm_device *(*dummy)(int); + + int fd; + const char *name; + unsigned int refcount; + struct stat stat; + + void (*destroy)(struct gbm_device *gbm); + int (*is_format_supported)(struct gbm_device *gbm, + enum gbm_bo_format format, + uint32_t usage); + + struct gbm_bo *(*bo_create)(struct gbm_device *gbm, + uint32_t width, uint32_t height, + enum gbm_bo_format format, + uint32_t usage); + struct gbm_bo *(*bo_create_from_egl_image)(struct gbm_device *gbm, + void *egl_dpy, void *egl_img, + uint32_t width, uint32_t height, + uint32_t usage); + void (*bo_destroy)(struct gbm_bo *bo); +}; + +struct gbm_bo { + struct gbm_device *gbm; + uint32_t width; + uint32_t height; + uint32_t pitch; + union gbm_bo_handle handle; +}; + +struct gbm_backend { + const char *backend_name; + struct gbm_device *(*create_device)(int fd); +}; + +GBM_EXPORT struct gbm_device * +_gbm_mesa_get_device(int fd); + +#endif diff --git a/src/glsl/SConscript b/src/glsl/SConscript index c3255835fb4..1441cc74bd8 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -102,7 +102,7 @@ if env['msvc']: env.Prepend(CPPPATH = ['#/src/getopt']) env.PrependUnique(LIBS = [getopt]) -if env['crosscompile'] and env['platform'] != 'embedded': +if env['crosscompile'] and not env['embedded']: Import('builtin_glsl_function') else: # Copy these files to avoid generation object files into src/mesa/program @@ -156,7 +156,7 @@ Export('glsl') # Skip building these programs as they will cause SCons error "Two environments # with different actions were specified for the same target" -if env['crosscompile'] or env['platform'] == 'embedded': +if env['crosscompile'] or env['embedded']: Return() env = env.Clone() diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 3ba699ad971..60a2c617f70 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -271,17 +271,36 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type) assert(a <= GLSL_TYPE_BOOL); assert(b <= GLSL_TYPE_BOOL); - if ((a == b) || (src->type->is_integer() && desired_type->is_integer())) + if (a == b) return src; switch (a) { case GLSL_TYPE_UINT: + switch (b) { + case GLSL_TYPE_INT: + result = new(ctx) ir_expression(ir_unop_i2u, src); + break; + case GLSL_TYPE_FLOAT: + result = new(ctx) ir_expression(ir_unop_i2u, + new(ctx) ir_expression(ir_unop_f2i, src)); + break; + case GLSL_TYPE_BOOL: + result = new(ctx) ir_expression(ir_unop_i2u, + new(ctx) ir_expression(ir_unop_b2i, src)); + break; + } + break; case GLSL_TYPE_INT: - if (b == GLSL_TYPE_FLOAT) - result = new(ctx) ir_expression(ir_unop_f2i, desired_type, src, NULL); - else { - assert(b == GLSL_TYPE_BOOL); - result = new(ctx) ir_expression(ir_unop_b2i, desired_type, src, NULL); + switch (b) { + case GLSL_TYPE_UINT: + result = new(ctx) ir_expression(ir_unop_u2i, src); + break; + case GLSL_TYPE_FLOAT: + result = new(ctx) ir_expression(ir_unop_f2i, src); + break; + case GLSL_TYPE_BOOL: + result = new(ctx) ir_expression(ir_unop_b2i, src); + break; } break; case GLSL_TYPE_FLOAT: @@ -300,6 +319,9 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type) case GLSL_TYPE_BOOL: switch (b) { case GLSL_TYPE_UINT: + result = new(ctx) ir_expression(ir_unop_i2b, + new(ctx) ir_expression(ir_unop_u2i, src)); + break; case GLSL_TYPE_INT: result = new(ctx) ir_expression(ir_unop_i2b, desired_type, src, NULL); break; @@ -311,6 +333,7 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type) } assert(result != NULL); + assert(result->type == desired_type); /* Try constant folding; it may fold in the conversion we just added. */ ir_constant *const constant = result->constant_expression_value(); diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 3b87f0d56de..2e54e8c22d8 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -447,9 +447,17 @@ modulus_result_type(const struct glsl_type *type_a, * integer vectors. The operand types must both be signed or both be * unsigned." */ - if (!type_a->is_integer() || !type_b->is_integer() - || (type_a->base_type != type_b->base_type)) { - _mesa_glsl_error(loc, state, "type mismatch"); + if (!type_a->is_integer()) { + _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer."); + return glsl_type::error_type; + } + if (!type_b->is_integer()) { + _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer."); + return glsl_type::error_type; + } + if (type_a->base_type != type_b->base_type) { + _mesa_glsl_error(loc, state, + "operands of %% must have the same base type"); return glsl_type::error_type; } @@ -1940,7 +1948,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, break; case fragment_shader: - if (!global_scope || (var->mode != ir_var_in)) { + if (!global_scope || (var->mode != ir_var_out)) { fail = true; string = "output"; } diff --git a/src/glsl/builtins/ir/abs b/src/glsl/builtins/ir/abs index 904845307c4..d07d1d99e9f 100644 --- a/src/glsl/builtins/ir/abs +++ b/src/glsl/builtins/ir/abs @@ -18,4 +18,24 @@ (parameters (declare (in) vec4 arg0)) ((return (expression vec4 abs (var_ref arg0))))) + + (signature int + (parameters + (declare (in) int arg0)) + ((return (expression int abs (var_ref arg0))))) + + (signature ivec2 + (parameters + (declare (in) ivec2 arg0)) + ((return (expression ivec2 abs (var_ref arg0))))) + + (signature ivec3 + (parameters + (declare (in) ivec3 arg0)) + ((return (expression ivec3 abs (var_ref arg0))))) + + (signature ivec4 + (parameters + (declare (in) ivec4 arg0)) + ((return (expression ivec4 abs (var_ref arg0))))) )) diff --git a/src/glsl/builtins/tools/generate_builtins.py b/src/glsl/builtins/tools/generate_builtins.py index edd3c70e00b..17d528c2180 100755 --- a/src/glsl/builtins/tools/generate_builtins.py +++ b/src/glsl/builtins/tools/generate_builtins.py @@ -82,10 +82,6 @@ def write_profile(filename, profile): kill_globals = re.compile(r'^\(declare.*\n', re.MULTILINE) proto_ir = kill_globals.sub('', proto_ir) - # Kill pointer addresses. They're not necessary in prototypes and just - # clutter the diff output. - proto_ir = re.sub(r'@0x[0-9a-f]+', '', proto_ir) - print 'static const char prototypes_for_' + profile + '[] =' print stringify(proto_ir), ';' diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index d9aa300bbe4..cc781378d76 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -165,133 +165,242 @@ _mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state, } +/** + * Enum representing the possible behaviors that can be specified in + * an #extension directive. + */ +enum ext_behavior { + extension_disable, + extension_enable, + extension_require, + extension_warn +}; + +/** + * Element type for _mesa_glsl_supported_extensions + */ +struct _mesa_glsl_extension { + /** + * Name of the extension when referred to in a GLSL extension + * statement + */ + const char *name; + + /** True if this extension is available to vertex shaders */ + bool avail_in_VS; + + /** True if this extension is available to geometry shaders */ + bool avail_in_GS; + + /** True if this extension is available to fragment shaders */ + bool avail_in_FS; + + /** True if this extension is available to desktop GL shaders */ + bool avail_in_GL; + + /** True if this extension is available to GLES shaders */ + bool avail_in_ES; + + /** + * Flag in the gl_extensions struct indicating whether this + * extension is supported by the driver, or + * &gl_extensions::dummy_true if supported by all drivers. + * + * Note: the type (GLboolean gl_extensions::*) is a "pointer to + * member" type, the type-safe alternative to the "offsetof" macro. + * In a nutshell: + * + * - foo bar::* p declares p to be an "offset" to a field of type + * foo that exists within struct bar + * - &bar::baz computes the "offset" of field baz within struct bar + * - x.*p accesses the field of x that exists at "offset" p + * - x->*p is equivalent to (*x).*p + */ + const GLboolean gl_extensions::* supported_flag; + + /** + * Flag in the _mesa_glsl_parse_state struct that should be set + * when this extension is enabled. + * + * See note in _mesa_glsl_extension::supported_flag about "pointer + * to member" types. + */ + bool _mesa_glsl_parse_state::* enable_flag; + + /** + * Flag in the _mesa_glsl_parse_state struct that should be set + * when the shader requests "warn" behavior for this extension. + * + * See note in _mesa_glsl_extension::supported_flag about "pointer + * to member" types. + */ + bool _mesa_glsl_parse_state::* warn_flag; + + + bool compatible_with_state(const _mesa_glsl_parse_state *state) const; + void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const; +}; + +#define EXT(NAME, VS, GS, FS, GL, ES, SUPPORTED_FLAG) \ + { "GL_" #NAME, VS, GS, FS, GL, ES, &gl_extensions::SUPPORTED_FLAG, \ + &_mesa_glsl_parse_state::NAME##_enable, \ + &_mesa_glsl_parse_state::NAME##_warn } + +/** + * Table of extensions that can be enabled/disabled within a shader, + * and the conditions under which they are supported. + */ +static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { + /* target availability API availability */ + /* name VS GS FS GL ES supported flag */ + EXT(ARB_draw_buffers, false, false, true, true, false, dummy_true), + EXT(ARB_draw_instanced, true, false, false, true, false, ARB_draw_instanced), + EXT(ARB_explicit_attrib_location, true, false, true, true, false, ARB_explicit_attrib_location), + EXT(ARB_fragment_coord_conventions, true, false, true, true, false, ARB_fragment_coord_conventions), + EXT(ARB_texture_rectangle, true, false, true, true, false, dummy_true), + EXT(EXT_texture_array, true, false, true, true, false, EXT_texture_array), + EXT(ARB_shader_texture_lod, true, false, true, true, false, ARB_shader_texture_lod), + EXT(ARB_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export), + EXT(AMD_conservative_depth, true, false, true, true, false, AMD_conservative_depth), + EXT(AMD_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export), + EXT(OES_texture_3D, true, false, true, false, true, EXT_texture3D), +}; + +#undef EXT + + +/** + * Determine whether a given extension is compatible with the target, + * API, and extension information in the current parser state. + */ +bool _mesa_glsl_extension::compatible_with_state(const _mesa_glsl_parse_state * + state) const +{ + /* Check that this extension matches the type of shader we are + * compiling to. + */ + switch (state->target) { + case vertex_shader: + if (!this->avail_in_VS) { + return false; + } + break; + case geometry_shader: + if (!this->avail_in_GS) { + return false; + } + break; + case fragment_shader: + if (!this->avail_in_FS) { + return false; + } + break; + default: + assert (!"Unrecognized shader target"); + return false; + } + + /* Check that this extension matches whether we are compiling + * for desktop GL or GLES. + */ + if (state->es_shader) { + if (!this->avail_in_ES) return false; + } else { + if (!this->avail_in_GL) return false; + } + + /* Check that this extension is supported by the OpenGL + * implementation. + * + * Note: the ->* operator indexes into state->extensions by the + * offset this->supported_flag. See + * _mesa_glsl_extension::supported_flag for more info. + */ + return state->extensions->*(this->supported_flag); +} + +/** + * Set the appropriate flags in the parser state to establish the + * given behavior for this extension. + */ +void _mesa_glsl_extension::set_flags(_mesa_glsl_parse_state *state, + ext_behavior behavior) const +{ + /* Note: the ->* operator indexes into state by the + * offsets this->enable_flag and this->warn_flag. See + * _mesa_glsl_extension::supported_flag for more info. + */ + state->*(this->enable_flag) = (behavior != extension_disable); + state->*(this->warn_flag) = (behavior == extension_warn); +} + +/** + * Find an extension by name in _mesa_glsl_supported_extensions. If + * the name is not found, return NULL. + */ +static const _mesa_glsl_extension *find_extension(const char *name) +{ + for (unsigned i = 0; i < Elements(_mesa_glsl_supported_extensions); ++i) { + if (strcmp(name, _mesa_glsl_supported_extensions[i].name) == 0) { + return &_mesa_glsl_supported_extensions[i]; + } + } + return NULL; +} + + bool _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, - const char *behavior, YYLTYPE *behavior_locp, + const char *behavior_string, YYLTYPE *behavior_locp, _mesa_glsl_parse_state *state) { - enum { - extension_disable, - extension_enable, - extension_require, - extension_warn - } ext_mode; - - if (strcmp(behavior, "warn") == 0) { - ext_mode = extension_warn; - } else if (strcmp(behavior, "require") == 0) { - ext_mode = extension_require; - } else if (strcmp(behavior, "enable") == 0) { - ext_mode = extension_enable; - } else if (strcmp(behavior, "disable") == 0) { - ext_mode = extension_disable; + ext_behavior behavior; + if (strcmp(behavior_string, "warn") == 0) { + behavior = extension_warn; + } else if (strcmp(behavior_string, "require") == 0) { + behavior = extension_require; + } else if (strcmp(behavior_string, "enable") == 0) { + behavior = extension_enable; + } else if (strcmp(behavior_string, "disable") == 0) { + behavior = extension_disable; } else { _mesa_glsl_error(behavior_locp, state, "Unknown extension behavior `%s'", - behavior); + behavior_string); return false; } - bool unsupported = false; - if (strcmp(name, "all") == 0) { - if ((ext_mode == extension_enable) || (ext_mode == extension_require)) { + if ((behavior == extension_enable) || (behavior == extension_require)) { _mesa_glsl_error(name_locp, state, "Cannot %s all extensions", - (ext_mode == extension_enable) + (behavior == extension_enable) ? "enable" : "require"); return false; - } - } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) { - /* This extension is only supported in fragment shaders. - */ - if (state->target != fragment_shader) { - unsupported = true; } else { - state->ARB_draw_buffers_enable = (ext_mode != extension_disable); - state->ARB_draw_buffers_warn = (ext_mode == extension_warn); + for (unsigned i = 0; + i < Elements(_mesa_glsl_supported_extensions); ++i) { + const _mesa_glsl_extension *extension + = &_mesa_glsl_supported_extensions[i]; + if (extension->compatible_with_state(state)) { + _mesa_glsl_supported_extensions[i].set_flags(state, behavior); + } + } } - } else if (strcmp(name, "GL_ARB_draw_instanced") == 0) { - state->ARB_draw_instanced_enable = (ext_mode != extension_disable); - state->ARB_draw_instanced_warn = (ext_mode == extension_warn); - - /* This extension is only supported in vertex shaders. - */ - unsupported = (state->target != vertex_shader) - || !state->extensions->ARB_draw_instanced; - } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) { - state->ARB_explicit_attrib_location_enable = - (ext_mode != extension_disable); - state->ARB_explicit_attrib_location_warn = - (ext_mode == extension_warn); - - unsupported = !state->extensions->ARB_explicit_attrib_location; - } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) { - state->ARB_fragment_coord_conventions_enable = - (ext_mode != extension_disable); - state->ARB_fragment_coord_conventions_warn = - (ext_mode == extension_warn); - - unsupported = !state->extensions->ARB_fragment_coord_conventions; - } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) { - state->ARB_texture_rectangle_enable = (ext_mode != extension_disable); - state->ARB_texture_rectangle_warn = (ext_mode == extension_warn); - } else if (strcmp(name, "GL_EXT_texture_array") == 0) { - state->EXT_texture_array_enable = (ext_mode != extension_disable); - state->EXT_texture_array_warn = (ext_mode == extension_warn); - - unsupported = !state->extensions->EXT_texture_array; - } else if (strcmp(name, "GL_ARB_shader_texture_lod") == 0) { - /* Force ARB_texture_rectangle to be on so sampler2DRects are defined */ - state->ARB_texture_rectangle_enable = true; - - state->ARB_shader_texture_lod_enable = (ext_mode != extension_disable); - state->ARB_shader_texture_lod_warn = (ext_mode == extension_warn); - - unsupported = !state->extensions->ARB_shader_texture_lod; - } else if (strcmp(name, "GL_ARB_shader_stencil_export") == 0) { - state->ARB_shader_stencil_export_enable = (ext_mode != extension_disable); - state->ARB_shader_stencil_export_warn = (ext_mode == extension_warn); - - /* This extension is only supported in fragment shaders. - */ - unsupported = (state->target != fragment_shader) - || !state->extensions->ARB_shader_stencil_export; - } else if (strcmp(name, "GL_AMD_conservative_depth") == 0) { - /* The AMD_conservative spec does not forbid requiring the extension in - * the vertex shader. - */ - state->AMD_conservative_depth_enable = (ext_mode != extension_disable); - state->AMD_conservative_depth_warn = (ext_mode == extension_warn); - unsupported = !state->extensions->AMD_conservative_depth; - } else if (strcmp(name, "GL_AMD_shader_stencil_export") == 0) { - state->AMD_shader_stencil_export_enable = (ext_mode != extension_disable); - state->AMD_shader_stencil_export_warn = (ext_mode == extension_warn); - - /* This extension is only supported in fragment shaders. - * Both the ARB and AMD variants share the same ARB flag - * in gl_extensions. - */ - unsupported = (state->target != fragment_shader) - || !state->extensions->ARB_shader_stencil_export; - } else if (strcmp(name, "GL_OES_texture_3D") == 0 && state->es_shader) { - state->OES_texture_3D_enable = (ext_mode != extension_disable); - state->OES_texture_3D_warn = (ext_mode == extension_warn); - - unsupported = !state->extensions->EXT_texture3D; } else { - unsupported = true; - } - - if (unsupported) { - static const char *const fmt = "extension `%s' unsupported in %s shader"; - - if (ext_mode == extension_require) { - _mesa_glsl_error(name_locp, state, fmt, - name, _mesa_glsl_shader_target_name(state->target)); - return false; + const _mesa_glsl_extension *extension = find_extension(name); + if (extension && extension->compatible_with_state(state)) { + extension->set_flags(state, behavior); } else { - _mesa_glsl_warning(name_locp, state, fmt, - name, _mesa_glsl_shader_target_name(state->target)); + static const char *const fmt = "extension `%s' unsupported in %s shader"; + + if (behavior == extension_require) { + _mesa_glsl_error(name_locp, state, fmt, + name, _mesa_glsl_shader_target_name(state->target)); + return false; + } else { + _mesa_glsl_warning(name_locp, state, fmt, + name, _mesa_glsl_shader_target_name(state->target)); + } } } diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index 878d2ae3f4d..2f4d3cba77f 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -156,28 +156,28 @@ struct _mesa_glsl_parse_state { * \name Enable bits for GLSL extensions */ /*@{*/ - unsigned ARB_draw_buffers_enable:1; - unsigned ARB_draw_buffers_warn:1; - unsigned ARB_draw_instanced_enable:1; - unsigned ARB_draw_instanced_warn:1; - unsigned ARB_explicit_attrib_location_enable:1; - unsigned ARB_explicit_attrib_location_warn:1; - unsigned ARB_fragment_coord_conventions_enable:1; - unsigned ARB_fragment_coord_conventions_warn:1; - unsigned ARB_texture_rectangle_enable:1; - unsigned ARB_texture_rectangle_warn:1; - unsigned EXT_texture_array_enable:1; - unsigned EXT_texture_array_warn:1; - unsigned ARB_shader_texture_lod_enable:1; - unsigned ARB_shader_texture_lod_warn:1; - unsigned ARB_shader_stencil_export_enable:1; - unsigned ARB_shader_stencil_export_warn:1; - unsigned AMD_conservative_depth_enable:1; - unsigned AMD_conservative_depth_warn:1; - unsigned AMD_shader_stencil_export_enable:1; - unsigned AMD_shader_stencil_export_warn:1; - unsigned OES_texture_3D_enable:1; - unsigned OES_texture_3D_warn:1; + bool ARB_draw_buffers_enable; + bool ARB_draw_buffers_warn; + bool ARB_draw_instanced_enable; + bool ARB_draw_instanced_warn; + bool ARB_explicit_attrib_location_enable; + bool ARB_explicit_attrib_location_warn; + bool ARB_fragment_coord_conventions_enable; + bool ARB_fragment_coord_conventions_warn; + bool ARB_texture_rectangle_enable; + bool ARB_texture_rectangle_warn; + bool EXT_texture_array_enable; + bool EXT_texture_array_warn; + bool ARB_shader_texture_lod_enable; + bool ARB_shader_texture_lod_warn; + bool ARB_shader_stencil_export_enable; + bool ARB_shader_stencil_export_warn; + bool AMD_conservative_depth_enable; + bool AMD_conservative_depth_warn; + bool AMD_shader_stencil_export_enable; + bool AMD_shader_stencil_export_warn; + bool OES_texture_3D_enable; + bool OES_texture_3D_warn; /*@}*/ /** Extensions supported by the OpenGL implementation. */ diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index a3623b31e5d..95689dc10b0 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -272,6 +272,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_f2i: case ir_unop_b2i: + case ir_unop_u2i: this->type = glsl_type::get_instance(GLSL_TYPE_INT, op0->type->vector_elements, 1); break; @@ -289,6 +290,11 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) op0->type->vector_elements, 1); break; + case ir_unop_i2u: + this->type = glsl_type::get_instance(GLSL_TYPE_UINT, + op0->type->vector_elements, 1); + break; + case ir_unop_noise: this->type = glsl_type::float_type; break; @@ -419,6 +425,8 @@ static const char *const operator_strs[] = { "i2b", "b2i", "u2f", + "i2u", + "u2i", "any", "trunc", "ceil", diff --git a/src/glsl/ir.h b/src/glsl/ir.h index a41984310b3..42a3936976a 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -682,7 +682,7 @@ public: class ir_assignment : public ir_instruction { public: - ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition); + ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition = NULL); /** * Construct an assignment with an explicit write mask @@ -789,6 +789,8 @@ enum ir_expression_operation { ir_unop_i2b, /**< int-to-boolean conversion */ ir_unop_b2i, /**< Boolean-to-int conversion */ ir_unop_u2f, /**< Unsigned-to-float conversion. */ + ir_unop_i2u, /**< Integer-to-unsigned conversion. */ + ir_unop_u2i, /**< Unsigned-to-integer conversion. */ ir_unop_any, /** diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp index 2a308489656..f0299a2c4a0 100644 --- a/src/glsl/ir_constant_expression.cpp +++ b/src/glsl/ir_constant_expression.cpp @@ -166,7 +166,18 @@ ir_expression::constant_expression_value() data.b[c] = op[0]->value.u[c] ? true : false; } break; - + case ir_unop_u2i: + assert(op[0]->type->base_type == GLSL_TYPE_UINT); + for (unsigned c = 0; c < op[0]->type->components(); c++) { + data.i[c] = op[0]->value.u[c]; + } + break; + case ir_unop_i2u: + assert(op[0]->type->base_type == GLSL_TYPE_INT); + for (unsigned c = 0; c < op[0]->type->components(); c++) { + data.u[c] = op[0]->value.i[c]; + } + break; case ir_unop_any: assert(op[0]->type->is_boolean()); data.b[0] = false; diff --git a/src/glsl/ir_function.cpp b/src/glsl/ir_function.cpp index caee9296af9..ef8d4fcfcd4 100644 --- a/src/glsl/ir_function.cpp +++ b/src/glsl/ir_function.cpp @@ -165,6 +165,7 @@ ir_function_signature * ir_function::matching_signature(const exec_list *actual_parameters) { ir_function_signature *match = NULL; + int matched_score; foreach_iter(exec_list_iterator, iter, signatures) { ir_function_signature *const sig = @@ -173,14 +174,14 @@ ir_function::matching_signature(const exec_list *actual_parameters) const int score = parameter_lists_match(& sig->parameters, actual_parameters); + /* If we found an exact match, simply return it */ if (score == 0) return sig; - if (score > 0) { - if (match != NULL) - return NULL; - + /* If we found a match with fewer conversions, use that instead */ + if (score > 0 && (match == NULL || score < matched_score)) { match = sig; + matched_score = score; } } diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index 7b1c19d65aa..f3fceb2a57d 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -254,7 +254,7 @@ ir_validate::visit_leave(ir_expression *ir) case ir_unop_f2i: assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); - assert(ir->type->is_integer()); + assert(ir->type->base_type == GLSL_TYPE_INT); break; case ir_unop_i2f: assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); @@ -269,17 +269,25 @@ ir_validate::visit_leave(ir_expression *ir) assert(ir->type->base_type == GLSL_TYPE_FLOAT); break; case ir_unop_i2b: - assert(ir->operands[0]->type->is_integer()); + assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); assert(ir->type->base_type == GLSL_TYPE_BOOL); break; case ir_unop_b2i: assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); - assert(ir->type->is_integer()); + assert(ir->type->base_type == GLSL_TYPE_INT); break; case ir_unop_u2f: assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT); assert(ir->type->base_type == GLSL_TYPE_FLOAT); break; + case ir_unop_i2u: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); + assert(ir->type->base_type == GLSL_TYPE_UINT); + break; + case ir_unop_u2i: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT); + assert(ir->type->base_type == GLSL_TYPE_INT); + break; case ir_unop_any: assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 255edc6a76f..b6479e7a3a4 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -1405,8 +1405,9 @@ demote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode) } -void -assign_varying_locations(struct gl_shader_program *prog, +bool +assign_varying_locations(struct gl_context *ctx, + struct gl_shader_program *prog, gl_shader *producer, gl_shader *consumer) { /* FINISHME: Set dynamically when geometry shader support is added. */ @@ -1462,6 +1463,8 @@ assign_varying_locations(struct gl_shader_program *prog, } } + unsigned varying_vectors = 0; + foreach_list(node, consumer->ir) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); @@ -1492,8 +1495,32 @@ assign_varying_locations(struct gl_shader_program *prog, * value is written by the previous stage. */ var->mode = ir_var_auto; + } else { + /* The packing rules are used for vertex shader inputs are also used + * for fragment shader inputs. + */ + varying_vectors += count_attribute_slots(var->type); } } + + if (ctx->API == API_OPENGLES2 || prog->Version == 100) { + if (varying_vectors > ctx->Const.MaxVarying) { + linker_error_printf(prog, "shader uses too many varying vectors " + "(%u > %u)\n", + varying_vectors, ctx->Const.MaxVarying); + return false; + } + } else { + const unsigned float_components = varying_vectors * 4; + if (float_components > ctx->Const.MaxVarying * 4) { + linker_error_printf(prog, "shader uses too many varying components " + "(%u > %u)\n", + float_components, ctx->Const.MaxVarying * 4); + return false; + } + } + + return true; } @@ -1666,9 +1693,13 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) if (prog->_LinkedShaders[i] == NULL) continue; - assign_varying_locations(prog, - prog->_LinkedShaders[prev], - prog->_LinkedShaders[i]); + if (!assign_varying_locations(ctx, prog, + prog->_LinkedShaders[prev], + prog->_LinkedShaders[i])) { + prog->LinkStatus = false; + goto done; + } + prev = i; } diff --git a/src/glsl/lower_if_to_cond_assign.cpp b/src/glsl/lower_if_to_cond_assign.cpp index e3a1065d996..b637eb4fe1d 100644 --- a/src/glsl/lower_if_to_cond_assign.cpp +++ b/src/glsl/lower_if_to_cond_assign.cpp @@ -149,11 +149,9 @@ ir_visitor_status ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir) { /* Only flatten when beyond the GPU's maximum supported nesting depth. */ - if (this->depth <= this->max_depth) + if (this->depth-- <= this->max_depth) return visit_continue; - this->depth--; - bool found_control_flow = false; ir_variable *cond_var; ir_assignment *assign; diff --git a/src/glsl/lower_instructions.cpp b/src/glsl/lower_instructions.cpp index a5f61f213d0..806f8639959 100644 --- a/src/glsl/lower_instructions.cpp +++ b/src/glsl/lower_instructions.cpp @@ -168,8 +168,13 @@ lower_instructions_visitor::div_to_mul_rcp(ir_expression *ir) op0 = new(ir) ir_expression(ir_binop_mul, vec_type, op0, op1); - ir->operation = ir_unop_f2i; - ir->operands[0] = op0; + if (ir->operands[1]->type->base_type == GLSL_TYPE_INT) { + ir->operation = ir_unop_f2i; + ir->operands[0] = op0; + } else { + ir->operation = ir_unop_i2u; + ir->operands[0] = new(ir) ir_expression(ir_unop_f2i, op0); + } ir->operands[1] = NULL; } @@ -271,7 +276,7 @@ lower_instructions_visitor::visit_leave(ir_expression *ir) break; case ir_binop_mod: - if (lowering(MOD_TO_FRACT)) + if (lowering(MOD_TO_FRACT) && ir->type->is_float()) mod_to_fract(ir); break; diff --git a/src/glsl/lower_mat_op_to_vec.cpp b/src/glsl/lower_mat_op_to_vec.cpp index 8cbbfa713c9..a371afc14c2 100644 --- a/src/glsl/lower_mat_op_to_vec.cpp +++ b/src/glsl/lower_mat_op_to_vec.cpp @@ -45,19 +45,19 @@ public: ir_visitor_status visit_leave(ir_assignment *); - ir_dereference *get_column(ir_variable *var, int col); - ir_rvalue *get_element(ir_variable *var, int col, int row); - - void do_mul_mat_mat(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_mul_mat_vec(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_mul_vec_mat(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_mul_mat_scalar(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_equal_mat_mat(ir_variable *result_var, ir_variable *a_var, - ir_variable *b_var, bool test_equal); + ir_dereference *get_column(ir_dereference *val, int col); + ir_rvalue *get_element(ir_dereference *val, int col, int row); + + void do_mul_mat_mat(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_mul_mat_vec(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_mul_vec_mat(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_mul_mat_scalar(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_equal_mat_mat(ir_dereference *result, ir_dereference *a, + ir_dereference *b, bool test_equal); void *mem_ctx; bool made_progress; @@ -97,182 +97,137 @@ do_mat_op_to_vec(exec_list *instructions) } ir_rvalue * -ir_mat_op_to_vec_visitor::get_element(ir_variable *var, int col, int row) +ir_mat_op_to_vec_visitor::get_element(ir_dereference *val, int col, int row) { - ir_dereference *deref; + val = get_column(val, col); - deref = new(mem_ctx) ir_dereference_variable(var); - - if (var->type->is_matrix()) { - deref = new(mem_ctx) ir_dereference_array(var, - new(mem_ctx) ir_constant(col)); - } else { - assert(col == 0); - } - - return new(mem_ctx) ir_swizzle(deref, row, 0, 0, 0, 1); + return new(mem_ctx) ir_swizzle(val, row, 0, 0, 0, 1); } ir_dereference * -ir_mat_op_to_vec_visitor::get_column(ir_variable *var, int row) +ir_mat_op_to_vec_visitor::get_column(ir_dereference *val, int row) { - ir_dereference *deref; - - if (!var->type->is_matrix()) { - deref = new(mem_ctx) ir_dereference_variable(var); - } else { - deref = new(mem_ctx) ir_dereference_variable(var); - deref = new(mem_ctx) ir_dereference_array(deref, - new(mem_ctx) ir_constant(row)); + val = val->clone(mem_ctx, NULL); + + if (val->type->is_matrix()) { + val = new(mem_ctx) ir_dereference_array(val, + new(mem_ctx) ir_constant(row)); } - return deref; + return val; } void -ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) +ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int b_col, i; ir_assignment *assign; ir_expression *expr; - for (b_col = 0; b_col < b_var->type->matrix_columns; b_col++) { - ir_rvalue *a = get_column(a_var, 0); - ir_rvalue *b = get_element(b_var, b_col, 0); - + for (b_col = 0; b_col < b->type->matrix_columns; b_col++) { /* first column */ expr = new(mem_ctx) ir_expression(ir_binop_mul, - a->type, - a, - b); + get_column(a, 0), + get_element(b, b_col, 0)); /* following columns */ - for (i = 1; i < a_var->type->matrix_columns; i++) { + for (i = 1; i < a->type->matrix_columns; i++) { ir_expression *mul_expr; - a = get_column(a_var, i); - b = get_element(b_var, b_col, i); - mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, - a->type, - a, - b); + get_column(a, i), + get_element(b, b_col, i)); expr = new(mem_ctx) ir_expression(ir_binop_add, - a->type, expr, mul_expr); } - ir_rvalue *result = get_column(result_var, b_col); - assign = new(mem_ctx) ir_assignment(result, - expr, - NULL); + assign = new(mem_ctx) ir_assignment(get_column(result, b_col), expr); base_ir->insert_before(assign); } } void -ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) +ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int i; - ir_rvalue *a = get_column(a_var, 0); - ir_rvalue *b = get_element(b_var, 0, 0); ir_assignment *assign; ir_expression *expr; /* first column */ expr = new(mem_ctx) ir_expression(ir_binop_mul, - result_var->type, - a, - b); + get_column(a, 0), + get_element(b, 0, 0)); /* following columns */ - for (i = 1; i < a_var->type->matrix_columns; i++) { + for (i = 1; i < a->type->matrix_columns; i++) { ir_expression *mul_expr; - a = get_column(a_var, i); - b = get_element(b_var, 0, i); - mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, - result_var->type, - a, - b); - expr = new(mem_ctx) ir_expression(ir_binop_add, - result_var->type, - expr, - mul_expr); + get_column(a, i), + get_element(b, 0, i)); + expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr); } - ir_rvalue *result = new(mem_ctx) ir_dereference_variable(result_var); - assign = new(mem_ctx) ir_assignment(result, - expr, - NULL); + result = result->clone(mem_ctx, NULL); + assign = new(mem_ctx) ir_assignment(result, expr); base_ir->insert_before(assign); } void -ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) +ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int i; - for (i = 0; i < b_var->type->matrix_columns; i++) { - ir_rvalue *a = new(mem_ctx) ir_dereference_variable(a_var); - ir_rvalue *b = get_column(b_var, i); - ir_rvalue *result; + for (i = 0; i < b->type->matrix_columns; i++) { + ir_rvalue *column_result; ir_expression *column_expr; ir_assignment *column_assign; - result = new(mem_ctx) ir_dereference_variable(result_var); - result = new(mem_ctx) ir_swizzle(result, i, 0, 0, 0, 1); + column_result = result->clone(mem_ctx, NULL); + column_result = new(mem_ctx) ir_swizzle(column_result, i, 0, 0, 0, 1); column_expr = new(mem_ctx) ir_expression(ir_binop_dot, - result->type, - a, - b); + a->clone(mem_ctx, NULL), + get_column(b, i)); - column_assign = new(mem_ctx) ir_assignment(result, - column_expr, - NULL); + column_assign = new(mem_ctx) ir_assignment(column_result, + column_expr); base_ir->insert_before(column_assign); } } void -ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) +ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int i; - for (i = 0; i < a_var->type->matrix_columns; i++) { - ir_rvalue *a = get_column(a_var, i); - ir_rvalue *b = new(mem_ctx) ir_dereference_variable(b_var); - ir_rvalue *result = get_column(result_var, i); + for (i = 0; i < a->type->matrix_columns; i++) { ir_expression *column_expr; ir_assignment *column_assign; column_expr = new(mem_ctx) ir_expression(ir_binop_mul, - result->type, - a, - b); + get_column(a, i), + b->clone(mem_ctx, NULL)); - column_assign = new(mem_ctx) ir_assignment(result, - column_expr, - NULL); + column_assign = new(mem_ctx) ir_assignment(get_column(result, i), + column_expr); base_ir->insert_before(column_assign); } } void -ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var, +ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_dereference *result, + ir_dereference *a, + ir_dereference *b, bool test_equal) { /* This essentially implements the following GLSL: @@ -293,7 +248,7 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, * a[3] != b[3]); * } */ - const unsigned columns = a_var->type->matrix_columns; + const unsigned columns = a->type->matrix_columns; const glsl_type *const bvec_type = glsl_type::get_instance(GLSL_TYPE_BOOL, columns, 1); @@ -303,12 +258,10 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, this->base_ir->insert_before(tmp_bvec); for (unsigned i = 0; i < columns; i++) { - ir_dereference *const op0 = get_column(a_var, i); - ir_dereference *const op1 = get_column(b_var, i); - ir_expression *const cmp = new(this->mem_ctx) ir_expression(ir_binop_any_nequal, - glsl_type::bool_type, op0, op1); + get_column(a, i), + get_column(b, i)); ir_dereference *const lhs = new(this->mem_ctx) ir_dereference_variable(tmp_bvec); @@ -319,23 +272,14 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, this->base_ir->insert_before(assign); } - ir_rvalue *const val = - new(this->mem_ctx) ir_dereference_variable(tmp_bvec); - - ir_expression *any = - new(this->mem_ctx) ir_expression(ir_unop_any, glsl_type::bool_type, - val, NULL); + ir_rvalue *const val = new(this->mem_ctx) ir_dereference_variable(tmp_bvec); + ir_expression *any = new(this->mem_ctx) ir_expression(ir_unop_any, val); if (test_equal) - any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, - glsl_type::bool_type, - any, NULL); - - ir_rvalue *const result = - new(this->mem_ctx) ir_dereference_variable(result_var); + any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, any); ir_assignment *const assign = - new(mem_ctx) ir_assignment(result, any, NULL); + new(mem_ctx) ir_assignment(result->clone(mem_ctx, NULL), any); base_ir->insert_before(assign); } @@ -358,7 +302,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) { ir_expression *orig_expr = orig_assign->rhs->as_expression(); unsigned int i, matrix_columns = 1; - ir_variable *op_var[2]; + ir_dereference *op[2]; if (!orig_expr) return visit_continue; @@ -370,51 +314,53 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) mem_ctx = ralloc_parent(orig_assign); - ir_dereference_variable *lhs_deref = + ir_dereference_variable *result = orig_assign->lhs->as_dereference_variable(); - assert(lhs_deref); - - ir_variable *result_var = lhs_deref->var; + assert(result); /* Store the expression operands in temps so we can use them * multiple times. */ for (i = 0; i < orig_expr->get_num_operands(); i++) { ir_assignment *assign; + ir_dereference *deref = orig_expr->operands[i]->as_dereference(); - op_var[i] = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, - "mat_op_to_vec", - ir_var_temporary); - base_ir->insert_before(op_var[i]); + /* Avoid making a temporary if we don't need to to avoid aliasing. */ + if (deref && + deref->variable_referenced() != result->variable_referenced()) { + op[i] = deref; + continue; + } - lhs_deref = new(mem_ctx) ir_dereference_variable(op_var[i]); - assign = new(mem_ctx) ir_assignment(lhs_deref, - orig_expr->operands[i], - NULL); + /* Otherwise, store the operand in a temporary generally if it's + * not a dereference. + */ + ir_variable *var = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, + "mat_op_to_vec", + ir_var_temporary); + base_ir->insert_before(var); + + /* Note that we use this dereference for the assignment. That means + * that others that want to use op[i] have to clone the deref. + */ + op[i] = new(mem_ctx) ir_dereference_variable(var); + assign = new(mem_ctx) ir_assignment(op[i], orig_expr->operands[i]); base_ir->insert_before(assign); } /* OK, time to break down this matrix operation. */ switch (orig_expr->operation) { case ir_unop_neg: { - const unsigned mask = (1U << result_var->type->vector_elements) - 1; - /* Apply the operation to each column.*/ for (i = 0; i < matrix_columns; i++) { - ir_rvalue *op0 = get_column(op_var[0], i); - ir_dereference *result = get_column(result_var, i); ir_expression *column_expr; ir_assignment *column_assign; column_expr = new(mem_ctx) ir_expression(orig_expr->operation, - result->type, - op0, - NULL); - - column_assign = new(mem_ctx) ir_assignment(result, - column_expr, - NULL, - mask); + get_column(op[0], i)); + + column_assign = new(mem_ctx) ir_assignment(get_column(result, i), + column_expr); assert(column_assign->write_mask != 0); base_ir->insert_before(column_assign); } @@ -424,57 +370,49 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) case ir_binop_sub: case ir_binop_div: case ir_binop_mod: { - const unsigned mask = (1U << result_var->type->vector_elements) - 1; - /* For most operations, the matrix version is just going * column-wise through and applying the operation to each column * if available. */ for (i = 0; i < matrix_columns; i++) { - ir_rvalue *op0 = get_column(op_var[0], i); - ir_rvalue *op1 = get_column(op_var[1], i); - ir_dereference *result = get_column(result_var, i); ir_expression *column_expr; ir_assignment *column_assign; column_expr = new(mem_ctx) ir_expression(orig_expr->operation, - result->type, - op0, - op1); - - column_assign = new(mem_ctx) ir_assignment(result, - column_expr, - NULL, - mask); + get_column(op[0], i), + get_column(op[1], i)); + + column_assign = new(mem_ctx) ir_assignment(get_column(result, i), + column_expr); assert(column_assign->write_mask != 0); base_ir->insert_before(column_assign); } break; } case ir_binop_mul: - if (op_var[0]->type->is_matrix()) { - if (op_var[1]->type->is_matrix()) { - do_mul_mat_mat(result_var, op_var[0], op_var[1]); - } else if (op_var[1]->type->is_vector()) { - do_mul_mat_vec(result_var, op_var[0], op_var[1]); + if (op[0]->type->is_matrix()) { + if (op[1]->type->is_matrix()) { + do_mul_mat_mat(result, op[0], op[1]); + } else if (op[1]->type->is_vector()) { + do_mul_mat_vec(result, op[0], op[1]); } else { - assert(op_var[1]->type->is_scalar()); - do_mul_mat_scalar(result_var, op_var[0], op_var[1]); + assert(op[1]->type->is_scalar()); + do_mul_mat_scalar(result, op[0], op[1]); } } else { - assert(op_var[1]->type->is_matrix()); - if (op_var[0]->type->is_vector()) { - do_mul_vec_mat(result_var, op_var[0], op_var[1]); + assert(op[1]->type->is_matrix()); + if (op[0]->type->is_vector()) { + do_mul_vec_mat(result, op[0], op[1]); } else { - assert(op_var[0]->type->is_scalar()); - do_mul_mat_scalar(result_var, op_var[1], op_var[0]); + assert(op[0]->type->is_scalar()); + do_mul_mat_scalar(result, op[1], op[0]); } } break; case ir_binop_all_equal: case ir_binop_any_nequal: - do_equal_mat_mat(result_var, op_var[1], op_var[0], + do_equal_mat_mat(result, op[1], op[0], (orig_expr->operation == ir_binop_all_equal)); break; diff --git a/src/glsl/main.cpp b/src/glsl/main.cpp index 096da93dcef..7952bb1a3e3 100644 --- a/src/glsl/main.cpp +++ b/src/glsl/main.cpp @@ -76,6 +76,7 @@ initialize_context(struct gl_context *ctx, gl_api api) ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE; ctx->Extensions.EXT_texture_array = GL_TRUE; ctx->Extensions.NV_texture_rectangle = GL_TRUE; + ctx->Extensions.EXT_texture3D = GL_TRUE; /* GLSL 1.30 isn't fully supported, but we need to advertise 1.30 so that * the built-in functions for 1.30 can be built. diff --git a/src/glsl/opt_discard_simplification.cpp b/src/glsl/opt_discard_simplification.cpp index 7c2928d271c..a19947ddd6c 100644 --- a/src/glsl/opt_discard_simplification.cpp +++ b/src/glsl/opt_discard_simplification.cpp @@ -104,9 +104,23 @@ static ir_discard * find_unconditional_discard(exec_list &instructions) { foreach_list(n, &instructions) { - ir_discard *ir = ((ir_instruction *) n)->as_discard(); - if (ir != NULL && ir->condition == NULL) - return ir; + ir_instruction *ir = (ir_instruction *)n; + + if (ir->ir_type == ir_type_return || + ir->ir_type == ir_type_loop_jump) + return NULL; + + /* So far, this code doesn't know how to look inside of flow + * control to see if a discard later on at this level is + * unconditional. + */ + if (ir->ir_type == ir_type_if || + ir->ir_type == ir_type_loop) + return NULL; + + ir_discard *discard = ir->as_discard(); + if (discard != NULL && discard->condition == NULL) + return discard; } return NULL; } diff --git a/src/glw/GLwDrawA.h b/src/glw/GLwDrawA.h index cd631b4fb57..b9711c216bc 100644 --- a/src/glw/GLwDrawA.h +++ b/src/glw/GLwDrawA.h @@ -136,7 +136,7 @@ typedef struct _GLwMDrawingAreaClassRec *GLwMDrawingAreaWidgetClass; typedef struct _GLwMDrawingAreaRec *GLwMDrawingAreaWidget; -extern WidgetClass glwMDrawingAreaWidgetClass; +GLAPI WidgetClass glwMDrawingAreaWidgetClass; #else @@ -144,7 +144,7 @@ extern WidgetClass glwMDrawingAreaWidgetClass; typedef struct _GLwDrawingAreaClassRec *GLwDrawingAreaWidgetClass; typedef struct _GLwDrawingAreaRec *GLwDrawingAreaWidget; -extern WidgetClass glwDrawingAreaWidgetClass; +GLAPI WidgetClass glwDrawingAreaWidgetClass; #endif @@ -177,8 +177,8 @@ extern "C" { #endif /* front ends to glXMakeCurrent and glXSwapBuffers */ -extern void GLwDrawingAreaMakeCurrent(Widget w,GLXContext ctx); -extern void GLwDrawingAreaSwapBuffers(Widget w); +GLAPI void GLwDrawingAreaMakeCurrent(Widget w,GLXContext ctx); +GLAPI void GLwDrawingAreaSwapBuffers(Widget w); #ifdef __GLX_MOTIF #ifdef _NO_PROTO diff --git a/src/glw/GLwDrawAP.h b/src/glw/GLwDrawAP.h index f1217019541..4ff21b426dd 100644 --- a/src/glw/GLwDrawAP.h +++ b/src/glw/GLwDrawAP.h @@ -59,7 +59,7 @@ typedef struct _GLwMDrawingAreaClassRec { } GLwMDrawingAreaClassRec; -extern GLwMDrawingAreaClassRec glwMDrawingAreaClassRec; +GLAPI GLwMDrawingAreaClassRec glwMDrawingAreaClassRec; /* XT */ @@ -70,7 +70,7 @@ typedef struct _GLwDrawingAreaClassRec { GLwDrawingAreaClassPart glwDrawingArea_class; } GLwDrawingAreaClassRec; -extern GLwDrawingAreaClassRec glwDrawingAreaClassRec; +GLAPI GLwDrawingAreaClassRec glwDrawingAreaClassRec; #endif diff --git a/src/glx/SConscript b/src/glx/SConscript new file mode 100644 index 00000000000..afef33727df --- /dev/null +++ b/src/glx/SConscript @@ -0,0 +1,85 @@ +Import('*') + +if env['platform'] == 'windows': + Return() + +env = env.Clone() + +env.Prepend(CPPPATH = [ + '#include', + '#include/GL/internal', + '#src/mesa', + '#src/mapi', + '#src/mapi/glapi', + #$(LIBDRM_CFLAGS) + #$(DRI2PROTO_CFLAGS) + #$(GLPROTO_CFLAGS) + #$(X11_INCLUDES) +]) + +env.Append(CPPDEFINES = [ + '_REENTRANT', + #('DEFAULT_DRIVER_DIR', 'DRI_DRIVER_SEARCH_DIR') +]) + +env.Prepend(LIBS = [ + glapi +]) + +env.PkgUseModules('X11') +env.PkgUseModules('DRM') + +if env['HAVE_XF86VIDMODE']: + env.Append(CPPDEFINES = ['XF86VIDMODE']) + env.PkgUseModules('XF86VIDMODE') + +if False: # XXX: SHARED_GLAPI + env.Append(CPPDEFINES = ['GLX_SHARED_GLAPI']) + +sources = [ + 'clientattrib.c', + 'compsize.c', + 'eval.c', + 'glxconfig.c', + 'glxcmds.c', + 'glxcurrent.c', + 'glxext.c', + 'glxextensions.c', + 'indirect_glx.c', + 'indirect.c', + 'indirect_init.c', + 'indirect_size.c', + 'indirect_window_pos.c', + 'indirect_texture_compression.c', + 'indirect_transpose_matrix.c', + 'indirect_vertex_array.c', + 'indirect_vertex_program.c', + 'pixel.c', + 'pixelstore.c', + 'render2.c', + 'renderpix.c', + 'single2.c', + 'singlepix.c', + 'vertarr.c', + 'xfont.c', + 'glx_pbuffer.c', + 'glx_query.c', + 'drisw_glx.c', + 'dri_common.c', + 'dri_glx.c', + 'XF86dri.c', + 'glxhash.c', + 'dri2_glx.c', + 'dri2.c', + 'applegl_glx.c', +] + +libgl = env.SharedLibrary( + target ='GL', + source = sources, +) + +libgl = env.InstallSharedLibrary(libgl, version=(1, 2)) + +env.Alias('glx', libgl) +env.Alias('libgl', libgl) diff --git a/src/glx/apple/apple_cgl.c b/src/glx/apple/apple_cgl.c index 737d757ed52..648ed869497 100644 --- a/src/glx/apple/apple_cgl.c +++ b/src/glx/apple/apple_cgl.c @@ -64,7 +64,6 @@ void apple_cgl_init(void) { void *h; - GLint major = 0, minor = 0; const char *opengl_framework_path; if (initialized) @@ -88,11 +87,11 @@ apple_cgl_init(void) apple_cgl.get_version = sym(h, "CGLGetVersion"); - apple_cgl.get_version(&major, &minor); + apple_cgl.get_version(&apple_cgl.version_major, &apple_cgl.version_minor); - apple_glx_diagnostic("CGL major %d minor %d\n", major, minor); + apple_glx_diagnostic("CGL major %d minor %d\n", apple_cgl.version_major, apple_cgl.version_minor); - if (1 != major) { + if (1 != apple_cgl.version_major) { fprintf(stderr, "WARNING: the CGL major version has changed!\n" "libGL may be incompatible!\n"); } diff --git a/src/glx/apple/apple_cgl.h b/src/glx/apple/apple_cgl.h index 5e98a00fe79..002c7e64bad 100644 --- a/src/glx/apple/apple_cgl.h +++ b/src/glx/apple/apple_cgl.h @@ -40,7 +40,8 @@ struct apple_cgl_api { - void (*get_version) (GLint * majorvers, GLint * minorvers); + GLint version_major, version_minor; + void (*get_version) (GLint * version_major, GLint * version_minor); CGLError(*choose_pixel_format) (const CGLPixelFormatAttribute * attribs, CGLPixelFormatObj * pix, GLint * npix); diff --git a/src/glx/apple/apple_glapi.c b/src/glx/apple/apple_glapi.c index f60cacece76..34f726efb64 100644 --- a/src/glx/apple/apple_glapi.c +++ b/src/glx/apple/apple_glapi.c @@ -44,1156 +44,20 @@ #include "apple_glx.h" #include "apple_xgl_api.h" - -#ifndef OPENGL_FRAMEWORK_PATH -#define OPENGL_FRAMEWORK_PATH "/System/Library/Frameworks/OpenGL.framework/OpenGL" -#endif +#include "apple_cgl.h" struct _glapi_table * __ogl_framework_api = NULL; struct _glapi_table * __applegl_api = NULL; -void apple_xgl_init_direct(void) { - static void *handle; - const char *opengl_framework_path; - +void apple_glapi_set_dispatch(void) { if(__applegl_api) { _glapi_set_dispatch(__applegl_api); return; } - opengl_framework_path = getenv("OPENGL_FRAMEWORK_PATH"); - if (!opengl_framework_path) { - opengl_framework_path = OPENGL_FRAMEWORK_PATH; - } - - (void) dlerror(); /*drain dlerror */ - handle = dlopen(opengl_framework_path, RTLD_LOCAL); - - if (!handle) { - fprintf(stderr, "error: unable to dlopen %s : %s\n", - opengl_framework_path, dlerror()); - abort(); - } - - __ogl_framework_api = calloc(1, sizeof(struct _glapi_table)); + __ogl_framework_api = _glapi_create_table_from_handle(apple_cgl_get_dl_handle(), "gl"); assert(__ogl_framework_api); - /* to update: - * for f in $(grep SET_ ../../mesa/main/dispatch.h | grep INLINE | sed 's:^.*\(SET_[^(]*\)(.*$:\1:' | sort -u); do grep -q "$f(" apple_glapi.c || echo $f ; done | sed 's:SET_\(.*\)$: SET_\1(__ogl_framework_api, dlsym(handle, "gl\1"))\;:' - */ - - SET_Accum(__ogl_framework_api, dlsym(handle, "glAccum")); - SET_AlphaFunc(__ogl_framework_api, dlsym(handle, "glAlphaFunc")); - SET_AreTexturesResident(__ogl_framework_api, dlsym(handle, "glAreTexturesResident")); - SET_ArrayElement(__ogl_framework_api, dlsym(handle, "glArrayElement")); - SET_Begin(__ogl_framework_api, dlsym(handle, "glBegin")); - SET_BindTexture(__ogl_framework_api, dlsym(handle, "glBindTexture")); - SET_Bitmap(__ogl_framework_api, dlsym(handle, "glBitmap")); - SET_BlendColor(__ogl_framework_api, dlsym(handle, "glBlendColor")); - SET_BlendEquation(__ogl_framework_api, dlsym(handle, "glBlendEquation")); - SET_BlendFunc(__ogl_framework_api, dlsym(handle, "glBlendFunc")); - SET_CallList(__ogl_framework_api, dlsym(handle, "glCallList")); - SET_CallLists(__ogl_framework_api, dlsym(handle, "glCallLists")); - SET_Clear(__ogl_framework_api, dlsym(handle, "glClear")); - SET_ClearAccum(__ogl_framework_api, dlsym(handle, "glClearAccum")); - SET_ClearColor(__ogl_framework_api, dlsym(handle, "glClearColor")); - SET_ClearDepth(__ogl_framework_api, dlsym(handle, "glClearDepth")); - SET_ClearIndex(__ogl_framework_api, dlsym(handle, "glClearIndex")); - SET_ClearStencil(__ogl_framework_api, dlsym(handle, "glClearStencil")); - SET_ClipPlane(__ogl_framework_api, dlsym(handle, "glClipPlane")); - SET_Color3b(__ogl_framework_api, dlsym(handle, "glColor3b")); - SET_Color3bv(__ogl_framework_api, dlsym(handle, "glColor3bv")); - SET_Color3d(__ogl_framework_api, dlsym(handle, "glColor3d")); - SET_Color3dv(__ogl_framework_api, dlsym(handle, "glColor3dv")); - SET_Color3f(__ogl_framework_api, dlsym(handle, "glColor3f")); - SET_Color3fv(__ogl_framework_api, dlsym(handle, "glColor3fv")); - SET_Color3i(__ogl_framework_api, dlsym(handle, "glColor3i")); - SET_Color3iv(__ogl_framework_api, dlsym(handle, "glColor3iv")); - SET_Color3s(__ogl_framework_api, dlsym(handle, "glColor3s")); - SET_Color3sv(__ogl_framework_api, dlsym(handle, "glColor3sv")); - SET_Color3ub(__ogl_framework_api, dlsym(handle, "glColor3ub")); - SET_Color3ubv(__ogl_framework_api, dlsym(handle, "glColor3ubv")); - SET_Color3ui(__ogl_framework_api, dlsym(handle, "glColor3ui")); - SET_Color3uiv(__ogl_framework_api, dlsym(handle, "glColor3uiv")); - SET_Color3us(__ogl_framework_api, dlsym(handle, "glColor3us")); - SET_Color3usv(__ogl_framework_api, dlsym(handle, "glColor3usv")); - SET_Color4b(__ogl_framework_api, dlsym(handle, "glColor4b")); - SET_Color4bv(__ogl_framework_api, dlsym(handle, "glColor4bv")); - SET_Color4d(__ogl_framework_api, dlsym(handle, "glColor4d")); - SET_Color4dv(__ogl_framework_api, dlsym(handle, "glColor4dv")); - SET_Color4f(__ogl_framework_api, dlsym(handle, "glColor4f")); - SET_Color4fv(__ogl_framework_api, dlsym(handle, "glColor4fv")); - SET_Color4i(__ogl_framework_api, dlsym(handle, "glColor4i")); - SET_Color4iv(__ogl_framework_api, dlsym(handle, "glColor4iv")); - SET_Color4s(__ogl_framework_api, dlsym(handle, "glColor4s")); - SET_Color4sv(__ogl_framework_api, dlsym(handle, "glColor4sv")); - SET_Color4ub(__ogl_framework_api, dlsym(handle, "glColor4ub")); - SET_Color4ubv(__ogl_framework_api, dlsym(handle, "glColor4ubv")); - SET_Color4ui(__ogl_framework_api, dlsym(handle, "glColor4ui")); - SET_Color4uiv(__ogl_framework_api, dlsym(handle, "glColor4uiv")); - SET_Color4us(__ogl_framework_api, dlsym(handle, "glColor4us")); - SET_Color4usv(__ogl_framework_api, dlsym(handle, "glColor4usv")); - SET_ColorMask(__ogl_framework_api, dlsym(handle, "glColorMask")); - SET_ColorMaterial(__ogl_framework_api, dlsym(handle, "glColorMaterial")); - SET_ColorPointer(__ogl_framework_api, dlsym(handle, "glColorPointer")); - SET_ColorSubTable(__ogl_framework_api, dlsym(handle, "glColorSubTable")); - SET_ColorTable(__ogl_framework_api, dlsym(handle, "glColorTable")); - SET_ColorTableParameterfv(__ogl_framework_api, dlsym(handle, "glColorTableParameterfv")); - SET_ColorTableParameteriv(__ogl_framework_api, dlsym(handle, "glColorTableParameteriv")); - SET_ConvolutionFilter1D(__ogl_framework_api, dlsym(handle, "glConvolutionFilter1D")); - SET_ConvolutionFilter2D(__ogl_framework_api, dlsym(handle, "glConvolutionFilter2D")); - SET_ConvolutionParameterf(__ogl_framework_api, dlsym(handle, "glConvolutionParameterf")); - SET_ConvolutionParameterfv(__ogl_framework_api, dlsym(handle, "glConvolutionParameterfv")); - SET_ConvolutionParameteri(__ogl_framework_api, dlsym(handle, "glConvolutionParameteri")); - SET_ConvolutionParameteriv(__ogl_framework_api, dlsym(handle, "glConvolutionParameteriv")); - SET_CopyColorSubTable(__ogl_framework_api, dlsym(handle, "glCopyColorSubTable")); - SET_CopyColorTable(__ogl_framework_api, dlsym(handle, "glCopyColorTable")); - SET_CopyConvolutionFilter1D(__ogl_framework_api, dlsym(handle, "glCopyConvolutionFilter1D")); - SET_CopyConvolutionFilter2D(__ogl_framework_api, dlsym(handle, "glCopyConvolutionFilter2D")); - SET_CopyPixels(__ogl_framework_api, dlsym(handle, "glCopyPixels")); - SET_CopyTexImage1D(__ogl_framework_api, dlsym(handle, "glCopyTexImage1D")); - SET_CopyTexImage2D(__ogl_framework_api, dlsym(handle, "glCopyTexImage2D")); - SET_CopyTexSubImage1D(__ogl_framework_api, dlsym(handle, "glCopyTexSubImage1D")); - SET_CopyTexSubImage2D(__ogl_framework_api, dlsym(handle, "glCopyTexSubImage2D")); - SET_CopyTexSubImage3D(__ogl_framework_api, dlsym(handle, "glCopyTexSubImage3D")); - SET_CullFace(__ogl_framework_api, dlsym(handle, "glCullFace")); - SET_DeleteLists(__ogl_framework_api, dlsym(handle, "glDeleteLists")); - SET_DeleteTextures(__ogl_framework_api, dlsym(handle, "glDeleteTextures")); - SET_DepthFunc(__ogl_framework_api, dlsym(handle, "glDepthFunc")); - SET_DepthMask(__ogl_framework_api, dlsym(handle, "glDepthMask")); - SET_DepthRange(__ogl_framework_api, dlsym(handle, "glDepthRange")); - SET_Disable(__ogl_framework_api, dlsym(handle, "glDisable")); - SET_DisableClientState(__ogl_framework_api, dlsym(handle, "glDisableClientState")); - SET_DrawArrays(__ogl_framework_api, dlsym(handle, "glDrawArrays")); - SET_DrawBuffer(__ogl_framework_api, dlsym(handle, "glDrawBuffer")); - SET_DrawElements(__ogl_framework_api, dlsym(handle, "glDrawElements")); - SET_DrawPixels(__ogl_framework_api, dlsym(handle, "glDrawPixels")); - SET_DrawRangeElements(__ogl_framework_api, dlsym(handle, "glDrawRangeElements")); - SET_EdgeFlag(__ogl_framework_api, dlsym(handle, "glEdgeFlag")); - SET_EdgeFlagPointer(__ogl_framework_api, dlsym(handle, "glEdgeFlagPointer")); - SET_EdgeFlagv(__ogl_framework_api, dlsym(handle, "glEdgeFlagv")); - SET_Enable(__ogl_framework_api, dlsym(handle, "glEnable")); - SET_EnableClientState(__ogl_framework_api, dlsym(handle, "glEnableClientState")); - SET_End(__ogl_framework_api, dlsym(handle, "glEnd")); - SET_EndList(__ogl_framework_api, dlsym(handle, "glEndList")); - SET_EvalCoord1d(__ogl_framework_api, dlsym(handle, "glEvalCoord1d")); - SET_EvalCoord1dv(__ogl_framework_api, dlsym(handle, "glEvalCoord1dv")); - SET_EvalCoord1f(__ogl_framework_api, dlsym(handle, "glEvalCoord1f")); - SET_EvalCoord1fv(__ogl_framework_api, dlsym(handle, "glEvalCoord1fv")); - SET_EvalCoord2d(__ogl_framework_api, dlsym(handle, "glEvalCoord2d")); - SET_EvalCoord2dv(__ogl_framework_api, dlsym(handle, "glEvalCoord2dv")); - SET_EvalCoord2f(__ogl_framework_api, dlsym(handle, "glEvalCoord2f")); - SET_EvalCoord2fv(__ogl_framework_api, dlsym(handle, "glEvalCoord2fv")); - SET_EvalMesh1(__ogl_framework_api, dlsym(handle, "glEvalMesh1")); - SET_EvalMesh2(__ogl_framework_api, dlsym(handle, "glEvalMesh2")); - SET_EvalPoint1(__ogl_framework_api, dlsym(handle, "glEvalPoint1")); - SET_EvalPoint2(__ogl_framework_api, dlsym(handle, "glEvalPoint2")); - SET_FeedbackBuffer(__ogl_framework_api, dlsym(handle, "glFeedbackBuffer")); - SET_Finish(__ogl_framework_api, dlsym(handle, "glFinish")); - SET_Flush(__ogl_framework_api, dlsym(handle, "glFlush")); - SET_Fogf(__ogl_framework_api, dlsym(handle, "glFogf")); - SET_Fogfv(__ogl_framework_api, dlsym(handle, "glFogfv")); - SET_Fogi(__ogl_framework_api, dlsym(handle, "glFogi")); - SET_Fogiv(__ogl_framework_api, dlsym(handle, "glFogiv")); - SET_FrontFace(__ogl_framework_api, dlsym(handle, "glFrontFace")); - SET_Frustum(__ogl_framework_api, dlsym(handle, "glFrustum")); - SET_GenLists(__ogl_framework_api, dlsym(handle, "glGenLists")); - SET_GenTextures(__ogl_framework_api, dlsym(handle, "glGenTextures")); - SET_GetBooleanv(__ogl_framework_api, dlsym(handle, "glGetBooleanv")); - SET_GetClipPlane(__ogl_framework_api, dlsym(handle, "glGetClipPlane")); - SET_GetColorTable(__ogl_framework_api, dlsym(handle, "glGetColorTable")); - SET_GetColorTableParameterfv(__ogl_framework_api, dlsym(handle, "glGetColorTableParameterfv")); - SET_GetColorTableParameteriv(__ogl_framework_api, dlsym(handle, "glGetColorTableParameteriv")); - SET_GetConvolutionFilter(__ogl_framework_api, dlsym(handle, "glGetConvolutionFilter")); - SET_GetConvolutionParameterfv(__ogl_framework_api, dlsym(handle, "glGetConvolutionParameterfv")); - SET_GetConvolutionParameteriv(__ogl_framework_api, dlsym(handle, "glGetConvolutionParameteriv")); - SET_GetDoublev(__ogl_framework_api, dlsym(handle, "glGetDoublev")); - SET_GetError(__ogl_framework_api, dlsym(handle, "glGetError")); - SET_GetFloatv(__ogl_framework_api, dlsym(handle, "glGetFloatv")); - SET_GetHistogram(__ogl_framework_api, dlsym(handle, "glGetHistogram")); - SET_GetHistogramParameterfv(__ogl_framework_api, dlsym(handle, "glGetHistogramParameterfv")); - SET_GetHistogramParameteriv(__ogl_framework_api, dlsym(handle, "glGetHistogramParameteriv")); - SET_GetIntegerv(__ogl_framework_api, dlsym(handle, "glGetIntegerv")); - SET_GetLightfv(__ogl_framework_api, dlsym(handle, "glGetLightfv")); - SET_GetLightiv(__ogl_framework_api, dlsym(handle, "glGetLightiv")); - SET_GetMapdv(__ogl_framework_api, dlsym(handle, "glGetMapdv")); - SET_GetMapfv(__ogl_framework_api, dlsym(handle, "glGetMapfv")); - SET_GetMapiv(__ogl_framework_api, dlsym(handle, "glGetMapiv")); - SET_GetMaterialfv(__ogl_framework_api, dlsym(handle, "glGetMaterialfv")); - SET_GetMaterialiv(__ogl_framework_api, dlsym(handle, "glGetMaterialiv")); - SET_GetMinmax(__ogl_framework_api, dlsym(handle, "glGetMinmax")); - SET_GetMinmaxParameterfv(__ogl_framework_api, dlsym(handle, "glGetMinmaxParameterfv")); - SET_GetMinmaxParameteriv(__ogl_framework_api, dlsym(handle, "glGetMinmaxParameteriv")); - SET_GetPixelMapfv(__ogl_framework_api, dlsym(handle, "glGetPixelMapfv")); - SET_GetPixelMapuiv(__ogl_framework_api, dlsym(handle, "glGetPixelMapuiv")); - SET_GetPixelMapusv(__ogl_framework_api, dlsym(handle, "glGetPixelMapusv")); - SET_GetPointerv(__ogl_framework_api, dlsym(handle, "glGetPointerv")); - SET_GetPolygonStipple(__ogl_framework_api, dlsym(handle, "glGetPolygonStipple")); - SET_GetSeparableFilter(__ogl_framework_api, dlsym(handle, "glGetSeparableFilter")); - SET_GetString(__ogl_framework_api, dlsym(handle, "glGetString")); - SET_GetTexEnvfv(__ogl_framework_api, dlsym(handle, "glGetTexEnvfv")); - SET_GetTexEnviv(__ogl_framework_api, dlsym(handle, "glGetTexEnviv")); - SET_GetTexGendv(__ogl_framework_api, dlsym(handle, "glGetTexGendv")); - SET_GetTexGenfv(__ogl_framework_api, dlsym(handle, "glGetTexGenfv")); - SET_GetTexGeniv(__ogl_framework_api, dlsym(handle, "glGetTexGeniv")); - SET_GetTexImage(__ogl_framework_api, dlsym(handle, "glGetTexImage")); - SET_GetTexLevelParameterfv(__ogl_framework_api, dlsym(handle, "glGetTexLevelParameterfv")); - SET_GetTexLevelParameteriv(__ogl_framework_api, dlsym(handle, "glGetTexLevelParameteriv")); - SET_GetTexParameterfv(__ogl_framework_api, dlsym(handle, "glGetTexParameterfv")); - SET_GetTexParameteriv(__ogl_framework_api, dlsym(handle, "glGetTexParameteriv")); - SET_Hint(__ogl_framework_api, dlsym(handle, "glHint")); - SET_Histogram(__ogl_framework_api, dlsym(handle, "glHistogram")); - SET_IndexMask(__ogl_framework_api, dlsym(handle, "glIndexMask")); - SET_IndexPointer(__ogl_framework_api, dlsym(handle, "glIndexPointer")); - SET_Indexd(__ogl_framework_api, dlsym(handle, "glIndexd")); - SET_Indexdv(__ogl_framework_api, dlsym(handle, "glIndexdv")); - SET_Indexf(__ogl_framework_api, dlsym(handle, "glIndexf")); - SET_Indexfv(__ogl_framework_api, dlsym(handle, "glIndexfv")); - SET_Indexi(__ogl_framework_api, dlsym(handle, "glIndexi")); - SET_Indexiv(__ogl_framework_api, dlsym(handle, "glIndexiv")); - SET_Indexs(__ogl_framework_api, dlsym(handle, "glIndexs")); - SET_Indexsv(__ogl_framework_api, dlsym(handle, "glIndexsv")); - SET_Indexub(__ogl_framework_api, dlsym(handle, "glIndexub")); - SET_Indexubv(__ogl_framework_api, dlsym(handle, "glIndexubv")); - SET_InitNames(__ogl_framework_api, dlsym(handle, "glInitNames")); - SET_InterleavedArrays(__ogl_framework_api, dlsym(handle, "glInterleavedArrays")); - SET_IsEnabled(__ogl_framework_api, dlsym(handle, "glIsEnabled")); - SET_IsList(__ogl_framework_api, dlsym(handle, "glIsList")); - SET_IsTexture(__ogl_framework_api, dlsym(handle, "glIsTexture")); - SET_LightModelf(__ogl_framework_api, dlsym(handle, "glLightModelf")); - SET_LightModelfv(__ogl_framework_api, dlsym(handle, "glLightModelfv")); - SET_LightModeli(__ogl_framework_api, dlsym(handle, "glLightModeli")); - SET_LightModeliv(__ogl_framework_api, dlsym(handle, "glLightModeliv")); - SET_Lightf(__ogl_framework_api, dlsym(handle, "glLightf")); - SET_Lightfv(__ogl_framework_api, dlsym(handle, "glLightfv")); - SET_Lighti(__ogl_framework_api, dlsym(handle, "glLighti")); - SET_Lightiv(__ogl_framework_api, dlsym(handle, "glLightiv")); - SET_LineStipple(__ogl_framework_api, dlsym(handle, "glLineStipple")); - SET_LineWidth(__ogl_framework_api, dlsym(handle, "glLineWidth")); - SET_ListBase(__ogl_framework_api, dlsym(handle, "glListBase")); - SET_LoadIdentity(__ogl_framework_api, dlsym(handle, "glLoadIdentity")); - SET_LoadMatrixd(__ogl_framework_api, dlsym(handle, "glLoadMatrixd")); - SET_LoadMatrixf(__ogl_framework_api, dlsym(handle, "glLoadMatrixf")); - SET_LoadName(__ogl_framework_api, dlsym(handle, "glLoadName")); - SET_LogicOp(__ogl_framework_api, dlsym(handle, "glLogicOp")); - SET_Map1d(__ogl_framework_api, dlsym(handle, "glMap1d")); - SET_Map1f(__ogl_framework_api, dlsym(handle, "glMap1f")); - SET_Map2d(__ogl_framework_api, dlsym(handle, "glMap2d")); - SET_Map2f(__ogl_framework_api, dlsym(handle, "glMap2f")); - SET_MapGrid1d(__ogl_framework_api, dlsym(handle, "glMapGrid1d")); - SET_MapGrid1f(__ogl_framework_api, dlsym(handle, "glMapGrid1f")); - SET_MapGrid2d(__ogl_framework_api, dlsym(handle, "glMapGrid2d")); - SET_MapGrid2f(__ogl_framework_api, dlsym(handle, "glMapGrid2f")); - SET_Materialf(__ogl_framework_api, dlsym(handle, "glMaterialf")); - SET_Materialfv(__ogl_framework_api, dlsym(handle, "glMaterialfv")); - SET_Materiali(__ogl_framework_api, dlsym(handle, "glMateriali")); - SET_Materialiv(__ogl_framework_api, dlsym(handle, "glMaterialiv")); - SET_MatrixMode(__ogl_framework_api, dlsym(handle, "glMatrixMode")); - SET_Minmax(__ogl_framework_api, dlsym(handle, "glMinmax")); - SET_MultMatrixd(__ogl_framework_api, dlsym(handle, "glMultMatrixd")); - SET_MultMatrixf(__ogl_framework_api, dlsym(handle, "glMultMatrixf")); - SET_NewList(__ogl_framework_api, dlsym(handle, "glNewList")); - SET_Normal3b(__ogl_framework_api, dlsym(handle, "glNormal3b")); - SET_Normal3bv(__ogl_framework_api, dlsym(handle, "glNormal3bv")); - SET_Normal3d(__ogl_framework_api, dlsym(handle, "glNormal3d")); - SET_Normal3dv(__ogl_framework_api, dlsym(handle, "glNormal3dv")); - SET_Normal3f(__ogl_framework_api, dlsym(handle, "glNormal3f")); - SET_Normal3fv(__ogl_framework_api, dlsym(handle, "glNormal3fv")); - SET_Normal3i(__ogl_framework_api, dlsym(handle, "glNormal3i")); - SET_Normal3iv(__ogl_framework_api, dlsym(handle, "glNormal3iv")); - SET_Normal3s(__ogl_framework_api, dlsym(handle, "glNormal3s")); - SET_Normal3sv(__ogl_framework_api, dlsym(handle, "glNormal3sv")); - SET_NormalPointer(__ogl_framework_api, dlsym(handle, "glNormalPointer")); - SET_Ortho(__ogl_framework_api, dlsym(handle, "glOrtho")); - SET_PassThrough(__ogl_framework_api, dlsym(handle, "glPassThrough")); - SET_PixelMapfv(__ogl_framework_api, dlsym(handle, "glPixelMapfv")); - SET_PixelMapuiv(__ogl_framework_api, dlsym(handle, "glPixelMapuiv")); - SET_PixelMapusv(__ogl_framework_api, dlsym(handle, "glPixelMapusv")); - SET_PixelStoref(__ogl_framework_api, dlsym(handle, "glPixelStoref")); - SET_PixelStorei(__ogl_framework_api, dlsym(handle, "glPixelStorei")); - SET_PixelTransferf(__ogl_framework_api, dlsym(handle, "glPixelTransferf")); - SET_PixelTransferi(__ogl_framework_api, dlsym(handle, "glPixelTransferi")); - SET_PixelZoom(__ogl_framework_api, dlsym(handle, "glPixelZoom")); - SET_PointSize(__ogl_framework_api, dlsym(handle, "glPointSize")); - SET_PolygonMode(__ogl_framework_api, dlsym(handle, "glPolygonMode")); - SET_PolygonOffset(__ogl_framework_api, dlsym(handle, "glPolygonOffset")); - SET_PolygonStipple(__ogl_framework_api, dlsym(handle, "glPolygonStipple")); - SET_PopAttrib(__ogl_framework_api, dlsym(handle, "glPopAttrib")); - SET_PopClientAttrib(__ogl_framework_api, dlsym(handle, "glPopClientAttrib")); - SET_PopMatrix(__ogl_framework_api, dlsym(handle, "glPopMatrix")); - SET_PopName(__ogl_framework_api, dlsym(handle, "glPopName")); - SET_PrioritizeTextures(__ogl_framework_api, dlsym(handle, "glPrioritizeTextures")); - SET_PushAttrib(__ogl_framework_api, dlsym(handle, "glPushAttrib")); - SET_PushClientAttrib(__ogl_framework_api, dlsym(handle, "glPushClientAttrib")); - SET_PushMatrix(__ogl_framework_api, dlsym(handle, "glPushMatrix")); - SET_PushName(__ogl_framework_api, dlsym(handle, "glPushName")); - SET_RasterPos2d(__ogl_framework_api, dlsym(handle, "glRasterPos2d")); - SET_RasterPos2dv(__ogl_framework_api, dlsym(handle, "glRasterPos2dv")); - SET_RasterPos2f(__ogl_framework_api, dlsym(handle, "glRasterPos2f")); - SET_RasterPos2fv(__ogl_framework_api, dlsym(handle, "glRasterPos2fv")); - SET_RasterPos2i(__ogl_framework_api, dlsym(handle, "glRasterPos2i")); - SET_RasterPos2iv(__ogl_framework_api, dlsym(handle, "glRasterPos2iv")); - SET_RasterPos2s(__ogl_framework_api, dlsym(handle, "glRasterPos2s")); - SET_RasterPos2sv(__ogl_framework_api, dlsym(handle, "glRasterPos2sv")); - SET_RasterPos3d(__ogl_framework_api, dlsym(handle, "glRasterPos3d")); - SET_RasterPos3dv(__ogl_framework_api, dlsym(handle, "glRasterPos3dv")); - SET_RasterPos3f(__ogl_framework_api, dlsym(handle, "glRasterPos3f")); - SET_RasterPos3fv(__ogl_framework_api, dlsym(handle, "glRasterPos3fv")); - SET_RasterPos3i(__ogl_framework_api, dlsym(handle, "glRasterPos3i")); - SET_RasterPos3iv(__ogl_framework_api, dlsym(handle, "glRasterPos3iv")); - SET_RasterPos3s(__ogl_framework_api, dlsym(handle, "glRasterPos3s")); - SET_RasterPos3sv(__ogl_framework_api, dlsym(handle, "glRasterPos3sv")); - SET_RasterPos4d(__ogl_framework_api, dlsym(handle, "glRasterPos4d")); - SET_RasterPos4dv(__ogl_framework_api, dlsym(handle, "glRasterPos4dv")); - SET_RasterPos4f(__ogl_framework_api, dlsym(handle, "glRasterPos4f")); - SET_RasterPos4fv(__ogl_framework_api, dlsym(handle, "glRasterPos4fv")); - SET_RasterPos4i(__ogl_framework_api, dlsym(handle, "glRasterPos4i")); - SET_RasterPos4iv(__ogl_framework_api, dlsym(handle, "glRasterPos4iv")); - SET_RasterPos4s(__ogl_framework_api, dlsym(handle, "glRasterPos4s")); - SET_RasterPos4sv(__ogl_framework_api, dlsym(handle, "glRasterPos4sv")); - SET_ReadBuffer(__ogl_framework_api, dlsym(handle, "glReadBuffer")); - SET_ReadPixels(__ogl_framework_api, dlsym(handle, "glReadPixels")); - SET_Rectd(__ogl_framework_api, dlsym(handle, "glRectd")); - SET_Rectdv(__ogl_framework_api, dlsym(handle, "glRectdv")); - SET_Rectf(__ogl_framework_api, dlsym(handle, "glRectf")); - SET_Rectfv(__ogl_framework_api, dlsym(handle, "glRectfv")); - SET_Recti(__ogl_framework_api, dlsym(handle, "glRecti")); - SET_Rectiv(__ogl_framework_api, dlsym(handle, "glRectiv")); - SET_Rects(__ogl_framework_api, dlsym(handle, "glRects")); - SET_Rectsv(__ogl_framework_api, dlsym(handle, "glRectsv")); - SET_RenderMode(__ogl_framework_api, dlsym(handle, "glRenderMode")); - SET_ResetHistogram(__ogl_framework_api, dlsym(handle, "glResetHistogram")); - SET_ResetMinmax(__ogl_framework_api, dlsym(handle, "glResetMinmax")); - SET_Rotated(__ogl_framework_api, dlsym(handle, "glRotated")); - SET_Rotatef(__ogl_framework_api, dlsym(handle, "glRotatef")); - SET_Scaled(__ogl_framework_api, dlsym(handle, "glScaled")); - SET_Scalef(__ogl_framework_api, dlsym(handle, "glScalef")); - SET_Scissor(__ogl_framework_api, dlsym(handle, "glScissor")); - SET_SelectBuffer(__ogl_framework_api, dlsym(handle, "glSelectBuffer")); - SET_SeparableFilter2D(__ogl_framework_api, dlsym(handle, "glSeparableFilter2D")); - SET_ShadeModel(__ogl_framework_api, dlsym(handle, "glShadeModel")); - SET_StencilFunc(__ogl_framework_api, dlsym(handle, "glStencilFunc")); - SET_StencilMask(__ogl_framework_api, dlsym(handle, "glStencilMask")); - SET_StencilOp(__ogl_framework_api, dlsym(handle, "glStencilOp")); - SET_TexCoord1d(__ogl_framework_api, dlsym(handle, "glTexCoord1d")); - SET_TexCoord1dv(__ogl_framework_api, dlsym(handle, "glTexCoord1dv")); - SET_TexCoord1f(__ogl_framework_api, dlsym(handle, "glTexCoord1f")); - SET_TexCoord1fv(__ogl_framework_api, dlsym(handle, "glTexCoord1fv")); - SET_TexCoord1i(__ogl_framework_api, dlsym(handle, "glTexCoord1i")); - SET_TexCoord1iv(__ogl_framework_api, dlsym(handle, "glTexCoord1iv")); - SET_TexCoord1s(__ogl_framework_api, dlsym(handle, "glTexCoord1s")); - SET_TexCoord1sv(__ogl_framework_api, dlsym(handle, "glTexCoord1sv")); - SET_TexCoord2d(__ogl_framework_api, dlsym(handle, "glTexCoord2d")); - SET_TexCoord2dv(__ogl_framework_api, dlsym(handle, "glTexCoord2dv")); - SET_TexCoord2f(__ogl_framework_api, dlsym(handle, "glTexCoord2f")); - SET_TexCoord2fv(__ogl_framework_api, dlsym(handle, "glTexCoord2fv")); - SET_TexCoord2i(__ogl_framework_api, dlsym(handle, "glTexCoord2i")); - SET_TexCoord2iv(__ogl_framework_api, dlsym(handle, "glTexCoord2iv")); - SET_TexCoord2s(__ogl_framework_api, dlsym(handle, "glTexCoord2s")); - SET_TexCoord2sv(__ogl_framework_api, dlsym(handle, "glTexCoord2sv")); - SET_TexCoord3d(__ogl_framework_api, dlsym(handle, "glTexCoord3d")); - SET_TexCoord3dv(__ogl_framework_api, dlsym(handle, "glTexCoord3dv")); - SET_TexCoord3f(__ogl_framework_api, dlsym(handle, "glTexCoord3f")); - SET_TexCoord3fv(__ogl_framework_api, dlsym(handle, "glTexCoord3fv")); - SET_TexCoord3i(__ogl_framework_api, dlsym(handle, "glTexCoord3i")); - SET_TexCoord3iv(__ogl_framework_api, dlsym(handle, "glTexCoord3iv")); - SET_TexCoord3s(__ogl_framework_api, dlsym(handle, "glTexCoord3s")); - SET_TexCoord3sv(__ogl_framework_api, dlsym(handle, "glTexCoord3sv")); - SET_TexCoord4d(__ogl_framework_api, dlsym(handle, "glTexCoord4d")); - SET_TexCoord4dv(__ogl_framework_api, dlsym(handle, "glTexCoord4dv")); - SET_TexCoord4f(__ogl_framework_api, dlsym(handle, "glTexCoord4f")); - SET_TexCoord4fv(__ogl_framework_api, dlsym(handle, "glTexCoord4fv")); - SET_TexCoord4i(__ogl_framework_api, dlsym(handle, "glTexCoord4i")); - SET_TexCoord4iv(__ogl_framework_api, dlsym(handle, "glTexCoord4iv")); - SET_TexCoord4s(__ogl_framework_api, dlsym(handle, "glTexCoord4s")); - SET_TexCoord4sv(__ogl_framework_api, dlsym(handle, "glTexCoord4sv")); - SET_TexCoordPointer(__ogl_framework_api, dlsym(handle, "glTexCoordPointer")); - SET_TexEnvf(__ogl_framework_api, dlsym(handle, "glTexEnvf")); - SET_TexEnvfv(__ogl_framework_api, dlsym(handle, "glTexEnvfv")); - SET_TexEnvi(__ogl_framework_api, dlsym(handle, "glTexEnvi")); - SET_TexEnviv(__ogl_framework_api, dlsym(handle, "glTexEnviv")); - SET_TexGend(__ogl_framework_api, dlsym(handle, "glTexGend")); - SET_TexGendv(__ogl_framework_api, dlsym(handle, "glTexGendv")); - SET_TexGenf(__ogl_framework_api, dlsym(handle, "glTexGenf")); - SET_TexGenfv(__ogl_framework_api, dlsym(handle, "glTexGenfv")); - SET_TexGeni(__ogl_framework_api, dlsym(handle, "glTexGeni")); - SET_TexGeniv(__ogl_framework_api, dlsym(handle, "glTexGeniv")); - SET_TexImage1D(__ogl_framework_api, dlsym(handle, "glTexImage1D")); - SET_TexImage2D(__ogl_framework_api, dlsym(handle, "glTexImage2D")); - SET_TexImage3D(__ogl_framework_api, dlsym(handle, "glTexImage3D")); - SET_TexParameterf(__ogl_framework_api, dlsym(handle, "glTexParameterf")); - SET_TexParameterfv(__ogl_framework_api, dlsym(handle, "glTexParameterfv")); - SET_TexParameteri(__ogl_framework_api, dlsym(handle, "glTexParameteri")); - SET_TexParameteriv(__ogl_framework_api, dlsym(handle, "glTexParameteriv")); - SET_TexSubImage1D(__ogl_framework_api, dlsym(handle, "glTexSubImage1D")); - SET_TexSubImage2D(__ogl_framework_api, dlsym(handle, "glTexSubImage2D")); - SET_TexSubImage3D(__ogl_framework_api, dlsym(handle, "glTexSubImage3D")); - SET_Translated(__ogl_framework_api, dlsym(handle, "glTranslated")); - SET_Translatef(__ogl_framework_api, dlsym(handle, "glTranslatef")); - SET_Vertex2d(__ogl_framework_api, dlsym(handle, "glVertex2d")); - SET_Vertex2dv(__ogl_framework_api, dlsym(handle, "glVertex2dv")); - SET_Vertex2f(__ogl_framework_api, dlsym(handle, "glVertex2f")); - SET_Vertex2fv(__ogl_framework_api, dlsym(handle, "glVertex2fv")); - SET_Vertex2i(__ogl_framework_api, dlsym(handle, "glVertex2i")); - SET_Vertex2iv(__ogl_framework_api, dlsym(handle, "glVertex2iv")); - SET_Vertex2s(__ogl_framework_api, dlsym(handle, "glVertex2s")); - SET_Vertex2sv(__ogl_framework_api, dlsym(handle, "glVertex2sv")); - SET_Vertex3d(__ogl_framework_api, dlsym(handle, "glVertex3d")); - SET_Vertex3dv(__ogl_framework_api, dlsym(handle, "glVertex3dv")); - SET_Vertex3f(__ogl_framework_api, dlsym(handle, "glVertex3f")); - SET_Vertex3fv(__ogl_framework_api, dlsym(handle, "glVertex3fv")); - SET_Vertex3i(__ogl_framework_api, dlsym(handle, "glVertex3i")); - SET_Vertex3iv(__ogl_framework_api, dlsym(handle, "glVertex3iv")); - SET_Vertex3s(__ogl_framework_api, dlsym(handle, "glVertex3s")); - SET_Vertex3sv(__ogl_framework_api, dlsym(handle, "glVertex3sv")); - SET_Vertex4d(__ogl_framework_api, dlsym(handle, "glVertex4d")); - SET_Vertex4dv(__ogl_framework_api, dlsym(handle, "glVertex4dv")); - SET_Vertex4f(__ogl_framework_api, dlsym(handle, "glVertex4f")); - SET_Vertex4fv(__ogl_framework_api, dlsym(handle, "glVertex4fv")); - SET_Vertex4i(__ogl_framework_api, dlsym(handle, "glVertex4i")); - SET_Vertex4iv(__ogl_framework_api, dlsym(handle, "glVertex4iv")); - SET_Vertex4s(__ogl_framework_api, dlsym(handle, "glVertex4s")); - SET_Vertex4sv(__ogl_framework_api, dlsym(handle, "glVertex4sv")); - SET_VertexPointer(__ogl_framework_api, dlsym(handle, "glVertexPointer")); - SET_Viewport(__ogl_framework_api, dlsym(handle, "glViewport")); - - /* GL_VERSION_2_0 */ - SET_AttachShader(__ogl_framework_api, dlsym(handle, "glAttachShader")); - SET_CreateProgram(__ogl_framework_api, dlsym(handle, "glCreateProgram")); - SET_CreateShader(__ogl_framework_api, dlsym(handle, "glCreateShader")); - SET_DeleteProgram(__ogl_framework_api, dlsym(handle, "glDeleteProgram")); - SET_DeleteShader(__ogl_framework_api, dlsym(handle, "glDeleteShader")); - SET_DetachShader(__ogl_framework_api, dlsym(handle, "glDetachShader")); - SET_GetAttachedShaders(__ogl_framework_api, dlsym(handle, "glGetAttachedShaders")); - SET_GetProgramiv(__ogl_framework_api, dlsym(handle, "glGetProgramiv")); - SET_GetProgramInfoLog(__ogl_framework_api, dlsym(handle, "glGetProgramInfoLog")); - SET_GetShaderInfoLog(__ogl_framework_api, dlsym(handle, "glGetShaderInfoLog")); - SET_GetShaderiv(__ogl_framework_api, dlsym(handle, "glGetShaderiv")); - SET_IsProgram(__ogl_framework_api, dlsym(handle, "glIsProgram")); - SET_IsShader(__ogl_framework_api, dlsym(handle, "glIsShader")); - SET_StencilFuncSeparate(__ogl_framework_api, dlsym(handle, "glStencilFuncSeparate")); - SET_StencilMaskSeparate(__ogl_framework_api, dlsym(handle, "glStencilMaskSeparate")); - SET_StencilOpSeparate(__ogl_framework_api, dlsym(handle, "glStencilOpSeparate")); - - /* GL_VERSION_2_1 */ - SET_UniformMatrix2x3fv(__ogl_framework_api, dlsym(handle, "glUniformMatrix2x3fv")); - SET_UniformMatrix2x4fv(__ogl_framework_api, dlsym(handle, "glUniformMatrix2x4fv")); - SET_UniformMatrix3x2fv(__ogl_framework_api, dlsym(handle, "glUniformMatrix3x2fv")); - SET_UniformMatrix3x4fv(__ogl_framework_api, dlsym(handle, "glUniformMatrix3x4fv")); - SET_UniformMatrix4x2fv(__ogl_framework_api, dlsym(handle, "glUniformMatrix4x2fv")); - SET_UniformMatrix4x3fv(__ogl_framework_api, dlsym(handle, "glUniformMatrix4x3fv")); - - /* GL_VERSION_3_0 */ - SET_ClampColor(__ogl_framework_api, dlsym(handle, "glClampColor")); - SET_ClearBufferfi(__ogl_framework_api, dlsym(handle, "glClearBufferfi")); - SET_ClearBufferfv(__ogl_framework_api, dlsym(handle, "glClearBufferfv")); - SET_ClearBufferiv(__ogl_framework_api, dlsym(handle, "glClearBufferiv")); - SET_ClearBufferuiv(__ogl_framework_api, dlsym(handle, "glClearBufferuiv")); - SET_GetStringi(__ogl_framework_api, dlsym(handle, "glGetStringi")); - - /* GL_VERSION_3_1 */ - SET_TexBuffer(__ogl_framework_api, dlsym(handle, "glTexBuffer")); - - /* GL_VERSION_3_2 */ - SET_FramebufferTexture(__ogl_framework_api, dlsym(handle, "glFramebufferTexture")); - SET_GetBufferParameteri64v(__ogl_framework_api, dlsym(handle, "glGetBufferParameteri64v")); - SET_GetInteger64i_v(__ogl_framework_api, dlsym(handle, "glGetInteger64i_v")); - - /* GL_APPLE_vertex_array_object */ - SET_BindVertexArrayAPPLE(__ogl_framework_api, dlsym(handle, "glBindVertexArrayAPPLE")); - SET_DeleteVertexArraysAPPLE(__ogl_framework_api, dlsym(handle, "glDeleteVertexArraysAPPLE")); - SET_GenVertexArraysAPPLE(__ogl_framework_api, dlsym(handle, "glGenVertexArraysAPPLE")); - SET_IsVertexArrayAPPLE(__ogl_framework_api, dlsym(handle, "glIsVertexArrayAPPLE")); - - /* GL_ARB_draw_buffers */ - SET_DrawBuffersARB(__ogl_framework_api, dlsym(handle, "glDrawBuffersARB")); - - /* GL_ARB_multisample */ - SET_SampleCoverageARB(__ogl_framework_api, dlsym(handle, "glSampleCoverageARB")); - - /* GL_ARB_multitexture */ - SET_ActiveTextureARB(__ogl_framework_api, dlsym(handle, "glActiveTextureARB")); - SET_ClientActiveTextureARB(__ogl_framework_api, dlsym(handle, "glClientActiveTextureARB")); - SET_MultiTexCoord1dARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord1dARB")); - SET_MultiTexCoord1dvARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord1dvARB")); - SET_MultiTexCoord1fARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord1fARB")); - SET_MultiTexCoord1fvARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord1fvARB")); - SET_MultiTexCoord1iARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord1iARB")); - SET_MultiTexCoord1ivARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord1ivARB")); - SET_MultiTexCoord1sARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord1sARB")); - SET_MultiTexCoord1svARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord1svARB")); - SET_MultiTexCoord2dARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord2dARB")); - SET_MultiTexCoord2dvARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord2dvARB")); - SET_MultiTexCoord2fARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord2fARB")); - SET_MultiTexCoord2fvARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord2fvARB")); - SET_MultiTexCoord2iARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord2iARB")); - SET_MultiTexCoord2ivARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord2ivARB")); - SET_MultiTexCoord2sARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord2sARB")); - SET_MultiTexCoord2svARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord2svARB")); - SET_MultiTexCoord3dARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord3dARB")); - SET_MultiTexCoord3dvARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord3dvARB")); - SET_MultiTexCoord3fARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord3fARB")); - SET_MultiTexCoord3fvARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord3fvARB")); - SET_MultiTexCoord3iARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord3iARB")); - SET_MultiTexCoord3ivARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord3ivARB")); - SET_MultiTexCoord3sARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord3sARB")); - SET_MultiTexCoord3svARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord3svARB")); - SET_MultiTexCoord4dARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord4dARB")); - SET_MultiTexCoord4dvARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord4dvARB")); - SET_MultiTexCoord4fARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord4fARB")); - SET_MultiTexCoord4fvARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord4fvARB")); - SET_MultiTexCoord4iARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord4iARB")); - SET_MultiTexCoord4ivARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord4ivARB")); - SET_MultiTexCoord4sARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord4sARB")); - SET_MultiTexCoord4svARB(__ogl_framework_api, dlsym(handle, "glMultiTexCoord4svARB")); - - /* GL_ARB_occlusion_query */ - SET_BeginQueryARB(__ogl_framework_api, dlsym(handle, "glBeginQueryARB")); - SET_DeleteQueriesARB(__ogl_framework_api, dlsym(handle, "glDeleteQueriesARB")); - SET_EndQueryARB(__ogl_framework_api, dlsym(handle, "glEndQueryARB")); - SET_GenQueriesARB(__ogl_framework_api, dlsym(handle, "glGenQueriesARB")); - SET_GetQueryObjectivARB(__ogl_framework_api, dlsym(handle, "glGetQueryObjectivARB")); - SET_GetQueryObjectuivARB(__ogl_framework_api, dlsym(handle, "glGetQueryObjectuivARB")); - SET_GetQueryivARB(__ogl_framework_api, dlsym(handle, "glGetQueryivARB")); - SET_IsQueryARB(__ogl_framework_api, dlsym(handle, "glIsQueryARB")); - - /* GL_ARB_shader_objects */ - SET_AttachObjectARB(__ogl_framework_api, dlsym(handle, "glAttachObjectARB")); - SET_CompileShaderARB(__ogl_framework_api, dlsym(handle, "glCompileShaderARB")); - SET_DeleteObjectARB(__ogl_framework_api, dlsym(handle, "glDeleteObjectARB")); - SET_GetHandleARB(__ogl_framework_api, dlsym(handle, "glGetHandleARB")); - SET_DetachObjectARB(__ogl_framework_api, dlsym(handle, "glDetachObjectARB")); - SET_CreateProgramObjectARB(__ogl_framework_api, dlsym(handle, "glCreateProgramObjectARB")); - SET_CreateShaderObjectARB(__ogl_framework_api, dlsym(handle, "glCreateShaderObjectARB")); - SET_GetInfoLogARB(__ogl_framework_api, dlsym(handle, "glGetInfoLogARB")); - SET_GetActiveUniformARB(__ogl_framework_api, dlsym(handle, "glGetActiveUniformARB")); - SET_GetAttachedObjectsARB(__ogl_framework_api, dlsym(handle, "glGetAttachedObjectsARB")); - SET_GetObjectParameterfvARB(__ogl_framework_api, dlsym(handle, "glGetObjectParameterfvARB")); - SET_GetObjectParameterivARB(__ogl_framework_api, dlsym(handle, "glGetObjectParameterivARB")); - SET_GetShaderSourceARB(__ogl_framework_api, dlsym(handle, "glGetShaderSourceARB")); - SET_GetUniformLocationARB(__ogl_framework_api, dlsym(handle, "glGetUniformLocationARB")); - SET_GetUniformfvARB(__ogl_framework_api, dlsym(handle, "glGetUniformfvARB")); - SET_GetUniformivARB(__ogl_framework_api, dlsym(handle, "glGetUniformivARB")); - SET_LinkProgramARB(__ogl_framework_api, dlsym(handle, "glLinkProgramARB")); - SET_ShaderSourceARB(__ogl_framework_api, dlsym(handle, "glShaderSourceARB")); - SET_Uniform1fARB(__ogl_framework_api, dlsym(handle, "glUniform1fARB")); - SET_Uniform1fvARB(__ogl_framework_api, dlsym(handle, "glUniform1fvARB")); - SET_Uniform1iARB(__ogl_framework_api, dlsym(handle, "glUniform1iARB")); - SET_Uniform1ivARB(__ogl_framework_api, dlsym(handle, "glUniform1ivARB")); - SET_Uniform2fARB(__ogl_framework_api, dlsym(handle, "glUniform2fARB")); - SET_Uniform2fvARB(__ogl_framework_api, dlsym(handle, "glUniform2fvARB")); - SET_Uniform2iARB(__ogl_framework_api, dlsym(handle, "glUniform2iARB")); - SET_Uniform2ivARB(__ogl_framework_api, dlsym(handle, "glUniform2ivARB")); - SET_Uniform3fARB(__ogl_framework_api, dlsym(handle, "glUniform3fARB")); - SET_Uniform3fvARB(__ogl_framework_api, dlsym(handle, "glUniform3fvARB")); - SET_Uniform3iARB(__ogl_framework_api, dlsym(handle, "glUniform3iARB")); - SET_Uniform3ivARB(__ogl_framework_api, dlsym(handle, "glUniform3ivARB")); - SET_Uniform4fARB(__ogl_framework_api, dlsym(handle, "glUniform4fARB")); - SET_Uniform4fvARB(__ogl_framework_api, dlsym(handle, "glUniform4fvARB")); - SET_Uniform4iARB(__ogl_framework_api, dlsym(handle, "glUniform4iARB")); - SET_Uniform4ivARB(__ogl_framework_api, dlsym(handle, "glUniform4ivARB")); - SET_UniformMatrix2fvARB(__ogl_framework_api, dlsym(handle, "glUniformMatrix2fvARB")); - SET_UniformMatrix3fvARB(__ogl_framework_api, dlsym(handle, "glUniformMatrix3fvARB")); - SET_UniformMatrix4fvARB(__ogl_framework_api, dlsym(handle, "glUniformMatrix4fvARB")); - SET_UseProgramObjectARB(__ogl_framework_api, dlsym(handle, "glUseProgramObjectARB")); - SET_ValidateProgramARB(__ogl_framework_api, dlsym(handle, "glValidateProgramARB")); - - /* GL_ARB_texture_compression */ - SET_CompressedTexImage1DARB(__ogl_framework_api, dlsym(handle, "glCompressedTexImage1DARB")); - SET_CompressedTexImage2DARB(__ogl_framework_api, dlsym(handle, "glCompressedTexImage2DARB")); - SET_CompressedTexImage3DARB(__ogl_framework_api, dlsym(handle, "glCompressedTexImage3DARB")); - SET_CompressedTexSubImage1DARB(__ogl_framework_api, dlsym(handle, "glCompressedTexSubImage1DARB")); - SET_CompressedTexSubImage2DARB(__ogl_framework_api, dlsym(handle, "glCompressedTexSubImage2DARB")); - SET_CompressedTexSubImage3DARB(__ogl_framework_api, dlsym(handle, "glCompressedTexSubImage3DARB")); - SET_GetCompressedTexImageARB(__ogl_framework_api, dlsym(handle, "glGetCompressedTexImageARB")); - - /* GL_ARB_transpose_matrix */ - SET_LoadTransposeMatrixdARB(__ogl_framework_api, dlsym(handle, "glLoadTransposeMatrixdARB")); - SET_LoadTransposeMatrixfARB(__ogl_framework_api, dlsym(handle, "glLoadTransposeMatrixfARB")); - SET_MultTransposeMatrixdARB(__ogl_framework_api, dlsym(handle, "glMultTransposeMatrixdARB")); - SET_MultTransposeMatrixfARB(__ogl_framework_api, dlsym(handle, "glMultTransposeMatrixfARB")); - - /* GL_ARB_vertex_buffer_object */ - SET_BindBufferARB(__ogl_framework_api, dlsym(handle, "glBindBufferARB")); - SET_BufferDataARB(__ogl_framework_api, dlsym(handle, "glBufferDataARB")); - SET_BufferSubDataARB(__ogl_framework_api, dlsym(handle, "glBufferSubDataARB")); - SET_DeleteBuffersARB(__ogl_framework_api, dlsym(handle, "glDeleteBuffersARB")); - SET_GenBuffersARB(__ogl_framework_api, dlsym(handle, "glGenBuffersARB")); - SET_GetBufferParameterivARB(__ogl_framework_api, dlsym(handle, "glGetBufferParameterivARB")); - SET_GetBufferPointervARB(__ogl_framework_api, dlsym(handle, "glGetBufferPointervARB")); - SET_GetBufferSubDataARB(__ogl_framework_api, dlsym(handle, "glGetBufferSubDataARB")); - SET_IsBufferARB(__ogl_framework_api, dlsym(handle, "glIsBufferARB")); - SET_MapBufferARB(__ogl_framework_api, dlsym(handle, "glMapBufferARB")); - SET_UnmapBufferARB(__ogl_framework_api, dlsym(handle, "glUnmapBufferARB")); - - /* GL_ARB_vertex_program */ - SET_DisableVertexAttribArrayARB(__ogl_framework_api, dlsym(handle, "glDisableVertexAttribArrayARB")); - SET_EnableVertexAttribArrayARB(__ogl_framework_api, dlsym(handle, "glEnableVertexAttribArrayARB")); - SET_GetProgramEnvParameterdvARB(__ogl_framework_api, dlsym(handle, "glGetProgramEnvParameterdvARB")); - SET_GetProgramEnvParameterfvARB(__ogl_framework_api, dlsym(handle, "glGetProgramEnvParameterfvARB")); - SET_GetProgramLocalParameterdvARB(__ogl_framework_api, dlsym(handle, "glGetProgramLocalParameterdvARB")); - SET_GetProgramLocalParameterfvARB(__ogl_framework_api, dlsym(handle, "glGetProgramLocalParameterfvARB")); - SET_GetProgramStringARB(__ogl_framework_api, dlsym(handle, "glGetProgramStringARB")); - SET_GetProgramivARB(__ogl_framework_api, dlsym(handle, "glGetProgramivARB")); - SET_GetVertexAttribdvARB(__ogl_framework_api, dlsym(handle, "glGetVertexAttribdvARB")); - SET_GetVertexAttribfvARB(__ogl_framework_api, dlsym(handle, "glGetVertexAttribfvARB")); - SET_GetVertexAttribivARB(__ogl_framework_api, dlsym(handle, "glGetVertexAttribivARB")); - SET_ProgramEnvParameter4dARB(__ogl_framework_api, dlsym(handle, "glProgramEnvParameter4dARB")); - SET_ProgramEnvParameter4dvARB(__ogl_framework_api, dlsym(handle, "glProgramEnvParameter4dvARB")); - SET_ProgramEnvParameter4fARB(__ogl_framework_api, dlsym(handle, "glProgramEnvParameter4fARB")); - SET_ProgramEnvParameter4fvARB(__ogl_framework_api, dlsym(handle, "glProgramEnvParameter4fvARB")); - SET_ProgramLocalParameter4dARB(__ogl_framework_api, dlsym(handle, "glProgramLocalParameter4dARB")); - SET_ProgramLocalParameter4dvARB(__ogl_framework_api, dlsym(handle, "glProgramLocalParameter4dvARB")); - SET_ProgramLocalParameter4fARB(__ogl_framework_api, dlsym(handle, "glProgramLocalParameter4fARB")); - SET_ProgramLocalParameter4fvARB(__ogl_framework_api, dlsym(handle, "glProgramLocalParameter4fvARB")); - SET_ProgramStringARB(__ogl_framework_api, dlsym(handle, "glProgramStringARB")); - SET_VertexAttrib1dARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib1dARB")); - SET_VertexAttrib1dvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib1dvARB")); - SET_VertexAttrib1fARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib1fARB")); - SET_VertexAttrib1fvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib1fvARB")); - SET_VertexAttrib1sARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib1sARB")); - SET_VertexAttrib1svARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib1svARB")); - SET_VertexAttrib2dARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib2dARB")); - SET_VertexAttrib2dvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib2dvARB")); - SET_VertexAttrib2fARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib2fARB")); - SET_VertexAttrib2fvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib2fvARB")); - SET_VertexAttrib2sARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib2sARB")); - SET_VertexAttrib2svARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib2svARB")); - SET_VertexAttrib3dARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib3dARB")); - SET_VertexAttrib3dvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib3dvARB")); - SET_VertexAttrib3fARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib3fARB")); - SET_VertexAttrib3fvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib3fvARB")); - SET_VertexAttrib3sARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib3sARB")); - SET_VertexAttrib3svARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib3svARB")); - SET_VertexAttrib4NbvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4NbvARB")); - SET_VertexAttrib4NivARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4NivARB")); - SET_VertexAttrib4NsvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4NsvARB")); - SET_VertexAttrib4NubARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4NubARB")); - SET_VertexAttrib4NubvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4NubvARB")); - SET_VertexAttrib4NuivARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4NuivARB")); - SET_VertexAttrib4NusvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4NusvARB")); - SET_VertexAttrib4bvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4bvARB")); - SET_VertexAttrib4dARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4dARB")); - SET_VertexAttrib4dvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4dvARB")); - SET_VertexAttrib4fARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4fARB")); - SET_VertexAttrib4fvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4fvARB")); - SET_VertexAttrib4ivARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4ivARB")); - SET_VertexAttrib4sARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4sARB")); - SET_VertexAttrib4svARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4svARB")); - SET_VertexAttrib4ubvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4ubvARB")); - SET_VertexAttrib4uivARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4uivARB")); - SET_VertexAttrib4usvARB(__ogl_framework_api, dlsym(handle, "glVertexAttrib4usvARB")); - SET_VertexAttribPointerARB(__ogl_framework_api, dlsym(handle, "glVertexAttribPointerARB")); - - /* GL_ARB_vertex_shader */ - SET_BindAttribLocationARB(__ogl_framework_api, dlsym(handle, "glBindAttribLocationARB")); - SET_GetActiveAttribARB(__ogl_framework_api, dlsym(handle, "glGetActiveAttribARB")); - SET_GetAttribLocationARB(__ogl_framework_api, dlsym(handle, "glGetAttribLocationARB")); - - /* GL_ARB_window_pos */ - SET_WindowPos2dMESA(__ogl_framework_api, dlsym(handle, "glWindowPos2dARB")); - SET_WindowPos2dvMESA(__ogl_framework_api, dlsym(handle, "glWindowPos2dvARB")); - SET_WindowPos2fMESA(__ogl_framework_api, dlsym(handle, "glWindowPos2fARB")); - SET_WindowPos2fvMESA(__ogl_framework_api, dlsym(handle, "glWindowPos2fvARB")); - SET_WindowPos2iMESA(__ogl_framework_api, dlsym(handle, "glWindowPos2iARB")); - SET_WindowPos2ivMESA(__ogl_framework_api, dlsym(handle, "glWindowPos2ivARB")); - SET_WindowPos2sMESA(__ogl_framework_api, dlsym(handle, "glWindowPos2sARB")); - SET_WindowPos2svMESA(__ogl_framework_api, dlsym(handle, "glWindowPos2svARB")); - SET_WindowPos3dMESA(__ogl_framework_api, dlsym(handle, "glWindowPos3dARB")); - SET_WindowPos3dvMESA(__ogl_framework_api, dlsym(handle, "glWindowPos3dvARB")); - SET_WindowPos3fMESA(__ogl_framework_api, dlsym(handle, "glWindowPos3fARB")); - SET_WindowPos3fvMESA(__ogl_framework_api, dlsym(handle, "glWindowPos3fvARB")); - SET_WindowPos3iMESA(__ogl_framework_api, dlsym(handle, "glWindowPos3iARB")); - SET_WindowPos3ivMESA(__ogl_framework_api, dlsym(handle, "glWindowPos3ivARB")); - SET_WindowPos3sMESA(__ogl_framework_api, dlsym(handle, "glWindowPos3sARB")); - SET_WindowPos3svMESA(__ogl_framework_api, dlsym(handle, "glWindowPos3svARB")); - - /* GL_ATI_fragment_shader / GL_EXT_fragment_shader */ - if(dlsym(handle, "glAlphaFragmentOp1ATI")) { - /* GL_ATI_fragment_shader */ - SET_AlphaFragmentOp1ATI(__ogl_framework_api, dlsym(handle, "glAlphaFragmentOp1ATI")); - SET_AlphaFragmentOp2ATI(__ogl_framework_api, dlsym(handle, "glAlphaFragmentOp2ATI")); - SET_AlphaFragmentOp3ATI(__ogl_framework_api, dlsym(handle, "glAlphaFragmentOp3ATI")); - SET_BeginFragmentShaderATI(__ogl_framework_api, dlsym(handle, "glBeginFragmentShaderATI")); - SET_BindFragmentShaderATI(__ogl_framework_api, dlsym(handle, "glBindFragmentShaderATI")); - SET_ColorFragmentOp1ATI(__ogl_framework_api, dlsym(handle, "glColorFragmentOp1ATI")); - SET_ColorFragmentOp2ATI(__ogl_framework_api, dlsym(handle, "glColorFragmentOp2ATI")); - SET_ColorFragmentOp3ATI(__ogl_framework_api, dlsym(handle, "glColorFragmentOp3ATI")); - SET_DeleteFragmentShaderATI(__ogl_framework_api, dlsym(handle, "glDeleteFragmentShaderATI")); - SET_EndFragmentShaderATI(__ogl_framework_api, dlsym(handle, "glEndFragmentShaderATI")); - SET_GenFragmentShadersATI(__ogl_framework_api, dlsym(handle, "glGenFragmentShadersATI")); - SET_PassTexCoordATI(__ogl_framework_api, dlsym(handle, "glPassTexCoordATI")); - SET_SampleMapATI(__ogl_framework_api, dlsym(handle, "glSampleMapATI")); - SET_SetFragmentShaderConstantATI(__ogl_framework_api, dlsym(handle, "glSetFragmentShaderConstantATI")); - } else { - /* GL_EXT_fragment_shader */ - SET_AlphaFragmentOp1ATI(__ogl_framework_api, dlsym(handle, "glAlphaFragmentOp1EXT")); - SET_AlphaFragmentOp2ATI(__ogl_framework_api, dlsym(handle, "glAlphaFragmentOp2EXT")); - SET_AlphaFragmentOp3ATI(__ogl_framework_api, dlsym(handle, "glAlphaFragmentOp3EXT")); - SET_BeginFragmentShaderATI(__ogl_framework_api, dlsym(handle, "glBeginFragmentShaderEXT")); - SET_BindFragmentShaderATI(__ogl_framework_api, dlsym(handle, "glBindFragmentShaderEXT")); - SET_ColorFragmentOp1ATI(__ogl_framework_api, dlsym(handle, "glColorFragmentOp1EXT")); - SET_ColorFragmentOp2ATI(__ogl_framework_api, dlsym(handle, "glColorFragmentOp2EXT")); - SET_ColorFragmentOp3ATI(__ogl_framework_api, dlsym(handle, "glColorFragmentOp3EXT")); - SET_DeleteFragmentShaderATI(__ogl_framework_api, dlsym(handle, "glDeleteFragmentShaderEXT")); - SET_EndFragmentShaderATI(__ogl_framework_api, dlsym(handle, "glEndFragmentShaderEXT")); - SET_GenFragmentShadersATI(__ogl_framework_api, dlsym(handle, "glGenFragmentShadersEXT")); - SET_PassTexCoordATI(__ogl_framework_api, dlsym(handle, "glPassTexCoordEXT")); - SET_SampleMapATI(__ogl_framework_api, dlsym(handle, "glSampleMapEXT")); - SET_SetFragmentShaderConstantATI(__ogl_framework_api, dlsym(handle, "glSetFragmentShaderConstantEXT")); - } - - /* GL_ATI_separate_stencil */ - SET_StencilFuncSeparateATI(__ogl_framework_api, dlsym(handle, "glStencilFuncSeparateATI")); - - /* GL_EXT_blend_equation_separate */ - SET_BlendEquationSeparateEXT(__ogl_framework_api, dlsym(handle, "glBlendEquationSeparateEXT")); - - /* GL_EXT_blend_func_separate */ - SET_BlendFuncSeparateEXT(__ogl_framework_api, dlsym(handle, "glBlendFuncSeparateEXT")); - - /* GL_EXT_depth_bounds_test */ - SET_DepthBoundsEXT(__ogl_framework_api, dlsym(handle, "glDepthBoundsEXT")); - - /* GL_EXT_compiled_vertex_array */ - SET_LockArraysEXT(__ogl_framework_api, dlsym(handle, "glLockArraysEXT")); - SET_UnlockArraysEXT(__ogl_framework_api, dlsym(handle, "glUnlockArraysEXT")); - - /* GL_EXT_cull_vertex */ -// SET_CullParameterdvEXT(__ogl_framework_api, dlsym(handle, "glCullParameterdvEXT")); -// SET_CullParameterfvEXT(__ogl_framework_api, dlsym(handle, "glCullParameterfvEXT")); - - /* GL_EXT_fog_coord */ - SET_FogCoordPointerEXT(__ogl_framework_api, dlsym(handle, "glFogCoordPointerEXT")); - SET_FogCoorddEXT(__ogl_framework_api, dlsym(handle, "glFogCoorddEXT")); - SET_FogCoorddvEXT(__ogl_framework_api, dlsym(handle, "glFogCoorddvEXT")); - SET_FogCoordfEXT(__ogl_framework_api, dlsym(handle, "glFogCoordfEXT")); - SET_FogCoordfvEXT(__ogl_framework_api, dlsym(handle, "glFogCoordfvEXT")); - - /* GL_EXT_framebuffer_blit */ - SET_BlitFramebufferEXT(__ogl_framework_api, dlsym(handle, "glBlitFramebufferEXT")); - - /* GL_EXT_framebuffer_object */ - SET_BindFramebufferEXT(__ogl_framework_api, dlsym(handle, "glBindFramebufferEXT")); - SET_BindRenderbufferEXT(__ogl_framework_api, dlsym(handle, "glBindRenderbufferEXT")); - SET_CheckFramebufferStatusEXT(__ogl_framework_api, dlsym(handle, "glCheckFramebufferStatusEXT")); - SET_DeleteFramebuffersEXT(__ogl_framework_api, dlsym(handle, "glDeleteFramebuffersEXT")); - SET_DeleteRenderbuffersEXT(__ogl_framework_api, dlsym(handle, "glDeleteRenderbuffersEXT")); - SET_FramebufferRenderbufferEXT(__ogl_framework_api, dlsym(handle, "glFramebufferRenderbufferEXT")); - SET_FramebufferTexture1DEXT(__ogl_framework_api, dlsym(handle, "glFramebufferTexture1DEXT")); - SET_FramebufferTexture2DEXT(__ogl_framework_api, dlsym(handle, "glFramebufferTexture2DEXT")); - SET_FramebufferTexture3DEXT(__ogl_framework_api, dlsym(handle, "glFramebufferTexture3DEXT")); - SET_GenerateMipmapEXT(__ogl_framework_api, dlsym(handle, "glGenerateMipmapEXT")); - SET_GenFramebuffersEXT(__ogl_framework_api, dlsym(handle, "glGenFramebuffersEXT")); - SET_GenRenderbuffersEXT(__ogl_framework_api, dlsym(handle, "glGenRenderbuffersEXT")); - SET_GetFramebufferAttachmentParameterivEXT(__ogl_framework_api, dlsym(handle, "glGetFramebufferAttachmentParameterivEXT")); - SET_GetRenderbufferParameterivEXT(__ogl_framework_api, dlsym(handle, "glGetRenderbufferParameterivEXT")); - SET_IsFramebufferEXT(__ogl_framework_api, dlsym(handle, "glIsFramebufferEXT")); - SET_IsRenderbufferEXT(__ogl_framework_api, dlsym(handle, "glIsRenderbufferEXT")); - SET_RenderbufferStorageEXT(__ogl_framework_api, dlsym(handle, "glRenderbufferStorageEXT")); - - /* GL_EXT_gpu_program_parameters */ - SET_ProgramEnvParameters4fvEXT(__ogl_framework_api, dlsym(handle, "glProgramEnvParameters4fvEXT")); - SET_ProgramLocalParameters4fvEXT(__ogl_framework_api, dlsym(handle, "glProgramLocalParameters4fvEXT")); - - /* GL_EXT_multi_draw_arrays */ - SET_MultiDrawArraysEXT(__ogl_framework_api, (void *)dlsym(handle, "glMultiDrawArraysEXT")); - SET_MultiDrawElementsEXT(__ogl_framework_api, dlsym(handle, "glMultiDrawElementsEXT")); - - /* GL_EXT_point_parameters / GL_ARB_point_parameters */ - if(dlsym(handle, "glPointParameterfEXT")) { - /* GL_EXT_point_parameters */ - SET_PointParameterfEXT(__ogl_framework_api, dlsym(handle, "glPointParameterfEXT")); - SET_PointParameterfvEXT(__ogl_framework_api, dlsym(handle, "glPointParameterfvEXT")); - } else { - /* GL_ARB_point_parameters */ - SET_PointParameterfEXT(__ogl_framework_api, dlsym(handle, "glPointParameterfARB")); - SET_PointParameterfvEXT(__ogl_framework_api, dlsym(handle, "glPointParameterfvARB")); - } - - /* GL_EXT_polygon_offset */ - SET_PolygonOffsetEXT(__ogl_framework_api, dlsym(handle, "glPolygonOffsetEXT")); - - /* GL_EXT_secondary_color */ - SET_SecondaryColor3bEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3bEXT")); - SET_SecondaryColor3bvEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3bvEXT")); - SET_SecondaryColor3dEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3dEXT")); - SET_SecondaryColor3dvEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3dvEXT")); - SET_SecondaryColor3fEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3fEXT")); - SET_SecondaryColor3fvEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3fvEXT")); - SET_SecondaryColor3iEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3iEXT")); - SET_SecondaryColor3ivEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3ivEXT")); - SET_SecondaryColor3sEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3sEXT")); - SET_SecondaryColor3svEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3svEXT")); - SET_SecondaryColor3ubEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3ubEXT")); - SET_SecondaryColor3ubvEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3ubvEXT")); - SET_SecondaryColor3uiEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3uiEXT")); - SET_SecondaryColor3uivEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3uivEXT")); - SET_SecondaryColor3usEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3usEXT")); - SET_SecondaryColor3usvEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColor3usvEXT")); - SET_SecondaryColorPointerEXT(__ogl_framework_api, dlsym(handle, "glSecondaryColorPointerEXT")); - - /* GL_EXT_stencil_two_side */ - SET_ActiveStencilFaceEXT(__ogl_framework_api, dlsym(handle, "glActiveStencilFaceEXT")); - - /* GL_EXT_timer_query */ - SET_GetQueryObjecti64vEXT(__ogl_framework_api, dlsym(handle, "glGetQueryObjecti64vEXT")); - SET_GetQueryObjectui64vEXT(__ogl_framework_api, dlsym(handle, "glGetQueryObjectui64vEXT")); - - /* GL_EXT_vertex_array */ - SET_ColorPointerEXT(__ogl_framework_api, dlsym(handle, "glColorPointerEXT")); - SET_EdgeFlagPointerEXT(__ogl_framework_api, dlsym(handle, "glEdgeFlagPointerEXT")); - SET_IndexPointerEXT(__ogl_framework_api, dlsym(handle, "glIndexPointerEXT")); - SET_NormalPointerEXT(__ogl_framework_api, dlsym(handle, "glNormalPointerEXT")); - SET_TexCoordPointerEXT(__ogl_framework_api, dlsym(handle, "glTexCoordPointerEXT")); - SET_VertexPointerEXT(__ogl_framework_api, dlsym(handle, "glVertexPointerEXT")); - - /* GL_IBM_multimode_draw_arrays */ - SET_MultiModeDrawArraysIBM(__ogl_framework_api, dlsym(handle, "glMultiModeDrawArraysIBM")); - SET_MultiModeDrawElementsIBM(__ogl_framework_api, dlsym(handle, "glMultiModeDrawElementsIBM")); - - /* GL_MESA_resize_buffers */ - SET_ResizeBuffersMESA(__ogl_framework_api, dlsym(handle, "glResizeBuffersMESA")); - - /* GL_MESA_window_pos */ - SET_WindowPos4dMESA(__ogl_framework_api, dlsym(handle, "glWindowPos4dMESA")); - SET_WindowPos4dvMESA(__ogl_framework_api, dlsym(handle, "glWindowPos4dvMESA")); - SET_WindowPos4fMESA(__ogl_framework_api, dlsym(handle, "glWindowPos4fMESA")); - SET_WindowPos4fvMESA(__ogl_framework_api, dlsym(handle, "glWindowPos4fvMESA")); - SET_WindowPos4iMESA(__ogl_framework_api, dlsym(handle, "glWindowPos4iMESA")); - SET_WindowPos4ivMESA(__ogl_framework_api, dlsym(handle, "glWindowPos4ivMESA")); - SET_WindowPos4sMESA(__ogl_framework_api, dlsym(handle, "glWindowPos4sMESA")); - SET_WindowPos4svMESA(__ogl_framework_api, dlsym(handle, "glWindowPos4svMESA")); - - /* GL_NV_fence */ - SET_DeleteFencesNV(__ogl_framework_api, dlsym(handle, "glDeleteFencesNV")); - SET_FinishFenceNV(__ogl_framework_api, dlsym(handle, "glFinishFenceNV")); - SET_GenFencesNV(__ogl_framework_api, dlsym(handle, "glGenFencesNV")); - SET_GetFenceivNV(__ogl_framework_api, dlsym(handle, "glGetFenceivNV")); - SET_IsFenceNV(__ogl_framework_api, dlsym(handle, "glIsFenceNV")); - SET_SetFenceNV(__ogl_framework_api, dlsym(handle, "glSetFenceNV")); - SET_TestFenceNV(__ogl_framework_api, dlsym(handle, "glTestFenceNV")); - - /* GL_NV_fragment_program */ - SET_GetProgramNamedParameterdvNV(__ogl_framework_api, dlsym(handle, "glGetProgramNamedParameterdvNV")); - SET_GetProgramNamedParameterfvNV(__ogl_framework_api, dlsym(handle, "glGetProgramNamedParameterfvNV")); - SET_ProgramNamedParameter4dNV(__ogl_framework_api, dlsym(handle, "glProgramNamedParameter4dNV")); - SET_ProgramNamedParameter4dvNV(__ogl_framework_api, dlsym(handle, "glProgramNamedParameter4dvNV")); - SET_ProgramNamedParameter4fNV(__ogl_framework_api, dlsym(handle, "glProgramNamedParameter4fNV")); - SET_ProgramNamedParameter4fvNV(__ogl_framework_api, dlsym(handle, "glProgramNamedParameter4fvNV")); - - /* GL_NV_geometry_program4 */ - SET_FramebufferTextureLayerEXT(__ogl_framework_api, dlsym(handle, "glFramebufferTextureLayerEXT")); - - /* GL_NV_point_sprite */ - SET_PointParameteriNV(__ogl_framework_api, dlsym(handle, "glPointParameteriNV")); - SET_PointParameterivNV(__ogl_framework_api, dlsym(handle, "glPointParameterivNV")); - - /* GL_NV_register_combiners */ - SET_CombinerInputNV(__ogl_framework_api, dlsym(handle, "glCombinerInputNV")); - SET_CombinerOutputNV(__ogl_framework_api, dlsym(handle, "glCombinerOutputNV")); - SET_CombinerParameterfNV(__ogl_framework_api, dlsym(handle, "glCombinerParameterfNV")); - SET_CombinerParameterfvNV(__ogl_framework_api, dlsym(handle, "glCombinerParameterfvNV")); - SET_CombinerParameteriNV(__ogl_framework_api, dlsym(handle, "glCombinerParameteriNV")); - SET_CombinerParameterivNV(__ogl_framework_api, dlsym(handle, "glCombinerParameterivNV")); - SET_FinalCombinerInputNV(__ogl_framework_api, dlsym(handle, "glFinalCombinerInputNV")); - SET_GetCombinerInputParameterfvNV(__ogl_framework_api, dlsym(handle, "glGetCombinerInputParameterfvNV")); - SET_GetCombinerInputParameterivNV(__ogl_framework_api, dlsym(handle, "glGetCombinerInputParameterivNV")); - SET_GetCombinerOutputParameterfvNV(__ogl_framework_api, dlsym(handle, "glGetCombinerOutputParameterfvNV")); - SET_GetCombinerOutputParameterivNV(__ogl_framework_api, dlsym(handle, "glGetCombinerOutputParameterivNV")); - SET_GetFinalCombinerInputParameterfvNV(__ogl_framework_api, dlsym(handle, "glGetFinalCombinerInputParameterfvNV")); - SET_GetFinalCombinerInputParameterivNV(__ogl_framework_api, dlsym(handle, "glGetFinalCombinerInputParameterivNV")); - - /* GL_NV_vertex_array_range */ - SET_FlushVertexArrayRangeNV(__ogl_framework_api, dlsym(handle, "glFlushVertexArrayRangeNV")); - SET_VertexArrayRangeNV(__ogl_framework_api, dlsym(handle, "glVertexArrayRangeNV")); - - /* GL_NV_vertex_program */ - SET_AreProgramsResidentNV(__ogl_framework_api, dlsym(handle, "glAreProgramsResidentNV")); - SET_BindProgramNV(__ogl_framework_api, dlsym(handle, "glBindProgramNV")); - SET_DeleteProgramsNV(__ogl_framework_api, dlsym(handle, "glDeleteProgramsNV")); - SET_ExecuteProgramNV(__ogl_framework_api, dlsym(handle, "glExecuteProgramNV")); - SET_GenProgramsNV(__ogl_framework_api, dlsym(handle, "glGenProgramsNV")); - SET_GetProgramParameterdvNV(__ogl_framework_api, dlsym(handle, "glGetProgramParameterdvNV")); - SET_GetProgramParameterfvNV(__ogl_framework_api, dlsym(handle, "glGetProgramParameterfvNV")); - SET_GetProgramStringNV(__ogl_framework_api, dlsym(handle, "glGetProgramStringNV")); - SET_GetProgramivNV(__ogl_framework_api, dlsym(handle, "glGetProgramivNV")); - SET_GetTrackMatrixivNV(__ogl_framework_api, dlsym(handle, "glGetTrackMatrixivNV")); - SET_GetVertexAttribPointervNV(__ogl_framework_api, dlsym(handle, "glGetVertexAttribPointervNV")); - SET_GetVertexAttribdvNV(__ogl_framework_api, dlsym(handle, "glGetVertexAttribdvNV")); - SET_GetVertexAttribfvNV(__ogl_framework_api, dlsym(handle, "glGetVertexAttribfvNV")); - SET_GetVertexAttribivNV(__ogl_framework_api, dlsym(handle, "glGetVertexAttribivNV")); - SET_IsProgramNV(__ogl_framework_api, dlsym(handle, "glIsProgramNV")); - SET_LoadProgramNV(__ogl_framework_api, dlsym(handle, "glLoadProgramNV")); - SET_ProgramParameters4dvNV(__ogl_framework_api, dlsym(handle, "glProgramParameters4dvNV")); - SET_ProgramParameters4fvNV(__ogl_framework_api, dlsym(handle, "glProgramParameters4fvNV")); - SET_RequestResidentProgramsNV(__ogl_framework_api, dlsym(handle, "glRequestResidentProgramsNV")); - SET_TrackMatrixNV(__ogl_framework_api, dlsym(handle, "glTrackMatrixNV")); - SET_VertexAttrib1dNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib1dNV")); - SET_VertexAttrib1dvNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib1dvNV")); - SET_VertexAttrib1fNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib1fNV")); - SET_VertexAttrib1fvNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib1fvNV")); - SET_VertexAttrib1sNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib1sNV")); - SET_VertexAttrib1svNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib1svNV")); - SET_VertexAttrib2dNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib2dNV")); - SET_VertexAttrib2dvNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib2dvNV")); - SET_VertexAttrib2fNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib2fNV")); - SET_VertexAttrib2fvNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib2fvNV")); - SET_VertexAttrib2sNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib2sNV")); - SET_VertexAttrib2svNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib2svNV")); - SET_VertexAttrib3dNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib3dNV")); - SET_VertexAttrib3dvNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib3dvNV")); - SET_VertexAttrib3fNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib3fNV")); - SET_VertexAttrib3fvNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib3fvNV")); - SET_VertexAttrib3sNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib3sNV")); - SET_VertexAttrib3svNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib3svNV")); - SET_VertexAttrib4dNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib4dNV")); - SET_VertexAttrib4dvNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib4dvNV")); - SET_VertexAttrib4fNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib4fNV")); - SET_VertexAttrib4fvNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib4fvNV")); - SET_VertexAttrib4sNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib4sNV")); - SET_VertexAttrib4svNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib4svNV")); - SET_VertexAttrib4ubNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib4ubNV")); - SET_VertexAttrib4ubvNV(__ogl_framework_api, dlsym(handle, "glVertexAttrib4ubvNV")); - SET_VertexAttribPointerNV(__ogl_framework_api, dlsym(handle, "glVertexAttribPointerNV")); - SET_VertexAttribs1dvNV(__ogl_framework_api, dlsym(handle, "glVertexAttribs1dvNV")); - SET_VertexAttribs1fvNV(__ogl_framework_api, dlsym(handle, "glVertexAttribs1fvNV")); - SET_VertexAttribs1svNV(__ogl_framework_api, dlsym(handle, "glVertexAttribs1svNV")); - SET_VertexAttribs2dvNV(__ogl_framework_api, dlsym(handle, "glVertexAttribs2dvNV")); - SET_VertexAttribs2fvNV(__ogl_framework_api, dlsym(handle, "glVertexAttribs2fvNV")); - SET_VertexAttribs2svNV(__ogl_framework_api, dlsym(handle, "glVertexAttribs2svNV")); - SET_VertexAttribs3dvNV(__ogl_framework_api, dlsym(handle, "glVertexAttribs3dvNV")); - SET_VertexAttribs3fvNV(__ogl_framework_api, dlsym(handle, "glVertexAttribs3fvNV")); - SET_VertexAttribs3svNV(__ogl_framework_api, dlsym(handle, "glVertexAttribs3svNV")); - SET_VertexAttribs4dvNV(__ogl_framework_api, dlsym(handle, "glVertexAttribs4dvNV")); - SET_VertexAttribs4fvNV(__ogl_framework_api, dlsym(handle, "glVertexAttribs4fvNV")); - SET_VertexAttribs4svNV(__ogl_framework_api, dlsym(handle, "glVertexAttribs4svNV")); - SET_VertexAttribs4ubvNV(__ogl_framework_api, dlsym(handle, "glVertexAttribs4ubvNV")); - - /* GL_SGIS_multisample */ - SET_SampleMaskSGIS(__ogl_framework_api, dlsym(handle, "glSampleMaskSGIS")); - SET_SamplePatternSGIS(__ogl_framework_api, dlsym(handle, "glSamplePatternSGIS")); - - /* GL_SGIS_pixel_texture */ - SET_GetPixelTexGenParameterfvSGIS(__ogl_framework_api, dlsym(handle, "glGetPixelTexGenParameterfvSGIS")); - SET_GetPixelTexGenParameterivSGIS(__ogl_framework_api, dlsym(handle, "glGetPixelTexGenParameterivSGIS")); - SET_PixelTexGenParameterfSGIS(__ogl_framework_api, dlsym(handle, "glPixelTexGenParameterfSGIS")); - SET_PixelTexGenParameterfvSGIS(__ogl_framework_api, dlsym(handle, "glPixelTexGenParameterfvSGIS")); - SET_PixelTexGenParameteriSGIS(__ogl_framework_api, dlsym(handle, "glPixelTexGenParameteriSGIS")); - SET_PixelTexGenParameterivSGIS(__ogl_framework_api, dlsym(handle, "glPixelTexGenParameterivSGIS")); - SET_PixelTexGenSGIX(__ogl_framework_api, dlsym(handle, "glPixelTexGenSGIX")); - - /* GL_EXT_separate_shader_objects */ - SET_ActiveProgramEXT(__ogl_framework_api, dlsym(handle, "glActiveProgramEXT")); - SET_CreateShaderProgramEXT(__ogl_framework_api, dlsym(handle, "glCreateShaderProgramEXT")); - SET_UseShaderProgramEXT(__ogl_framework_api, dlsym(handle, "glUseShaderProgramEXT")); - - /* GL_NV_conditional_render */ - SET_BeginConditionalRenderNV(__ogl_framework_api, dlsym(handle, "glBeginConditionalRenderNV")); - SET_EndConditionalRenderNV(__ogl_framework_api, dlsym(handle, "glEndConditionalRenderNV")); - - /* GL_EXT_transform_feedback */ - SET_BeginTransformFeedbackEXT(__ogl_framework_api, dlsym(handle, "glBeginTransformFeedbackEXT")); - SET_EndTransformFeedbackEXT(__ogl_framework_api, dlsym(handle, "glEndTransformFeedbackEXT")); - SET_BindBufferBaseEXT(__ogl_framework_api, dlsym(handle, "glBindBufferBaseEXT")); - SET_BindBufferOffsetEXT(__ogl_framework_api, dlsym(handle, "glBindBufferOffsetEXT")); - SET_BindBufferRangeEXT(__ogl_framework_api, dlsym(handle, "glBindBufferRangeEXT")); - SET_TransformFeedbackVaryingsEXT(__ogl_framework_api, dlsym(handle, "glTransformFeedbackVaryingsEXT")); - SET_GetTransformFeedbackVaryingEXT(__ogl_framework_api, dlsym(handle, "glGetTransformFeedbackVaryingEXT")); - - /* GL_EXT_gpu_shader4 */ - SET_BindFragDataLocationEXT(__ogl_framework_api, dlsym(handle, "glBindFragDataLocationEXT")); - SET_GetFragDataLocationEXT(__ogl_framework_api, dlsym(handle, "glGetFragDataLocationEXT")); - SET_GetUniformuivEXT(__ogl_framework_api, dlsym(handle, "glGetUniformuivEXT")); - SET_Uniform1uiEXT(__ogl_framework_api, dlsym(handle, "glUniform1uiEXT")); - SET_Uniform1uivEXT(__ogl_framework_api, dlsym(handle, "glUniform1uivEXT")); - SET_Uniform2uiEXT(__ogl_framework_api, dlsym(handle, "glUniform2uiEXT")); - SET_Uniform2uivEXT(__ogl_framework_api, dlsym(handle, "glUniform2uivEXT")); - SET_Uniform3uiEXT(__ogl_framework_api, dlsym(handle, "glUniform3uiEXT")); - SET_Uniform3uivEXT(__ogl_framework_api, dlsym(handle, "glUniform3uivEXT")); - SET_Uniform4uiEXT(__ogl_framework_api, dlsym(handle, "glUniform4uiEXT")); - SET_Uniform4uivEXT(__ogl_framework_api, dlsym(handle, "glUniform4uivEXT")); - - /* GL_ARB_sampler_objects */ - SET_BindSampler(__ogl_framework_api, dlsym(handle, "glBindSampler")); - SET_DeleteSamplers(__ogl_framework_api, dlsym(handle, "glDeleteSamplers")); - SET_GenSamplers(__ogl_framework_api, dlsym(handle, "glGenSamplers")); - SET_GetSamplerParameterIiv(__ogl_framework_api, dlsym(handle, "glGetSamplerParameterIiv")); - SET_GetSamplerParameterIuiv(__ogl_framework_api, dlsym(handle, "glGetSamplerParameterIuiv")); - SET_GetSamplerParameterfv(__ogl_framework_api, dlsym(handle, "glGetSamplerParameterfv")); - SET_GetSamplerParameteriv(__ogl_framework_api, dlsym(handle, "glGetSamplerParameteriv")); - SET_IsSampler(__ogl_framework_api, dlsym(handle, "glIsSampler")); - SET_SamplerParameterIiv(__ogl_framework_api, dlsym(handle, "glSamplerParameterIiv")); - SET_SamplerParameterIuiv(__ogl_framework_api, dlsym(handle, "glSamplerParameterIuiv")); - SET_SamplerParameterf(__ogl_framework_api, dlsym(handle, "glSamplerParameterf")); - SET_SamplerParameterfv(__ogl_framework_api, dlsym(handle, "glSamplerParameterfv")); - SET_SamplerParameteri(__ogl_framework_api, dlsym(handle, "glSamplerParameteri")); - SET_SamplerParameteriv(__ogl_framework_api, dlsym(handle, "glSamplerParameteriv")); - - /* GL_ARB_transform_feedback2 */ - SET_BindTransformFeedback(__ogl_framework_api, dlsym(handle, "glBindTransformFeedback")); - SET_DeleteTransformFeedbacks(__ogl_framework_api, dlsym(handle, "glDeleteTransformFeedbacks")); - SET_DrawTransformFeedback(__ogl_framework_api, dlsym(handle, "glDrawTransformFeedback")); - SET_GenTransformFeedbacks(__ogl_framework_api, dlsym(handle, "glGenTransformFeedbacks")); - SET_IsTransformFeedback(__ogl_framework_api, dlsym(handle, "glIsTransformFeedback")); - SET_PauseTransformFeedback(__ogl_framework_api, dlsym(handle, "glPauseTransformFeedback")); - SET_ResumeTransformFeedback(__ogl_framework_api, dlsym(handle, "glResumeTransformFeedback")); - - /* GL_ARB_vertex_array_object */ - SET_BindVertexArray(__ogl_framework_api, dlsym(handle, "glBindVertexArray")); - SET_GenVertexArrays(__ogl_framework_api, dlsym(handle, "glGenVertexArrays")); - - /* GL_ARB_draw_buffers_blend */ - SET_BlendEquationSeparateiARB(__ogl_framework_api, dlsym(handle, "glBlendEquationSeparateiARB")); - SET_BlendEquationiARB(__ogl_framework_api, dlsym(handle, "glBlendEquationiARB")); - SET_BlendFuncSeparateiARB(__ogl_framework_api, dlsym(handle, "glBlendFuncSeparateiARB")); - SET_BlendFunciARB(__ogl_framework_api, dlsym(handle, "glBlendFunciARB")); - - /* GL_APPLE_flush_buffer_range */ - SET_BufferParameteriAPPLE(__ogl_framework_api, dlsym(handle, "glBufferParameteriAPPLE")); - SET_FlushMappedBufferRangeAPPLE(__ogl_framework_api, dlsym(handle, "glFlushMappedBufferRangeAPPLE")); - - /* GL_ARB_color_buffer_float */ - SET_ClampColorARB(__ogl_framework_api, dlsym(handle, "glClampColorARB")); - - /* GL_EXT_texture_integer */ - SET_ClearColorIiEXT(__ogl_framework_api, dlsym(handle, "glClearColorIiEXT")); - SET_ClearColorIuiEXT(__ogl_framework_api, dlsym(handle, "glClearColorIuiEXT")); - SET_TexParameterIivEXT(__ogl_framework_api, dlsym(handle, "glTexParameterIivEXT")); - SET_TexParameterIuivEXT(__ogl_framework_api, dlsym(handle, "glTexParameterIuivEXT")); - SET_GetTexParameterIivEXT(__ogl_framework_api, dlsym(handle, "glGetTexParameterIivEXT")); - SET_GetTexParameterIuivEXT(__ogl_framework_api, dlsym(handle, "glGetTexParameterIuivEXT")); - - /* GL_ARB_ES2_compatibility */ - SET_ClearDepthf(__ogl_framework_api, dlsym(handle, "glClearDepthf")); - SET_DepthRangef(__ogl_framework_api, dlsym(handle, "glDepthRangef")); - SET_GetShaderPrecisionFormat(__ogl_framework_api, dlsym(handle, "glGetShaderPrecisionFormat")); - SET_ReleaseShaderCompiler(__ogl_framework_api, dlsym(handle, "glReleaseShaderCompiler")); - SET_ShaderBinary(__ogl_framework_api, dlsym(handle, "glShaderBinary")); - - /* GL_EXT_draw_buffers2 */ - SET_ColorMaskIndexedEXT(__ogl_framework_api, dlsym(handle, "glColorMaskIndexedEXT")); - SET_DisableIndexedEXT(__ogl_framework_api, dlsym(handle, "glDisableIndexedEXT")); - SET_EnableIndexedEXT(__ogl_framework_api, dlsym(handle, "glEnableIndexedEXT")); - SET_GetBooleanIndexedvEXT(__ogl_framework_api, dlsym(handle, "glGetBooleanIndexedvEXT")); - SET_GetIntegerIndexedvEXT(__ogl_framework_api, dlsym(handle, "glGetIntegerIndexedvEXT")); - SET_IsEnabledIndexedEXT(__ogl_framework_api, dlsym(handle, "glIsEnabledIndexedEXT")); - - /* GL_ARB_draw_instanced */ - SET_DrawArraysInstancedARB(__ogl_framework_api, dlsym(handle, "glDrawArraysInstancedARB")); - SET_DrawElementsInstancedARB(__ogl_framework_api, dlsym(handle, "glDrawElementsInstancedARB")); - - /* GL_ARB_geometry_shader4 */ - SET_FramebufferTextureARB(__ogl_framework_api, dlsym(handle, "glFramebufferTextureARB")); - SET_FramebufferTextureFaceARB(__ogl_framework_api, dlsym(handle, "glFramebufferTextureFaceARB")); - SET_ProgramParameteriARB(__ogl_framework_api, dlsym(handle, "glProgramParameteriARB")); - - /* GL_ARB_sync */ - SET_ClientWaitSync(__ogl_framework_api, dlsym(handle, "glClientWaitSync")); - SET_DeleteSync(__ogl_framework_api, dlsym(handle, "glDeleteSync")); - SET_FenceSync(__ogl_framework_api, dlsym(handle, "glFenceSync")); - SET_GetInteger64v(__ogl_framework_api, dlsym(handle, "glGetInteger64v")); - SET_GetSynciv(__ogl_framework_api, dlsym(handle, "glGetSynciv")); - SET_IsSync(__ogl_framework_api, dlsym(handle, "glIsSync")); - SET_WaitSync(__ogl_framework_api, dlsym(handle, "glWaitSync")); - - /* GL_ARB_copy_buffer */ - SET_CopyBufferSubData(__ogl_framework_api, dlsym(handle, "glCopyBufferSubData")); - - /* GL_ARB_draw_elements_base_vertex */ - SET_DrawElementsBaseVertex(__ogl_framework_api, dlsym(handle, "glDrawElementsBaseVertex")); - SET_DrawElementsInstancedBaseVertex(__ogl_framework_api, dlsym(handle, "glDrawElementsInstancedBaseVertex")); - SET_DrawRangeElementsBaseVertex(__ogl_framework_api, dlsym(handle, "glDrawRangeElementsBaseVertex")); - SET_MultiDrawElementsBaseVertex(__ogl_framework_api, dlsym(handle, "glMultiDrawElementsBaseVertex")); - - /* GL_ARB_map_buffer_range */ - SET_FlushMappedBufferRange(__ogl_framework_api, dlsym(handle, "glFlushMappedBufferRange")); - SET_MapBufferRange(__ogl_framework_api, dlsym(handle, "glMapBufferRange")); - - /* GL_ARB_robustness */ - SET_GetGraphicsResetStatusARB(__ogl_framework_api, dlsym(handle, "glGetGraphicsResetStatusARB")); - SET_GetnColorTableARB(__ogl_framework_api, dlsym(handle, "glGetnColorTableARB")); - SET_GetnCompressedTexImageARB(__ogl_framework_api, dlsym(handle, "glGetnCompressedTexImageARB")); - SET_GetnConvolutionFilterARB(__ogl_framework_api, dlsym(handle, "glGetnConvolutionFilterARB")); - SET_GetnHistogramARB(__ogl_framework_api, dlsym(handle, "glGetnHistogramARB")); - SET_GetnMapdvARB(__ogl_framework_api, dlsym(handle, "glGetnMapdvARB")); - SET_GetnMapfvARB(__ogl_framework_api, dlsym(handle, "glGetnMapfvARB")); - SET_GetnMapivARB(__ogl_framework_api, dlsym(handle, "glGetnMapivARB")); - SET_GetnMinmaxARB(__ogl_framework_api, dlsym(handle, "glGetnMinmaxARB")); - SET_GetnPixelMapfvARB(__ogl_framework_api, dlsym(handle, "glGetnPixelMapfvARB")); - SET_GetnPixelMapuivARB(__ogl_framework_api, dlsym(handle, "glGetnPixelMapuivARB")); - SET_GetnPixelMapusvARB(__ogl_framework_api, dlsym(handle, "glGetnPixelMapusvARB")); - SET_GetnPolygonStippleARB(__ogl_framework_api, dlsym(handle, "glGetnPolygonStippleARB")); - SET_GetnSeparableFilterARB(__ogl_framework_api, dlsym(handle, "glGetnSeparableFilterARB")); - SET_GetnTexImageARB(__ogl_framework_api, dlsym(handle, "glGetnTexImageARB")); - SET_GetnUniformdvARB(__ogl_framework_api, dlsym(handle, "glGetnUniformdvARB")); - SET_GetnUniformfvARB(__ogl_framework_api, dlsym(handle, "glGetnUniformfvARB")); - SET_GetnUniformivARB(__ogl_framework_api, dlsym(handle, "glGetnUniformivARB")); - SET_GetnUniformuivARB(__ogl_framework_api, dlsym(handle, "glGetnUniformuivARB")); - SET_ReadnPixelsARB(__ogl_framework_api, dlsym(handle, "glReadnPixelsARB")); - - /* GL_APPLE_object_purgeable */ - SET_GetObjectParameterivAPPLE(__ogl_framework_api, dlsym(handle, "glGetObjectParameterivAPPLE")); - SET_ObjectPurgeableAPPLE(__ogl_framework_api, dlsym(handle, "glObjectPurgeableAPPLE")); - SET_ObjectUnpurgeableAPPLE(__ogl_framework_api, dlsym(handle, "glObjectUnpurgeableAPPLE")); - - /* GL_ATI_envmap_bumpmap */ - SET_GetTexBumpParameterfvATI(__ogl_framework_api, dlsym(handle, "glGetTexBumpParameterfvATI")); - SET_GetTexBumpParameterivATI(__ogl_framework_api, dlsym(handle, "glGetTexBumpParameterivATI")); - SET_TexBumpParameterfvATI(__ogl_framework_api, dlsym(handle, "glTexBumpParameterfvATI")); - SET_TexBumpParameterivATI(__ogl_framework_api, dlsym(handle, "glTexBumpParameterivATI")); - - /* GL_APPLE_texture_range */ - SET_GetTexParameterPointervAPPLE(__ogl_framework_api, dlsym(handle, "glGetTexParameterPointervAPPLE")); - SET_TextureRangeAPPLE(__ogl_framework_api, dlsym(handle, "glTextureRangeAPPLE")); - - /* GL_NV_vertex_program4 */ - SET_GetVertexAttribIivEXT(__ogl_framework_api, dlsym(handle, "glGetVertexAttribIivEXT")); - SET_GetVertexAttribIuivEXT(__ogl_framework_api, dlsym(handle, "glGetVertexAttribIuivEXT")); - SET_VertexAttribDivisor(__ogl_framework_api, dlsym(handle, "glVertexAttribDivisor")); - SET_VertexAttribDivisorARB(__ogl_framework_api, dlsym(handle, "glVertexAttribDivisorARB")); - SET_VertexAttribI1iEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI1iEXT")); - SET_VertexAttribI1ivEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI1ivEXT")); - SET_VertexAttribI1uiEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI1uiEXT")); - SET_VertexAttribI1uivEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI1uivEXT")); - SET_VertexAttribI2iEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI2iEXT")); - SET_VertexAttribI2ivEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI2ivEXT")); - SET_VertexAttribI2uiEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI2uiEXT")); - SET_VertexAttribI2uivEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI2uivEXT")); - SET_VertexAttribI3iEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI3iEXT")); - SET_VertexAttribI3ivEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI3ivEXT")); - SET_VertexAttribI3uiEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI3uiEXT")); - SET_VertexAttribI3uivEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI3uivEXT")); - SET_VertexAttribI4bvEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI4bvEXT")); - SET_VertexAttribI4iEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI4iEXT")); - SET_VertexAttribI4ivEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI4ivEXT")); - SET_VertexAttribI4svEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI4svEXT")); - SET_VertexAttribI4ubvEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI4ubvEXT")); - SET_VertexAttribI4uiEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI4uiEXT")); - SET_VertexAttribI4uivEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI4uivEXT")); - SET_VertexAttribI4usvEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribI4usvEXT")); - SET_VertexAttribIPointerEXT(__ogl_framework_api, dlsym(handle, "glVertexAttribIPointerEXT")); - - /* GL_NV_primitive_restart */ - SET_PrimitiveRestartIndexNV(__ogl_framework_api, dlsym(handle, "glPrimitiveRestartIndexNV")); - SET_PrimitiveRestartNV(__ogl_framework_api, dlsym(handle, "glPrimitiveRestartNV")); - - /* GL_EXT_provoking_vertex */ - SET_ProvokingVertexEXT(__ogl_framework_api, dlsym(handle, "glProvokingVertexEXT")); - - /* GL_ARB_texture_buffer_object */ - SET_TexBufferARB(__ogl_framework_api, dlsym(handle, "glTexBufferARB")); - - /* GL_NV_texture_barrier */ - SET_TextureBarrierNV(__ogl_framework_api, dlsym(handle, "glTextureBarrierNV")); - - /* GL_ARB_framebuffer_object */ - SET_RenderbufferStorageMultisample(__ogl_framework_api, dlsym(handle, "glRenderbufferStorageMultisample")); - - /* GL_OES_EGL_image */ - SET_EGLImageTargetRenderbufferStorageOES(__ogl_framework_api, dlsym(handle, "glEGLImageTargetRenderbufferStorageOES")); - SET_EGLImageTargetTexture2DOES(__ogl_framework_api, dlsym(handle, "glEGLImageTargetTexture2DOES")); - __applegl_api = malloc(sizeof(struct _glapi_table)); assert(__applegl_api); memcpy(__applegl_api, __ogl_framework_api, sizeof(struct _glapi_table)); diff --git a/src/glx/apple/apple_glx.c b/src/glx/apple/apple_glx.c index a76cb4cac1f..d94c1e0fb16 100644 --- a/src/glx/apple/apple_glx.c +++ b/src/glx/apple/apple_glx.c @@ -131,7 +131,6 @@ apple_init_glx(Display * dpy) } apple_cgl_init(); - apple_xgl_init_direct(); (void) apple_glx_get_client_id(); XAppleDRISetSurfaceNotifyHandler(surface_notify_handler); diff --git a/src/glx/apple/apple_glx.h b/src/glx/apple/apple_glx.h index 25f5ea66ee3..c70fc009dd5 100644 --- a/src/glx/apple/apple_glx.h +++ b/src/glx/apple/apple_glx.h @@ -45,6 +45,6 @@ void apple_glx_swap_buffers(void *ptr); void apple_glx_waitx(Display * dpy, void *ptr); int apple_get_dri_event_base(void); -void apple_xgl_init_direct(void); +void apple_glapi_set_dispatch(void); #endif diff --git a/src/glx/apple/apple_visual.c b/src/glx/apple/apple_visual.c index 29c6f16c4ac..a24616480ab 100644 --- a/src/glx/apple/apple_visual.c +++ b/src/glx/apple/apple_visual.c @@ -40,10 +40,19 @@ #include <OpenGL/OpenGL.h> #include <OpenGL/CGLContext.h> #include <OpenGL/CGLRenderers.h> +#include <OpenGL/CGLTypes.h> #undef glTexImage1D #undef glTexImage2D #undef glTexImage3D +#ifndef kCGLPFAOpenGLProfile +#define kCGLPFAOpenGLProfile 99 +#endif + +#ifndef kCGLOGLPVersion_3_2_Core +#define kCGLOGLPVersion_3_2_Core 0x3200 +#endif + #include "apple_cgl.h" #include "apple_visual.h" #include "apple_glx.h" @@ -54,18 +63,22 @@ enum MAX_ATTR = 60 }; -/*mode is a __GlcontextModes*/ void -apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const void *mode, +apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const struct glx_config * mode, bool * double_buffered, bool * uses_stereo, bool offscreen) { CGLPixelFormatAttribute attr[MAX_ATTR]; - const struct glx_config *c = mode; int numattr = 0; GLint vsref = 0; CGLError error = 0; + /* Request an OpenGL 3.2 profile if one is available */ + if(apple_cgl.version_major > 1 || (apple_cgl.version_major == 1 && apple_cgl.version_minor >= 3)) { + attr[numattr++] = kCGLPFAOpenGLProfile; + attr[numattr++] = kCGLOGLPVersion_3_2_Core; + } + if (offscreen) { apple_glx_diagnostic ("offscreen rendering enabled. Using kCGLPFAOffScreen\n"); @@ -95,7 +108,7 @@ apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const void *mode, */ attr[numattr++] = kCGLPFAClosestPolicy; - if (c->stereoMode) { + if (mode->stereoMode) { attr[numattr++] = kCGLPFAStereo; *uses_stereo = true; } @@ -103,7 +116,7 @@ apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const void *mode, *uses_stereo = false; } - if (c->doubleBufferMode) { + if (mode->doubleBufferMode) { attr[numattr++] = kCGLPFADoubleBuffer; *double_buffered = true; } @@ -112,32 +125,32 @@ apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const void *mode, } attr[numattr++] = kCGLPFAColorSize; - attr[numattr++] = c->redBits + c->greenBits + c->blueBits; + attr[numattr++] = mode->redBits + mode->greenBits + mode->blueBits; attr[numattr++] = kCGLPFAAlphaSize; - attr[numattr++] = c->alphaBits; + attr[numattr++] = mode->alphaBits; - if ((c->accumRedBits + c->accumGreenBits + c->accumBlueBits) > 0) { + if ((mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits) > 0) { attr[numattr++] = kCGLPFAAccumSize; - attr[numattr++] = c->accumRedBits + c->accumGreenBits + - c->accumBlueBits + c->accumAlphaBits; + attr[numattr++] = mode->accumRedBits + mode->accumGreenBits + + mode->accumBlueBits + mode->accumAlphaBits; } - if (c->depthBits > 0) { + if (mode->depthBits > 0) { attr[numattr++] = kCGLPFADepthSize; - attr[numattr++] = c->depthBits; + attr[numattr++] = mode->depthBits; } - if (c->stencilBits > 0) { + if (mode->stencilBits > 0) { attr[numattr++] = kCGLPFAStencilSize; - attr[numattr++] = c->stencilBits; + attr[numattr++] = mode->stencilBits; } - if (c->sampleBuffers > 0) { + if (mode->sampleBuffers > 0) { attr[numattr++] = kCGLPFAMultisample; attr[numattr++] = kCGLPFASampleBuffers; - attr[numattr++] = c->sampleBuffers; + attr[numattr++] = mode->sampleBuffers; attr[numattr++] = kCGLPFASamples; - attr[numattr++] = c->samples; + attr[numattr++] = mode->samples; } attr[numattr++] = 0; diff --git a/src/glx/apple/apple_visual.h b/src/glx/apple/apple_visual.h index 2cf9a9e2513..65bbc2e10ab 100644 --- a/src/glx/apple/apple_visual.h +++ b/src/glx/apple/apple_visual.h @@ -32,9 +32,9 @@ #include <stdbool.h> #include <OpenGL/CGLTypes.h> +#include "glxconfig.h" -/* mode is expected to be of type struct glx_config. */ -void apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const void *mode, +void apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const struct glx_config * mode, bool * double_buffered, bool * uses_stereo, bool offscreen); diff --git a/src/glx/applegl_glx.c b/src/glx/applegl_glx.c index 9b8605f4075..8766c88a136 100644 --- a/src/glx/applegl_glx.c +++ b/src/glx/applegl_glx.c @@ -34,16 +34,18 @@ #if defined(GLX_USE_APPLEGL) #include <stdbool.h> +#include <dlfcn.h> #include "glxclient.h" #include "apple_glx_context.h" #include "apple_glx.h" +#include "apple_cgl.h" #include "glx_error.h" static void applegl_destroy_context(struct glx_context *gc) { - apple_glx_destroy_context(&gc->driContext, gc->currentDpy); + apple_glx_destroy_context(&gc->driContext, gc->psc->dpy); } static int @@ -59,6 +61,8 @@ applegl_bind_context(struct glx_context *gc, struct glx_context *old, if (error) return 1; /* GLXBadContext is the same as Success (0) */ + apple_glapi_set_dispatch(); + return Success; } @@ -80,6 +84,12 @@ applegl_wait_x(struct glx_context *gc) apple_glx_waitx(dpy, gc->driContext); } +static void * +applegl_get_proc_address(const char *symbol) +{ + return dlsym(apple_cgl_get_dl_handle(), symbol); +} + static const struct glx_context_vtable applegl_context_vtable = { applegl_destroy_context, applegl_bind_context, @@ -89,6 +99,7 @@ static const struct glx_context_vtable applegl_context_vtable = { DRI_glXUseXFont, NULL, /* bind_tex_image, */ NULL, /* release_tex_image, */ + applegl_get_proc_address, }; struct glx_context * @@ -116,7 +127,6 @@ applegl_create_context(struct glx_screen *psc, gc->vtable = &applegl_context_vtable; gc->driContext = NULL; - gc->do_destroy = False; /* TODO: darwin: Integrate with above to do indirect */ if(apple_glx_create_context(&gc->driContext, dpy, screen, config, diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index 506754ccc1f..80e4da30beb 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -143,6 +143,8 @@ dri2_bind_context(struct glx_context *context, struct glx_context *old, pdraw = (struct dri2_drawable *) driFetchDrawable(context, draw); pread = (struct dri2_drawable *) driFetchDrawable(context, read); + driReleaseDrawables(&pcp->base); + if (pdraw == NULL || pread == NULL) return GLXBadDrawable; @@ -170,9 +172,6 @@ dri2_unbind_context(struct glx_context *context, struct glx_context *new) struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc; (*psc->core->unbindContext) (pcp->driContext); - - if (context == new) - driReleaseDrawables(&pcp->base); } static struct glx_context * @@ -768,6 +767,7 @@ static const struct glx_context_vtable dri2_context_vtable = { DRI_glXUseXFont, dri2_bind_tex_image, dri2_release_tex_image, + NULL, /* get_proc_address */ }; static void diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c index 06a73e4a6b2..bac0c9e5911 100644 --- a/src/glx/dri_common.c +++ b/src/glx/dri_common.c @@ -369,8 +369,10 @@ driFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable) if (priv->drawHash == NULL) return NULL; - if (__glxHashLookup(priv->drawHash, glxDrawable, (void *) &pdraw) == 0) + if (__glxHashLookup(priv->drawHash, glxDrawable, (void *) &pdraw) == 0) { + pdraw->refcount ++; return pdraw; + } pdraw = psc->driScreen->createDrawable(psc, glxDrawable, glxDrawable, gc->config); @@ -378,6 +380,7 @@ driFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable) (*pdraw->destroyDrawable) (pdraw); return NULL; } + pdraw->refcount = 1; return pdraw; } @@ -394,19 +397,28 @@ driReleaseDrawables(struct glx_context *gc) if (__glxHashLookup(priv->drawHash, gc->currentDrawable, (void *) &pdraw) == 0) { if (pdraw->drawable == pdraw->xDrawable) { - (*pdraw->destroyDrawable)(pdraw); - __glxHashDelete(priv->drawHash, gc->currentDrawable); + pdraw->refcount --; + if (pdraw->refcount == 0) { + (*pdraw->destroyDrawable)(pdraw); + __glxHashDelete(priv->drawHash, gc->currentDrawable); + } } } - if (gc->currentDrawable != gc->currentReadable && - __glxHashLookup(priv->drawHash, + if (__glxHashLookup(priv->drawHash, gc->currentReadable, (void *) &pdraw) == 0) { if (pdraw->drawable == pdraw->xDrawable) { - (*pdraw->destroyDrawable)(pdraw); - __glxHashDelete(priv->drawHash, gc->currentReadable); + pdraw->refcount --; + if (pdraw->refcount == 0) { + (*pdraw->destroyDrawable)(pdraw); + __glxHashDelete(priv->drawHash, gc->currentReadable); + } } } + + gc->currentDrawable = None; + gc->currentReadable = None; + } #endif /* GLX_DIRECT_RENDERING */ diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c index ff027dc9e9c..6f3b2b8900c 100644 --- a/src/glx/dri_glx.c +++ b/src/glx/dri_glx.c @@ -503,6 +503,8 @@ dri_destroy_context(struct glx_context * context) struct dri_context *pcp = (struct dri_context *) context; struct dri_screen *psc = (struct dri_screen *) context->psc; + driReleaseDrawables(&pcp->base); + if (context->xid) glx_send_destroy_context(psc->base.dpy, context->xid); @@ -526,6 +528,8 @@ dri_bind_context(struct glx_context *context, struct glx_context *old, pdraw = (struct dri_drawable *) driFetchDrawable(context, draw); pread = (struct dri_drawable *) driFetchDrawable(context, read); + driReleaseDrawables(&pcp->base); + if (pdraw == NULL || pread == NULL) return GLXBadDrawable; @@ -543,8 +547,6 @@ dri_unbind_context(struct glx_context *context, struct glx_context *new) struct dri_screen *psc = (struct dri_screen *) pcp->base.psc; (*psc->core->unbindContext) (pcp->driContext); - - driReleaseDrawables(&pcp->base); } static const struct glx_context_vtable dri_context_vtable = { @@ -556,6 +558,7 @@ static const struct glx_context_vtable dri_context_vtable = { DRI_glXUseXFont, NULL, NULL, + NULL, /* get_proc_address */ }; static struct glx_context * diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index 2eaa3c59348..d63f6e8d5ff 100644 --- a/src/glx/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -242,6 +242,8 @@ drisw_destroy_context(struct glx_context *context) struct drisw_context *pcp = (struct drisw_context *) context; struct drisw_screen *psc = (struct drisw_screen *) context->psc; + driReleaseDrawables(&pcp->base); + if (context->xid) glx_send_destroy_context(psc->base.dpy, context->xid); @@ -264,6 +266,8 @@ drisw_bind_context(struct glx_context *context, struct glx_context *old, pdraw = (struct drisw_drawable *) driFetchDrawable(context, draw); pread = (struct drisw_drawable *) driFetchDrawable(context, read); + driReleaseDrawables(&pcp->base); + if (pdraw == NULL || pread == NULL) return GLXBadDrawable; @@ -281,8 +285,6 @@ drisw_unbind_context(struct glx_context *context, struct glx_context *new) struct drisw_screen *psc = (struct drisw_screen *) pcp->base.psc; (*psc->core->unbindContext) (pcp->driContext); - - driReleaseDrawables(&pcp->base); } static const struct glx_context_vtable drisw_context_vtable = { @@ -294,6 +296,7 @@ static const struct glx_context_vtable drisw_context_vtable = { DRI_glXUseXFont, NULL, NULL, + NULL, /* get_proc_address */ }; static struct glx_context * @@ -359,10 +362,6 @@ driswCreateDrawable(struct glx_screen *base, XID xDrawable, const __DRIswrastExtension *swrast = psc->swrast; - /* Old dri can't handle GLX 1.3+ drawable constructors. */ - if (xDrawable != drawable) - return NULL; - pdp = Xmalloc(sizeof(*pdp)); if (!pdp) return NULL; diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c index 1f4c0f309fc..0e74e7ccd0e 100644 --- a/src/glx/glx_pbuffer.c +++ b/src/glx/glx_pbuffer.c @@ -187,7 +187,7 @@ determineTextureFormat(const int *attribs, int numAttribs) return 0; } -static void +static GLboolean CreateDRIDrawable(Display *dpy, struct glx_config *config, XID drawable, XID glxdrawable, const int *attrib_list, size_t num_attribs) @@ -198,22 +198,24 @@ CreateDRIDrawable(Display *dpy, struct glx_config *config, psc = priv->screens[config->screen]; if (psc->driScreen == NULL) - return; + return GL_TRUE; pdraw = psc->driScreen->createDrawable(psc, drawable, glxdrawable, config); if (pdraw == NULL) { fprintf(stderr, "failed to create drawable\n"); - return; + return GL_FALSE; } if (__glxHashInsert(priv->drawHash, glxdrawable, pdraw)) { (*pdraw->destroyDrawable) (pdraw); - return; /* FIXME: Check what we're supposed to do here... */ + return GL_FALSE; } pdraw->textureTarget = determineTextureTarget(attrib_list, num_attribs); pdraw->textureFormat = determineTextureFormat(attrib_list, num_attribs); + + return GL_TRUE; } static void @@ -234,11 +236,12 @@ DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable) #else -static void +static GLboolean CreateDRIDrawable(Display *dpy, const struct glx_config * fbconfig, XID drawable, XID glxdrawable, const int *attrib_list, size_t num_attribs) { + return GL_FALSE; } static void @@ -364,6 +367,27 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable, return 0; } +static void +protocolDestroyDrawable(Display *dpy, GLXDrawable drawable, CARD32 glxCode) +{ + xGLXDestroyPbufferReq *req; + CARD8 opcode; + + opcode = __glXSetupForCommand(dpy); + if (!opcode) + return; + + LockDisplay(dpy); + + GetReq(GLXDestroyPbuffer, req); + req->reqType = opcode; + req->glxCode = glxCode; + req->pbuffer = (GLXPbuffer) drawable; + + UnlockDisplay(dpy); + SyncHandle(); +} + /** * Create a non-pbuffer GLX drawable. */ @@ -405,7 +429,14 @@ CreateDrawable(Display *dpy, struct glx_config *config, UnlockDisplay(dpy); SyncHandle(); - CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i); + if (!CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i)) { + if (glxCode == X_GLXCreatePixmap) + glxCode = X_GLXDestroyPixmap; + else + glxCode = X_GLXDestroyWindow; + protocolDestroyDrawable(dpy, xid, glxCode); + xid = None; + } return xid; } @@ -417,27 +448,11 @@ CreateDrawable(Display *dpy, struct glx_config *config, static void DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode) { - xGLXDestroyPbufferReq *req; - CARD8 opcode; - if ((dpy == NULL) || (drawable == 0)) { return; } - - opcode = __glXSetupForCommand(dpy); - if (!opcode) - return; - - LockDisplay(dpy); - - GetReq(GLXDestroyPbuffer, req); - req->reqType = opcode; - req->glxCode = glxCode; - req->pbuffer = (GLXPbuffer) drawable; - - UnlockDisplay(dpy); - SyncHandle(); + protocolDestroyDrawable(dpy, drawable, glxCode); DestroyDRIDrawable(dpy, drawable, GL_FALSE); @@ -466,6 +481,7 @@ CreatePbuffer(Display * dpy, struct glx_config *config, CARD8 opcode; unsigned int i; Pixmap pixmap; + GLboolean glx_1_3 = GL_FALSE; i = 0; if (attrib_list) { @@ -484,6 +500,8 @@ CreatePbuffer(Display * dpy, struct glx_config *config, xGLXCreatePbufferReq *req; unsigned int extra = (size_in_attribs) ? 0 : 2; + glx_1_3 = GL_TRUE; + GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req); data = (CARD32 *) (req + 1); @@ -528,7 +546,12 @@ CreatePbuffer(Display * dpy, struct glx_config *config, pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen), width, height, config->rgbBits); - CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i); + if (!CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i)) { + CARD32 o = glx_1_3 ? X_GLXDestroyPbuffer : X_GLXvop_DestroyGLXPbufferSGIX; + XFreePixmap(dpy, pixmap); + protocolDestroyDrawable(dpy, id, o); + id = None; + } return id; } diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 9262f86f1f3..06415288165 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -138,6 +138,7 @@ struct __GLXDRIdrawableRec GLenum textureTarget; GLenum textureFormat; /* EXT_texture_from_pixmap support */ unsigned long eventMask; + int refcount; }; /* @@ -223,7 +224,7 @@ struct glx_context_vtable { GLXDrawable drawable, int buffer, const int *attrib_list); void (*release_tex_image)(Display * dpy, GLXDrawable drawable, int buffer); - + void * (*get_proc_address)(const char *symbol); }; extern void @@ -335,7 +336,6 @@ struct glx_context #if defined(GLX_DIRECT_RENDERING) && defined(GLX_USE_APPLEGL) void *driContext; - Bool do_destroy; #endif /** diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index 774d38b2634..191b321ce32 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -354,8 +354,9 @@ glx_send_destroy_context(Display *dpy, XID xid) /* ** Destroy the named context */ -static void -DestroyContext(Display * dpy, GLXContext ctx) + +_X_EXPORT void +glXDestroyContext(Display * dpy, GLXContext ctx) { struct glx_context *gc = (struct glx_context *) ctx; @@ -377,14 +378,7 @@ DestroyContext(Display * dpy, GLXContext ctx) } __glXUnlock(); - if (gc->vtable->destroy) - gc->vtable->destroy(gc); -} - -_X_EXPORT void -glXDestroyContext(Display * dpy, GLXContext gc) -{ - DestroyContext(dpy, gc); + gc->vtable->destroy(gc); } /* @@ -646,19 +640,33 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap) psc = priv->screens[vis->screen]; if (psc->driScreen == NULL) - break; + return xid; + config = glx_config_find_visual(psc->visuals, vis->visualid); pdraw = psc->driScreen->createDrawable(psc, pixmap, xid, config); if (pdraw == NULL) { fprintf(stderr, "failed to create pixmap\n"); + xid = None; break; } if (__glxHashInsert(priv->drawHash, xid, pdraw)) { (*pdraw->destroyDrawable) (pdraw); - return None; /* FIXME: Check what we're supposed to do here... */ + xid = None; + break; } } while (0); + + if (xid == None) { + xGLXDestroyGLXPixmapReq *dreq; + LockDisplay(dpy); + GetReq(GLXDestroyGLXPixmap, dreq); + dreq->reqType = opcode; + dreq->glxCode = X_GLXDestroyGLXPixmap; + dreq->glxpixmap = xid; + UnlockDisplay(dpy); + SyncHandle(); + } #endif return xid; @@ -1480,12 +1488,9 @@ _X_EXPORT GLXContextID glXGetContextIDEXT(const GLXContext ctx_user) return ctx->xid; } -_X_EXPORT void -glXFreeContextEXT(Display * dpy, GLXContext ctx) -{ - DestroyContext(dpy, ctx); -} - +_X_EXPORT +GLX_ALIAS_VOID(glXFreeContextEXT, (Display *dpy, GLXContext ctx), (dpy, ctx), + glXDestroyContext); _X_EXPORT GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, @@ -2522,6 +2527,12 @@ _X_EXPORT void (*glXGetProcAddressARB(const GLubyte * procName)) (void) #endif if (!f) f = (gl_function) _glapi_get_proc_address((const char *) procName); + if (!f) { + struct glx_context *gc = __glXGetCurrentContext(); + + if (gc != NULL && gc->vtable->get_proc_address != NULL) + f = gc->vtable->get_proc_address((const char *) procName); + } } return f; } diff --git a/src/glx/glxcurrent.c b/src/glx/glxcurrent.c index 064fd71ae6e..c92a2fd3cc2 100644 --- a/src/glx/glxcurrent.c +++ b/src/glx/glxcurrent.c @@ -212,7 +212,6 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, { struct glx_context *gc = (struct glx_context *) gc_user; struct glx_context *oldGC = __glXGetCurrentContext(); - int ret = Success; /* XXX: If this is left out, then libGL ends up not having this * symbol, and drivers using it fail to load. Compare the @@ -255,37 +254,45 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, if (--oldGC->thread_refcount == 0) { oldGC->vtable->unbind(oldGC, gc); oldGC->currentDpy = 0; - oldGC->currentDrawable = None; - oldGC->currentReadable = None; - - if (oldGC->xid == None && oldGC != gc) { - /* We are switching away from a context that was - * previously destroyed, so we need to free the memory - * for the old handle. */ - oldGC->vtable->destroy(oldGC); - } } } if (gc) { - if (gc->thread_refcount++ == 0) { - gc->currentDpy = dpy; - gc->currentDrawable = draw; - gc->currentReadable = read; + /* Attempt to bind the context. We do this before mucking with + * gc and __glXSetCurrentContext to properly handle our state in + * case of an error. + * + * If an error occurs, set the Null context since we've already + * blown away our old context. The caller is responsible for + * figuring out how to handle setting a valid context. + */ + if (gc->vtable->bind(gc, oldGC, draw, read) != Success) { + __glXSetCurrentContextNull(); + __glXUnlock(); + __glXGenerateError(dpy, None, GLXBadContext, X_GLXMakeContextCurrent); + return GL_FALSE; } + + if (gc->thread_refcount == 0) { + gc->currentDpy = dpy; + gc->currentDrawable = draw; + gc->currentReadable = read; + } + gc->thread_refcount++; __glXSetCurrentContext(gc); - ret = gc->vtable->bind(gc, oldGC, draw, read); } else { __glXSetCurrentContextNull(); } - __glXUnlock(); - - if (ret) { - __glXGenerateError(dpy, None, ret, X_GLXMakeContextCurrent); - return GL_FALSE; + if (oldGC->thread_refcount == 0 && oldGC != &dummyContext && oldGC->xid == None) { + /* We are switching away from a context that was + * previously destroyed, so we need to free the memory + * for the old handle. */ + oldGC->vtable->destroy(oldGC); } + __glXUnlock(); + return GL_TRUE; } diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c index b4f16c72536..7b542dd159c 100644 --- a/src/glx/indirect_glx.c +++ b/src/glx/indirect_glx.c @@ -335,6 +335,7 @@ static const struct glx_context_vtable indirect_context_vtable = { indirect_use_x_font, indirect_bind_tex_image, indirect_release_tex_image, + NULL, /* get_proc_address */ }; /** diff --git a/src/mapi/glapi/SConscript b/src/mapi/glapi/SConscript index 276b2160246..a7764745eda 100644 --- a/src/mapi/glapi/SConscript +++ b/src/mapi/glapi/SConscript @@ -52,30 +52,23 @@ if env['platform'] != 'winddk': if env['gcc'] and env['platform'] != 'windows': if env['machine'] == 'x86': env.Append(CPPDEFINES = [ - 'USE_X86_ASM', - 'USE_MMX_ASM', - 'USE_3DNOW_ASM', - 'USE_SSE_ASM', + 'USE_X86_ASM', ]) glapi_sources += [ 'glapi_x86.S', ] elif env['machine'] == 'x86_64': env.Append(CPPDEFINES = [ - 'USE_X86_64_ASM', + 'USE_X86_64_ASM', ]) glapi_sources += [ 'glapi_x86-64.S' ] - elif env['machine'] == 'ppc': + elif env['machine'] == 'sparc': env.Append(CPPDEFINES = [ - 'USE_PPC_ASM', - 'USE_VMX_ASM', + 'USE_SPARC_ASM', ]) glapi_sources += [ - ] - elif env['machine'] == 'sparc': - glapi_sources += [ 'glapi_sparc.S' ] else: diff --git a/src/mapi/glapi/gen/ARB_geometry_shader4.xml b/src/mapi/glapi/gen/ARB_geometry_shader4.xml index ca9a101a0ee..d9e540fc94d 100644 --- a/src/mapi/glapi/gen/ARB_geometry_shader4.xml +++ b/src/mapi/glapi/gen/ARB_geometry_shader4.xml @@ -38,7 +38,7 @@ <param name="texture" type="GLuint"/> <param name="level" type="GLint"/> </function> - <function name="FramebufferTextureLayerARB" alias="FramebufferTextureLayer"> + <function name="FramebufferTextureLayerARB" alias="FramebufferTextureLayerEXT"> <param name="target" type="GLenum"/> <param name="attachment" type="GLenum"/> <param name="texture" type="GLuint"/> diff --git a/src/mapi/glapi/gen/Makefile b/src/mapi/glapi/gen/Makefile index 7415bdc5267..3e101f3a10f 100644 --- a/src/mapi/glapi/gen/Makefile +++ b/src/mapi/glapi/gen/Makefile @@ -16,7 +16,8 @@ MESA_GLAPI_OUTPUTS = \ $(MESA_GLAPI_DIR)/glapi_mapi_tmp.h \ $(MESA_GLAPI_DIR)/glprocs.h \ $(MESA_GLAPI_DIR)/glapitemp.h \ - $(MESA_GLAPI_DIR)/glapitable.h + $(MESA_GLAPI_DIR)/glapitable.h \ + $(MESA_GLAPI_DIR)/glapi_gentable.c MESA_GLAPI_ASM_OUTPUTS = \ $(MESA_GLAPI_DIR)/glapi_x86.S \ @@ -50,7 +51,8 @@ XORG_GLAPI_OUTPUTS = \ $(XORG_GLAPI_DIR)/glprocs.h \ $(XORG_GLAPI_DIR)/glapioffsets.h \ $(XORG_GLAPI_DIR)/glapitable.h \ - $(XORG_GLAPI_DIR)/glapidispatch.h + $(XORG_GLAPI_DIR)/glapidispatch.h \ + $(XORG_GLAPI_DIR)/glapi_gentable.c XORG_OUTPUTS = \ $(XORG_GLAPI_FILES) \ @@ -162,6 +164,9 @@ $(MESA_GLAPI_DIR)/glapitemp.h: gl_apitemp.py $(COMMON) $(MESA_GLAPI_DIR)/glapitable.h: gl_table.py $(COMMON) $(PYTHON2) $(PYTHON_FLAGS) $< > $@ +$(MESA_GLAPI_DIR)/glapi_gentable.c: gl_gentable.py $(COMMON) + $(PYTHON2) $(PYTHON_FLAGS) $< > $@ + ###################################################################### $(MESA_GLAPI_DIR)/glapi_x86.S: gl_x86_asm.py $(COMMON) diff --git a/src/mapi/glapi/gen/gl_gentable.py b/src/mapi/glapi/gen/gl_gentable.py new file mode 100644 index 00000000000..814238a76e1 --- /dev/null +++ b/src/mapi/glapi/gen/gl_gentable.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python + +# (C) Copyright IBM Corporation 2004, 2005 +# (C) Copyright Apple Inc. 2011 +# 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 +# on 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 +# IBM 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: +# Jeremy Huddleston <[email protected]> +# +# Based on code ogiginally by: +# Ian Romanick <[email protected]> + +import license +import gl_XML, glX_XML +import sys, getopt + +header = """ +#if defined(DEBUG) && !defined(_WIN32_WCE) +#include <execinfo.h> +#endif + +#include <dlfcn.h> +#include <stdlib.h> +#include <stdio.h> + +#include <GL/gl.h> + +#include "glapi.h" +#include "glapitable.h" + +static void +__glapi_gentable_NoOp(void) { +#if defined(DEBUG) && !defined(_WIN32_WCE) + if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) { + const char *fstr = "Unknown"; + void *frames[2]; + + if(backtrace(frames, 2) == 2) { + Dl_info info; + dladdr(frames[1], &info); + if(info.dli_sname) + fstr = info.dli_sname; + } + + fprintf(stderr, "Call to unimplemented API: %s\\n", fstr); + } +#endif +} + +static void +__glapi_gentable_set_remaining_noop(struct _glapi_table *disp) { + GLuint entries = _glapi_get_dispatch_table_size(); + void **dispatch = (void **) disp; + int i; + + /* ISO C is annoying sometimes */ + union {_glapi_proc p; void *v;} p; + p.p = __glapi_gentable_NoOp; + + for(i=0; i < entries; i++) + if(dispatch[i] == NULL) + dispatch[i] = p.v; +} + +struct _glapi_table * +_glapi_create_table_from_handle(void *handle, const char *symbol_prefix) { + struct _glapi_table *disp = calloc(1, sizeof(struct _glapi_table)); + char symboln[512]; + + if(!disp) + return NULL; + + if(symbol_prefix == NULL) + symbol_prefix = ""; +""" + +footer = """ + __glapi_gentable_set_remaining_noop(disp); + + return disp; +} +""" + +body_template = """ + if(!disp->%(name)s) { + void ** procp = (void **) &disp->%(name)s; + snprintf(symboln, sizeof(symboln), "%%s%(entry_point)s", symbol_prefix); + *procp = dlsym(handle, symboln); + } +""" + +class PrintCode(gl_XML.gl_print_base): + + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.name = "gl_gen_table.py (from Mesa)" + self.license = license.bsd_license_template % ( \ +"""Copyright (C) 1999-2001 Brian Paul All Rights Reserved. +(C) Copyright IBM Corporation 2004, 2005 +(C) Copyright Apple Inc 2011""", "BRIAN PAUL, IBM") + + return + + + def get_stack_size(self, f): + size = 0 + for p in f.parameterIterator(): + if p.is_padding: + continue + + size += p.get_stack_size() + + return size + + + def printRealHeader(self): + print header + return + + + def printRealFooter(self): + print footer + return + + + def printBody(self, api): + for f in api.functionIterateByOffset(): + for entry_point in f.entry_points: + vars = { 'entry_point' : entry_point, + 'name' : f.name } + + print body_template % vars + return + +def show_usage(): + print "Usage: %s [-f input_file_name]" % sys.argv[0] + sys.exit(1) + +if __name__ == '__main__': + file_name = "gl_API.xml" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "m:f:") + except Exception,e: + show_usage() + + for (arg,val) in args: + if arg == "-f": + file_name = val + + printer = PrintCode() + + api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory()) + printer.Print(api) diff --git a/src/mapi/glapi/glapi.h b/src/mapi/glapi/glapi.h index e909cf892ab..35dffd75767 100644 --- a/src/mapi/glapi/glapi.h +++ b/src/mapi/glapi/glapi.h @@ -159,6 +159,10 @@ _GLAPI_EXPORT const char * _glapi_get_proc_name(unsigned int offset); +_GLAPI_EXPORT struct _glapi_table * +_glapi_create_table_from_handle(void *handle, const char *symbol_prefix); + + _GLAPI_EXPORT unsigned long _glthread_GetID(void); diff --git a/src/mapi/glapi/glapi_gentable.c b/src/mapi/glapi/glapi_gentable.c new file mode 100644 index 00000000000..6dd02a747e1 --- /dev/null +++ b/src/mapi/glapi/glapi_gentable.c @@ -0,0 +1,9138 @@ +/* DO NOT EDIT - This file generated automatically by gl_gen_table.py (from Mesa) script */ + +/* + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * (C) Copyright IBM Corporation 2004, 2005 + * (C) Copyright Apple Inc 2011 + * 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 + * BRIAN PAUL, IBM, + * AND/OR THEIR 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. + */ + + +#if defined(DEBUG) && !defined(_WIN32_WCE) +#include <execinfo.h> +#endif + +#include <dlfcn.h> +#include <stdlib.h> +#include <stdio.h> + +#include <GL/gl.h> + +#include "glapi.h" +#include "glapitable.h" + +static void +__glapi_gentable_NoOp(void) { +#if defined(DEBUG) && !defined(_WIN32_WCE) + if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) { + const char *fstr = "Unknown"; + void *frames[2]; + + if(backtrace(frames, 2) == 2) { + Dl_info info; + dladdr(frames[1], &info); + if(info.dli_sname) + fstr = info.dli_sname; + } + + fprintf(stderr, "Call to unimplemented API: %s\n", fstr); + } +#endif +} + +static void +__glapi_gentable_set_remaining_noop(struct _glapi_table *disp) { + GLuint entries = _glapi_get_dispatch_table_size(); + void **dispatch = (void **) disp; + int i; + + /* ISO C is annoying sometimes */ + union {_glapi_proc p; void *v;} p; + p.p = __glapi_gentable_NoOp; + + for(i=0; i < entries; i++) + if(dispatch[i] == NULL) + dispatch[i] = p.v; +} + +struct _glapi_table * +_glapi_create_table_from_handle(void *handle, const char *symbol_prefix) { + struct _glapi_table *disp = calloc(1, sizeof(struct _glapi_table)); + char symboln[512]; + + if(!disp) + return NULL; + + if(symbol_prefix == NULL) + symbol_prefix = ""; + + + if(!disp->NewList) { + void ** procp = (void **) &disp->NewList; + snprintf(symboln, sizeof(symboln), "%sNewList", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EndList) { + void ** procp = (void **) &disp->EndList; + snprintf(symboln, sizeof(symboln), "%sEndList", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CallList) { + void ** procp = (void **) &disp->CallList; + snprintf(symboln, sizeof(symboln), "%sCallList", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CallLists) { + void ** procp = (void **) &disp->CallLists; + snprintf(symboln, sizeof(symboln), "%sCallLists", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteLists) { + void ** procp = (void **) &disp->DeleteLists; + snprintf(symboln, sizeof(symboln), "%sDeleteLists", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenLists) { + void ** procp = (void **) &disp->GenLists; + snprintf(symboln, sizeof(symboln), "%sGenLists", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ListBase) { + void ** procp = (void **) &disp->ListBase; + snprintf(symboln, sizeof(symboln), "%sListBase", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Begin) { + void ** procp = (void **) &disp->Begin; + snprintf(symboln, sizeof(symboln), "%sBegin", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Bitmap) { + void ** procp = (void **) &disp->Bitmap; + snprintf(symboln, sizeof(symboln), "%sBitmap", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3b) { + void ** procp = (void **) &disp->Color3b; + snprintf(symboln, sizeof(symboln), "%sColor3b", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3bv) { + void ** procp = (void **) &disp->Color3bv; + snprintf(symboln, sizeof(symboln), "%sColor3bv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3d) { + void ** procp = (void **) &disp->Color3d; + snprintf(symboln, sizeof(symboln), "%sColor3d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3dv) { + void ** procp = (void **) &disp->Color3dv; + snprintf(symboln, sizeof(symboln), "%sColor3dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3f) { + void ** procp = (void **) &disp->Color3f; + snprintf(symboln, sizeof(symboln), "%sColor3f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3fv) { + void ** procp = (void **) &disp->Color3fv; + snprintf(symboln, sizeof(symboln), "%sColor3fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3i) { + void ** procp = (void **) &disp->Color3i; + snprintf(symboln, sizeof(symboln), "%sColor3i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3iv) { + void ** procp = (void **) &disp->Color3iv; + snprintf(symboln, sizeof(symboln), "%sColor3iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3s) { + void ** procp = (void **) &disp->Color3s; + snprintf(symboln, sizeof(symboln), "%sColor3s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3sv) { + void ** procp = (void **) &disp->Color3sv; + snprintf(symboln, sizeof(symboln), "%sColor3sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3ub) { + void ** procp = (void **) &disp->Color3ub; + snprintf(symboln, sizeof(symboln), "%sColor3ub", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3ubv) { + void ** procp = (void **) &disp->Color3ubv; + snprintf(symboln, sizeof(symboln), "%sColor3ubv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3ui) { + void ** procp = (void **) &disp->Color3ui; + snprintf(symboln, sizeof(symboln), "%sColor3ui", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3uiv) { + void ** procp = (void **) &disp->Color3uiv; + snprintf(symboln, sizeof(symboln), "%sColor3uiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3us) { + void ** procp = (void **) &disp->Color3us; + snprintf(symboln, sizeof(symboln), "%sColor3us", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color3usv) { + void ** procp = (void **) &disp->Color3usv; + snprintf(symboln, sizeof(symboln), "%sColor3usv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4b) { + void ** procp = (void **) &disp->Color4b; + snprintf(symboln, sizeof(symboln), "%sColor4b", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4bv) { + void ** procp = (void **) &disp->Color4bv; + snprintf(symboln, sizeof(symboln), "%sColor4bv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4d) { + void ** procp = (void **) &disp->Color4d; + snprintf(symboln, sizeof(symboln), "%sColor4d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4dv) { + void ** procp = (void **) &disp->Color4dv; + snprintf(symboln, sizeof(symboln), "%sColor4dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4f) { + void ** procp = (void **) &disp->Color4f; + snprintf(symboln, sizeof(symboln), "%sColor4f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4fv) { + void ** procp = (void **) &disp->Color4fv; + snprintf(symboln, sizeof(symboln), "%sColor4fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4i) { + void ** procp = (void **) &disp->Color4i; + snprintf(symboln, sizeof(symboln), "%sColor4i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4iv) { + void ** procp = (void **) &disp->Color4iv; + snprintf(symboln, sizeof(symboln), "%sColor4iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4s) { + void ** procp = (void **) &disp->Color4s; + snprintf(symboln, sizeof(symboln), "%sColor4s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4sv) { + void ** procp = (void **) &disp->Color4sv; + snprintf(symboln, sizeof(symboln), "%sColor4sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4ub) { + void ** procp = (void **) &disp->Color4ub; + snprintf(symboln, sizeof(symboln), "%sColor4ub", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4ubv) { + void ** procp = (void **) &disp->Color4ubv; + snprintf(symboln, sizeof(symboln), "%sColor4ubv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4ui) { + void ** procp = (void **) &disp->Color4ui; + snprintf(symboln, sizeof(symboln), "%sColor4ui", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4uiv) { + void ** procp = (void **) &disp->Color4uiv; + snprintf(symboln, sizeof(symboln), "%sColor4uiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4us) { + void ** procp = (void **) &disp->Color4us; + snprintf(symboln, sizeof(symboln), "%sColor4us", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Color4usv) { + void ** procp = (void **) &disp->Color4usv; + snprintf(symboln, sizeof(symboln), "%sColor4usv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EdgeFlag) { + void ** procp = (void **) &disp->EdgeFlag; + snprintf(symboln, sizeof(symboln), "%sEdgeFlag", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EdgeFlagv) { + void ** procp = (void **) &disp->EdgeFlagv; + snprintf(symboln, sizeof(symboln), "%sEdgeFlagv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->End) { + void ** procp = (void **) &disp->End; + snprintf(symboln, sizeof(symboln), "%sEnd", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Indexd) { + void ** procp = (void **) &disp->Indexd; + snprintf(symboln, sizeof(symboln), "%sIndexd", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Indexdv) { + void ** procp = (void **) &disp->Indexdv; + snprintf(symboln, sizeof(symboln), "%sIndexdv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Indexf) { + void ** procp = (void **) &disp->Indexf; + snprintf(symboln, sizeof(symboln), "%sIndexf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Indexfv) { + void ** procp = (void **) &disp->Indexfv; + snprintf(symboln, sizeof(symboln), "%sIndexfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Indexi) { + void ** procp = (void **) &disp->Indexi; + snprintf(symboln, sizeof(symboln), "%sIndexi", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Indexiv) { + void ** procp = (void **) &disp->Indexiv; + snprintf(symboln, sizeof(symboln), "%sIndexiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Indexs) { + void ** procp = (void **) &disp->Indexs; + snprintf(symboln, sizeof(symboln), "%sIndexs", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Indexsv) { + void ** procp = (void **) &disp->Indexsv; + snprintf(symboln, sizeof(symboln), "%sIndexsv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Normal3b) { + void ** procp = (void **) &disp->Normal3b; + snprintf(symboln, sizeof(symboln), "%sNormal3b", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Normal3bv) { + void ** procp = (void **) &disp->Normal3bv; + snprintf(symboln, sizeof(symboln), "%sNormal3bv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Normal3d) { + void ** procp = (void **) &disp->Normal3d; + snprintf(symboln, sizeof(symboln), "%sNormal3d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Normal3dv) { + void ** procp = (void **) &disp->Normal3dv; + snprintf(symboln, sizeof(symboln), "%sNormal3dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Normal3f) { + void ** procp = (void **) &disp->Normal3f; + snprintf(symboln, sizeof(symboln), "%sNormal3f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Normal3fv) { + void ** procp = (void **) &disp->Normal3fv; + snprintf(symboln, sizeof(symboln), "%sNormal3fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Normal3i) { + void ** procp = (void **) &disp->Normal3i; + snprintf(symboln, sizeof(symboln), "%sNormal3i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Normal3iv) { + void ** procp = (void **) &disp->Normal3iv; + snprintf(symboln, sizeof(symboln), "%sNormal3iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Normal3s) { + void ** procp = (void **) &disp->Normal3s; + snprintf(symboln, sizeof(symboln), "%sNormal3s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Normal3sv) { + void ** procp = (void **) &disp->Normal3sv; + snprintf(symboln, sizeof(symboln), "%sNormal3sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos2d) { + void ** procp = (void **) &disp->RasterPos2d; + snprintf(symboln, sizeof(symboln), "%sRasterPos2d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos2dv) { + void ** procp = (void **) &disp->RasterPos2dv; + snprintf(symboln, sizeof(symboln), "%sRasterPos2dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos2f) { + void ** procp = (void **) &disp->RasterPos2f; + snprintf(symboln, sizeof(symboln), "%sRasterPos2f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos2fv) { + void ** procp = (void **) &disp->RasterPos2fv; + snprintf(symboln, sizeof(symboln), "%sRasterPos2fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos2i) { + void ** procp = (void **) &disp->RasterPos2i; + snprintf(symboln, sizeof(symboln), "%sRasterPos2i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos2iv) { + void ** procp = (void **) &disp->RasterPos2iv; + snprintf(symboln, sizeof(symboln), "%sRasterPos2iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos2s) { + void ** procp = (void **) &disp->RasterPos2s; + snprintf(symboln, sizeof(symboln), "%sRasterPos2s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos2sv) { + void ** procp = (void **) &disp->RasterPos2sv; + snprintf(symboln, sizeof(symboln), "%sRasterPos2sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos3d) { + void ** procp = (void **) &disp->RasterPos3d; + snprintf(symboln, sizeof(symboln), "%sRasterPos3d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos3dv) { + void ** procp = (void **) &disp->RasterPos3dv; + snprintf(symboln, sizeof(symboln), "%sRasterPos3dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos3f) { + void ** procp = (void **) &disp->RasterPos3f; + snprintf(symboln, sizeof(symboln), "%sRasterPos3f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos3fv) { + void ** procp = (void **) &disp->RasterPos3fv; + snprintf(symboln, sizeof(symboln), "%sRasterPos3fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos3i) { + void ** procp = (void **) &disp->RasterPos3i; + snprintf(symboln, sizeof(symboln), "%sRasterPos3i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos3iv) { + void ** procp = (void **) &disp->RasterPos3iv; + snprintf(symboln, sizeof(symboln), "%sRasterPos3iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos3s) { + void ** procp = (void **) &disp->RasterPos3s; + snprintf(symboln, sizeof(symboln), "%sRasterPos3s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos3sv) { + void ** procp = (void **) &disp->RasterPos3sv; + snprintf(symboln, sizeof(symboln), "%sRasterPos3sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos4d) { + void ** procp = (void **) &disp->RasterPos4d; + snprintf(symboln, sizeof(symboln), "%sRasterPos4d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos4dv) { + void ** procp = (void **) &disp->RasterPos4dv; + snprintf(symboln, sizeof(symboln), "%sRasterPos4dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos4f) { + void ** procp = (void **) &disp->RasterPos4f; + snprintf(symboln, sizeof(symboln), "%sRasterPos4f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos4fv) { + void ** procp = (void **) &disp->RasterPos4fv; + snprintf(symboln, sizeof(symboln), "%sRasterPos4fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos4i) { + void ** procp = (void **) &disp->RasterPos4i; + snprintf(symboln, sizeof(symboln), "%sRasterPos4i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos4iv) { + void ** procp = (void **) &disp->RasterPos4iv; + snprintf(symboln, sizeof(symboln), "%sRasterPos4iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos4s) { + void ** procp = (void **) &disp->RasterPos4s; + snprintf(symboln, sizeof(symboln), "%sRasterPos4s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RasterPos4sv) { + void ** procp = (void **) &disp->RasterPos4sv; + snprintf(symboln, sizeof(symboln), "%sRasterPos4sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Rectd) { + void ** procp = (void **) &disp->Rectd; + snprintf(symboln, sizeof(symboln), "%sRectd", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Rectdv) { + void ** procp = (void **) &disp->Rectdv; + snprintf(symboln, sizeof(symboln), "%sRectdv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Rectf) { + void ** procp = (void **) &disp->Rectf; + snprintf(symboln, sizeof(symboln), "%sRectf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Rectfv) { + void ** procp = (void **) &disp->Rectfv; + snprintf(symboln, sizeof(symboln), "%sRectfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Recti) { + void ** procp = (void **) &disp->Recti; + snprintf(symboln, sizeof(symboln), "%sRecti", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Rectiv) { + void ** procp = (void **) &disp->Rectiv; + snprintf(symboln, sizeof(symboln), "%sRectiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Rects) { + void ** procp = (void **) &disp->Rects; + snprintf(symboln, sizeof(symboln), "%sRects", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Rectsv) { + void ** procp = (void **) &disp->Rectsv; + snprintf(symboln, sizeof(symboln), "%sRectsv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord1d) { + void ** procp = (void **) &disp->TexCoord1d; + snprintf(symboln, sizeof(symboln), "%sTexCoord1d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord1dv) { + void ** procp = (void **) &disp->TexCoord1dv; + snprintf(symboln, sizeof(symboln), "%sTexCoord1dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord1f) { + void ** procp = (void **) &disp->TexCoord1f; + snprintf(symboln, sizeof(symboln), "%sTexCoord1f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord1fv) { + void ** procp = (void **) &disp->TexCoord1fv; + snprintf(symboln, sizeof(symboln), "%sTexCoord1fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord1i) { + void ** procp = (void **) &disp->TexCoord1i; + snprintf(symboln, sizeof(symboln), "%sTexCoord1i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord1iv) { + void ** procp = (void **) &disp->TexCoord1iv; + snprintf(symboln, sizeof(symboln), "%sTexCoord1iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord1s) { + void ** procp = (void **) &disp->TexCoord1s; + snprintf(symboln, sizeof(symboln), "%sTexCoord1s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord1sv) { + void ** procp = (void **) &disp->TexCoord1sv; + snprintf(symboln, sizeof(symboln), "%sTexCoord1sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord2d) { + void ** procp = (void **) &disp->TexCoord2d; + snprintf(symboln, sizeof(symboln), "%sTexCoord2d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord2dv) { + void ** procp = (void **) &disp->TexCoord2dv; + snprintf(symboln, sizeof(symboln), "%sTexCoord2dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord2f) { + void ** procp = (void **) &disp->TexCoord2f; + snprintf(symboln, sizeof(symboln), "%sTexCoord2f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord2fv) { + void ** procp = (void **) &disp->TexCoord2fv; + snprintf(symboln, sizeof(symboln), "%sTexCoord2fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord2i) { + void ** procp = (void **) &disp->TexCoord2i; + snprintf(symboln, sizeof(symboln), "%sTexCoord2i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord2iv) { + void ** procp = (void **) &disp->TexCoord2iv; + snprintf(symboln, sizeof(symboln), "%sTexCoord2iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord2s) { + void ** procp = (void **) &disp->TexCoord2s; + snprintf(symboln, sizeof(symboln), "%sTexCoord2s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord2sv) { + void ** procp = (void **) &disp->TexCoord2sv; + snprintf(symboln, sizeof(symboln), "%sTexCoord2sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord3d) { + void ** procp = (void **) &disp->TexCoord3d; + snprintf(symboln, sizeof(symboln), "%sTexCoord3d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord3dv) { + void ** procp = (void **) &disp->TexCoord3dv; + snprintf(symboln, sizeof(symboln), "%sTexCoord3dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord3f) { + void ** procp = (void **) &disp->TexCoord3f; + snprintf(symboln, sizeof(symboln), "%sTexCoord3f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord3fv) { + void ** procp = (void **) &disp->TexCoord3fv; + snprintf(symboln, sizeof(symboln), "%sTexCoord3fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord3i) { + void ** procp = (void **) &disp->TexCoord3i; + snprintf(symboln, sizeof(symboln), "%sTexCoord3i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord3iv) { + void ** procp = (void **) &disp->TexCoord3iv; + snprintf(symboln, sizeof(symboln), "%sTexCoord3iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord3s) { + void ** procp = (void **) &disp->TexCoord3s; + snprintf(symboln, sizeof(symboln), "%sTexCoord3s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord3sv) { + void ** procp = (void **) &disp->TexCoord3sv; + snprintf(symboln, sizeof(symboln), "%sTexCoord3sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord4d) { + void ** procp = (void **) &disp->TexCoord4d; + snprintf(symboln, sizeof(symboln), "%sTexCoord4d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord4dv) { + void ** procp = (void **) &disp->TexCoord4dv; + snprintf(symboln, sizeof(symboln), "%sTexCoord4dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord4f) { + void ** procp = (void **) &disp->TexCoord4f; + snprintf(symboln, sizeof(symboln), "%sTexCoord4f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord4fv) { + void ** procp = (void **) &disp->TexCoord4fv; + snprintf(symboln, sizeof(symboln), "%sTexCoord4fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord4i) { + void ** procp = (void **) &disp->TexCoord4i; + snprintf(symboln, sizeof(symboln), "%sTexCoord4i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord4iv) { + void ** procp = (void **) &disp->TexCoord4iv; + snprintf(symboln, sizeof(symboln), "%sTexCoord4iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord4s) { + void ** procp = (void **) &disp->TexCoord4s; + snprintf(symboln, sizeof(symboln), "%sTexCoord4s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoord4sv) { + void ** procp = (void **) &disp->TexCoord4sv; + snprintf(symboln, sizeof(symboln), "%sTexCoord4sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex2d) { + void ** procp = (void **) &disp->Vertex2d; + snprintf(symboln, sizeof(symboln), "%sVertex2d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex2dv) { + void ** procp = (void **) &disp->Vertex2dv; + snprintf(symboln, sizeof(symboln), "%sVertex2dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex2f) { + void ** procp = (void **) &disp->Vertex2f; + snprintf(symboln, sizeof(symboln), "%sVertex2f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex2fv) { + void ** procp = (void **) &disp->Vertex2fv; + snprintf(symboln, sizeof(symboln), "%sVertex2fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex2i) { + void ** procp = (void **) &disp->Vertex2i; + snprintf(symboln, sizeof(symboln), "%sVertex2i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex2iv) { + void ** procp = (void **) &disp->Vertex2iv; + snprintf(symboln, sizeof(symboln), "%sVertex2iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex2s) { + void ** procp = (void **) &disp->Vertex2s; + snprintf(symboln, sizeof(symboln), "%sVertex2s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex2sv) { + void ** procp = (void **) &disp->Vertex2sv; + snprintf(symboln, sizeof(symboln), "%sVertex2sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex3d) { + void ** procp = (void **) &disp->Vertex3d; + snprintf(symboln, sizeof(symboln), "%sVertex3d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex3dv) { + void ** procp = (void **) &disp->Vertex3dv; + snprintf(symboln, sizeof(symboln), "%sVertex3dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex3f) { + void ** procp = (void **) &disp->Vertex3f; + snprintf(symboln, sizeof(symboln), "%sVertex3f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex3fv) { + void ** procp = (void **) &disp->Vertex3fv; + snprintf(symboln, sizeof(symboln), "%sVertex3fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex3i) { + void ** procp = (void **) &disp->Vertex3i; + snprintf(symboln, sizeof(symboln), "%sVertex3i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex3iv) { + void ** procp = (void **) &disp->Vertex3iv; + snprintf(symboln, sizeof(symboln), "%sVertex3iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex3s) { + void ** procp = (void **) &disp->Vertex3s; + snprintf(symboln, sizeof(symboln), "%sVertex3s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex3sv) { + void ** procp = (void **) &disp->Vertex3sv; + snprintf(symboln, sizeof(symboln), "%sVertex3sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex4d) { + void ** procp = (void **) &disp->Vertex4d; + snprintf(symboln, sizeof(symboln), "%sVertex4d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex4dv) { + void ** procp = (void **) &disp->Vertex4dv; + snprintf(symboln, sizeof(symboln), "%sVertex4dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex4f) { + void ** procp = (void **) &disp->Vertex4f; + snprintf(symboln, sizeof(symboln), "%sVertex4f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex4fv) { + void ** procp = (void **) &disp->Vertex4fv; + snprintf(symboln, sizeof(symboln), "%sVertex4fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex4i) { + void ** procp = (void **) &disp->Vertex4i; + snprintf(symboln, sizeof(symboln), "%sVertex4i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex4iv) { + void ** procp = (void **) &disp->Vertex4iv; + snprintf(symboln, sizeof(symboln), "%sVertex4iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex4s) { + void ** procp = (void **) &disp->Vertex4s; + snprintf(symboln, sizeof(symboln), "%sVertex4s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Vertex4sv) { + void ** procp = (void **) &disp->Vertex4sv; + snprintf(symboln, sizeof(symboln), "%sVertex4sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClipPlane) { + void ** procp = (void **) &disp->ClipPlane; + snprintf(symboln, sizeof(symboln), "%sClipPlane", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorMaterial) { + void ** procp = (void **) &disp->ColorMaterial; + snprintf(symboln, sizeof(symboln), "%sColorMaterial", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CullFace) { + void ** procp = (void **) &disp->CullFace; + snprintf(symboln, sizeof(symboln), "%sCullFace", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Fogf) { + void ** procp = (void **) &disp->Fogf; + snprintf(symboln, sizeof(symboln), "%sFogf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Fogfv) { + void ** procp = (void **) &disp->Fogfv; + snprintf(symboln, sizeof(symboln), "%sFogfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Fogi) { + void ** procp = (void **) &disp->Fogi; + snprintf(symboln, sizeof(symboln), "%sFogi", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Fogiv) { + void ** procp = (void **) &disp->Fogiv; + snprintf(symboln, sizeof(symboln), "%sFogiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FrontFace) { + void ** procp = (void **) &disp->FrontFace; + snprintf(symboln, sizeof(symboln), "%sFrontFace", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Hint) { + void ** procp = (void **) &disp->Hint; + snprintf(symboln, sizeof(symboln), "%sHint", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Lightf) { + void ** procp = (void **) &disp->Lightf; + snprintf(symboln, sizeof(symboln), "%sLightf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Lightfv) { + void ** procp = (void **) &disp->Lightfv; + snprintf(symboln, sizeof(symboln), "%sLightfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Lighti) { + void ** procp = (void **) &disp->Lighti; + snprintf(symboln, sizeof(symboln), "%sLighti", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Lightiv) { + void ** procp = (void **) &disp->Lightiv; + snprintf(symboln, sizeof(symboln), "%sLightiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LightModelf) { + void ** procp = (void **) &disp->LightModelf; + snprintf(symboln, sizeof(symboln), "%sLightModelf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LightModelfv) { + void ** procp = (void **) &disp->LightModelfv; + snprintf(symboln, sizeof(symboln), "%sLightModelfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LightModeli) { + void ** procp = (void **) &disp->LightModeli; + snprintf(symboln, sizeof(symboln), "%sLightModeli", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LightModeliv) { + void ** procp = (void **) &disp->LightModeliv; + snprintf(symboln, sizeof(symboln), "%sLightModeliv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LineStipple) { + void ** procp = (void **) &disp->LineStipple; + snprintf(symboln, sizeof(symboln), "%sLineStipple", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LineWidth) { + void ** procp = (void **) &disp->LineWidth; + snprintf(symboln, sizeof(symboln), "%sLineWidth", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Materialf) { + void ** procp = (void **) &disp->Materialf; + snprintf(symboln, sizeof(symboln), "%sMaterialf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Materialfv) { + void ** procp = (void **) &disp->Materialfv; + snprintf(symboln, sizeof(symboln), "%sMaterialfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Materiali) { + void ** procp = (void **) &disp->Materiali; + snprintf(symboln, sizeof(symboln), "%sMateriali", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Materialiv) { + void ** procp = (void **) &disp->Materialiv; + snprintf(symboln, sizeof(symboln), "%sMaterialiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PointSize) { + void ** procp = (void **) &disp->PointSize; + snprintf(symboln, sizeof(symboln), "%sPointSize", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PolygonMode) { + void ** procp = (void **) &disp->PolygonMode; + snprintf(symboln, sizeof(symboln), "%sPolygonMode", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PolygonStipple) { + void ** procp = (void **) &disp->PolygonStipple; + snprintf(symboln, sizeof(symboln), "%sPolygonStipple", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Scissor) { + void ** procp = (void **) &disp->Scissor; + snprintf(symboln, sizeof(symboln), "%sScissor", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ShadeModel) { + void ** procp = (void **) &disp->ShadeModel; + snprintf(symboln, sizeof(symboln), "%sShadeModel", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexParameterf) { + void ** procp = (void **) &disp->TexParameterf; + snprintf(symboln, sizeof(symboln), "%sTexParameterf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexParameterfv) { + void ** procp = (void **) &disp->TexParameterfv; + snprintf(symboln, sizeof(symboln), "%sTexParameterfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexParameteri) { + void ** procp = (void **) &disp->TexParameteri; + snprintf(symboln, sizeof(symboln), "%sTexParameteri", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexParameteriv) { + void ** procp = (void **) &disp->TexParameteriv; + snprintf(symboln, sizeof(symboln), "%sTexParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexImage1D) { + void ** procp = (void **) &disp->TexImage1D; + snprintf(symboln, sizeof(symboln), "%sTexImage1D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexImage2D) { + void ** procp = (void **) &disp->TexImage2D; + snprintf(symboln, sizeof(symboln), "%sTexImage2D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexEnvf) { + void ** procp = (void **) &disp->TexEnvf; + snprintf(symboln, sizeof(symboln), "%sTexEnvf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexEnvfv) { + void ** procp = (void **) &disp->TexEnvfv; + snprintf(symboln, sizeof(symboln), "%sTexEnvfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexEnvi) { + void ** procp = (void **) &disp->TexEnvi; + snprintf(symboln, sizeof(symboln), "%sTexEnvi", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexEnviv) { + void ** procp = (void **) &disp->TexEnviv; + snprintf(symboln, sizeof(symboln), "%sTexEnviv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexGend) { + void ** procp = (void **) &disp->TexGend; + snprintf(symboln, sizeof(symboln), "%sTexGend", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexGendv) { + void ** procp = (void **) &disp->TexGendv; + snprintf(symboln, sizeof(symboln), "%sTexGendv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexGenf) { + void ** procp = (void **) &disp->TexGenf; + snprintf(symboln, sizeof(symboln), "%sTexGenf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexGenfv) { + void ** procp = (void **) &disp->TexGenfv; + snprintf(symboln, sizeof(symboln), "%sTexGenfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexGeni) { + void ** procp = (void **) &disp->TexGeni; + snprintf(symboln, sizeof(symboln), "%sTexGeni", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexGeniv) { + void ** procp = (void **) &disp->TexGeniv; + snprintf(symboln, sizeof(symboln), "%sTexGeniv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FeedbackBuffer) { + void ** procp = (void **) &disp->FeedbackBuffer; + snprintf(symboln, sizeof(symboln), "%sFeedbackBuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SelectBuffer) { + void ** procp = (void **) &disp->SelectBuffer; + snprintf(symboln, sizeof(symboln), "%sSelectBuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RenderMode) { + void ** procp = (void **) &disp->RenderMode; + snprintf(symboln, sizeof(symboln), "%sRenderMode", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->InitNames) { + void ** procp = (void **) &disp->InitNames; + snprintf(symboln, sizeof(symboln), "%sInitNames", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LoadName) { + void ** procp = (void **) &disp->LoadName; + snprintf(symboln, sizeof(symboln), "%sLoadName", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PassThrough) { + void ** procp = (void **) &disp->PassThrough; + snprintf(symboln, sizeof(symboln), "%sPassThrough", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PopName) { + void ** procp = (void **) &disp->PopName; + snprintf(symboln, sizeof(symboln), "%sPopName", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PushName) { + void ** procp = (void **) &disp->PushName; + snprintf(symboln, sizeof(symboln), "%sPushName", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawBuffer) { + void ** procp = (void **) &disp->DrawBuffer; + snprintf(symboln, sizeof(symboln), "%sDrawBuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Clear) { + void ** procp = (void **) &disp->Clear; + snprintf(symboln, sizeof(symboln), "%sClear", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClearAccum) { + void ** procp = (void **) &disp->ClearAccum; + snprintf(symboln, sizeof(symboln), "%sClearAccum", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClearIndex) { + void ** procp = (void **) &disp->ClearIndex; + snprintf(symboln, sizeof(symboln), "%sClearIndex", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClearColor) { + void ** procp = (void **) &disp->ClearColor; + snprintf(symboln, sizeof(symboln), "%sClearColor", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClearStencil) { + void ** procp = (void **) &disp->ClearStencil; + snprintf(symboln, sizeof(symboln), "%sClearStencil", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClearDepth) { + void ** procp = (void **) &disp->ClearDepth; + snprintf(symboln, sizeof(symboln), "%sClearDepth", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->StencilMask) { + void ** procp = (void **) &disp->StencilMask; + snprintf(symboln, sizeof(symboln), "%sStencilMask", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorMask) { + void ** procp = (void **) &disp->ColorMask; + snprintf(symboln, sizeof(symboln), "%sColorMask", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DepthMask) { + void ** procp = (void **) &disp->DepthMask; + snprintf(symboln, sizeof(symboln), "%sDepthMask", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IndexMask) { + void ** procp = (void **) &disp->IndexMask; + snprintf(symboln, sizeof(symboln), "%sIndexMask", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Accum) { + void ** procp = (void **) &disp->Accum; + snprintf(symboln, sizeof(symboln), "%sAccum", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Disable) { + void ** procp = (void **) &disp->Disable; + snprintf(symboln, sizeof(symboln), "%sDisable", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Enable) { + void ** procp = (void **) &disp->Enable; + snprintf(symboln, sizeof(symboln), "%sEnable", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Finish) { + void ** procp = (void **) &disp->Finish; + snprintf(symboln, sizeof(symboln), "%sFinish", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Flush) { + void ** procp = (void **) &disp->Flush; + snprintf(symboln, sizeof(symboln), "%sFlush", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PopAttrib) { + void ** procp = (void **) &disp->PopAttrib; + snprintf(symboln, sizeof(symboln), "%sPopAttrib", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PushAttrib) { + void ** procp = (void **) &disp->PushAttrib; + snprintf(symboln, sizeof(symboln), "%sPushAttrib", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Map1d) { + void ** procp = (void **) &disp->Map1d; + snprintf(symboln, sizeof(symboln), "%sMap1d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Map1f) { + void ** procp = (void **) &disp->Map1f; + snprintf(symboln, sizeof(symboln), "%sMap1f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Map2d) { + void ** procp = (void **) &disp->Map2d; + snprintf(symboln, sizeof(symboln), "%sMap2d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Map2f) { + void ** procp = (void **) &disp->Map2f; + snprintf(symboln, sizeof(symboln), "%sMap2f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MapGrid1d) { + void ** procp = (void **) &disp->MapGrid1d; + snprintf(symboln, sizeof(symboln), "%sMapGrid1d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MapGrid1f) { + void ** procp = (void **) &disp->MapGrid1f; + snprintf(symboln, sizeof(symboln), "%sMapGrid1f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MapGrid2d) { + void ** procp = (void **) &disp->MapGrid2d; + snprintf(symboln, sizeof(symboln), "%sMapGrid2d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MapGrid2f) { + void ** procp = (void **) &disp->MapGrid2f; + snprintf(symboln, sizeof(symboln), "%sMapGrid2f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EvalCoord1d) { + void ** procp = (void **) &disp->EvalCoord1d; + snprintf(symboln, sizeof(symboln), "%sEvalCoord1d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EvalCoord1dv) { + void ** procp = (void **) &disp->EvalCoord1dv; + snprintf(symboln, sizeof(symboln), "%sEvalCoord1dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EvalCoord1f) { + void ** procp = (void **) &disp->EvalCoord1f; + snprintf(symboln, sizeof(symboln), "%sEvalCoord1f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EvalCoord1fv) { + void ** procp = (void **) &disp->EvalCoord1fv; + snprintf(symboln, sizeof(symboln), "%sEvalCoord1fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EvalCoord2d) { + void ** procp = (void **) &disp->EvalCoord2d; + snprintf(symboln, sizeof(symboln), "%sEvalCoord2d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EvalCoord2dv) { + void ** procp = (void **) &disp->EvalCoord2dv; + snprintf(symboln, sizeof(symboln), "%sEvalCoord2dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EvalCoord2f) { + void ** procp = (void **) &disp->EvalCoord2f; + snprintf(symboln, sizeof(symboln), "%sEvalCoord2f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EvalCoord2fv) { + void ** procp = (void **) &disp->EvalCoord2fv; + snprintf(symboln, sizeof(symboln), "%sEvalCoord2fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EvalMesh1) { + void ** procp = (void **) &disp->EvalMesh1; + snprintf(symboln, sizeof(symboln), "%sEvalMesh1", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EvalPoint1) { + void ** procp = (void **) &disp->EvalPoint1; + snprintf(symboln, sizeof(symboln), "%sEvalPoint1", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EvalMesh2) { + void ** procp = (void **) &disp->EvalMesh2; + snprintf(symboln, sizeof(symboln), "%sEvalMesh2", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EvalPoint2) { + void ** procp = (void **) &disp->EvalPoint2; + snprintf(symboln, sizeof(symboln), "%sEvalPoint2", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->AlphaFunc) { + void ** procp = (void **) &disp->AlphaFunc; + snprintf(symboln, sizeof(symboln), "%sAlphaFunc", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendFunc) { + void ** procp = (void **) &disp->BlendFunc; + snprintf(symboln, sizeof(symboln), "%sBlendFunc", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LogicOp) { + void ** procp = (void **) &disp->LogicOp; + snprintf(symboln, sizeof(symboln), "%sLogicOp", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->StencilFunc) { + void ** procp = (void **) &disp->StencilFunc; + snprintf(symboln, sizeof(symboln), "%sStencilFunc", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->StencilOp) { + void ** procp = (void **) &disp->StencilOp; + snprintf(symboln, sizeof(symboln), "%sStencilOp", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DepthFunc) { + void ** procp = (void **) &disp->DepthFunc; + snprintf(symboln, sizeof(symboln), "%sDepthFunc", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PixelZoom) { + void ** procp = (void **) &disp->PixelZoom; + snprintf(symboln, sizeof(symboln), "%sPixelZoom", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PixelTransferf) { + void ** procp = (void **) &disp->PixelTransferf; + snprintf(symboln, sizeof(symboln), "%sPixelTransferf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PixelTransferi) { + void ** procp = (void **) &disp->PixelTransferi; + snprintf(symboln, sizeof(symboln), "%sPixelTransferi", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PixelStoref) { + void ** procp = (void **) &disp->PixelStoref; + snprintf(symboln, sizeof(symboln), "%sPixelStoref", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PixelStorei) { + void ** procp = (void **) &disp->PixelStorei; + snprintf(symboln, sizeof(symboln), "%sPixelStorei", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PixelMapfv) { + void ** procp = (void **) &disp->PixelMapfv; + snprintf(symboln, sizeof(symboln), "%sPixelMapfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PixelMapuiv) { + void ** procp = (void **) &disp->PixelMapuiv; + snprintf(symboln, sizeof(symboln), "%sPixelMapuiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PixelMapusv) { + void ** procp = (void **) &disp->PixelMapusv; + snprintf(symboln, sizeof(symboln), "%sPixelMapusv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ReadBuffer) { + void ** procp = (void **) &disp->ReadBuffer; + snprintf(symboln, sizeof(symboln), "%sReadBuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyPixels) { + void ** procp = (void **) &disp->CopyPixels; + snprintf(symboln, sizeof(symboln), "%sCopyPixels", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ReadPixels) { + void ** procp = (void **) &disp->ReadPixels; + snprintf(symboln, sizeof(symboln), "%sReadPixels", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawPixels) { + void ** procp = (void **) &disp->DrawPixels; + snprintf(symboln, sizeof(symboln), "%sDrawPixels", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetBooleanv) { + void ** procp = (void **) &disp->GetBooleanv; + snprintf(symboln, sizeof(symboln), "%sGetBooleanv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetClipPlane) { + void ** procp = (void **) &disp->GetClipPlane; + snprintf(symboln, sizeof(symboln), "%sGetClipPlane", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetDoublev) { + void ** procp = (void **) &disp->GetDoublev; + snprintf(symboln, sizeof(symboln), "%sGetDoublev", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetError) { + void ** procp = (void **) &disp->GetError; + snprintf(symboln, sizeof(symboln), "%sGetError", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetFloatv) { + void ** procp = (void **) &disp->GetFloatv; + snprintf(symboln, sizeof(symboln), "%sGetFloatv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetIntegerv) { + void ** procp = (void **) &disp->GetIntegerv; + snprintf(symboln, sizeof(symboln), "%sGetIntegerv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetLightfv) { + void ** procp = (void **) &disp->GetLightfv; + snprintf(symboln, sizeof(symboln), "%sGetLightfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetLightiv) { + void ** procp = (void **) &disp->GetLightiv; + snprintf(symboln, sizeof(symboln), "%sGetLightiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetMapdv) { + void ** procp = (void **) &disp->GetMapdv; + snprintf(symboln, sizeof(symboln), "%sGetMapdv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetMapfv) { + void ** procp = (void **) &disp->GetMapfv; + snprintf(symboln, sizeof(symboln), "%sGetMapfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetMapiv) { + void ** procp = (void **) &disp->GetMapiv; + snprintf(symboln, sizeof(symboln), "%sGetMapiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetMaterialfv) { + void ** procp = (void **) &disp->GetMaterialfv; + snprintf(symboln, sizeof(symboln), "%sGetMaterialfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetMaterialiv) { + void ** procp = (void **) &disp->GetMaterialiv; + snprintf(symboln, sizeof(symboln), "%sGetMaterialiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetPixelMapfv) { + void ** procp = (void **) &disp->GetPixelMapfv; + snprintf(symboln, sizeof(symboln), "%sGetPixelMapfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetPixelMapuiv) { + void ** procp = (void **) &disp->GetPixelMapuiv; + snprintf(symboln, sizeof(symboln), "%sGetPixelMapuiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetPixelMapusv) { + void ** procp = (void **) &disp->GetPixelMapusv; + snprintf(symboln, sizeof(symboln), "%sGetPixelMapusv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetPolygonStipple) { + void ** procp = (void **) &disp->GetPolygonStipple; + snprintf(symboln, sizeof(symboln), "%sGetPolygonStipple", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetString) { + void ** procp = (void **) &disp->GetString; + snprintf(symboln, sizeof(symboln), "%sGetString", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexEnvfv) { + void ** procp = (void **) &disp->GetTexEnvfv; + snprintf(symboln, sizeof(symboln), "%sGetTexEnvfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexEnviv) { + void ** procp = (void **) &disp->GetTexEnviv; + snprintf(symboln, sizeof(symboln), "%sGetTexEnviv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexGendv) { + void ** procp = (void **) &disp->GetTexGendv; + snprintf(symboln, sizeof(symboln), "%sGetTexGendv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexGenfv) { + void ** procp = (void **) &disp->GetTexGenfv; + snprintf(symboln, sizeof(symboln), "%sGetTexGenfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexGeniv) { + void ** procp = (void **) &disp->GetTexGeniv; + snprintf(symboln, sizeof(symboln), "%sGetTexGeniv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexImage) { + void ** procp = (void **) &disp->GetTexImage; + snprintf(symboln, sizeof(symboln), "%sGetTexImage", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexParameterfv) { + void ** procp = (void **) &disp->GetTexParameterfv; + snprintf(symboln, sizeof(symboln), "%sGetTexParameterfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexParameteriv) { + void ** procp = (void **) &disp->GetTexParameteriv; + snprintf(symboln, sizeof(symboln), "%sGetTexParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexLevelParameterfv) { + void ** procp = (void **) &disp->GetTexLevelParameterfv; + snprintf(symboln, sizeof(symboln), "%sGetTexLevelParameterfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexLevelParameteriv) { + void ** procp = (void **) &disp->GetTexLevelParameteriv; + snprintf(symboln, sizeof(symboln), "%sGetTexLevelParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsEnabled) { + void ** procp = (void **) &disp->IsEnabled; + snprintf(symboln, sizeof(symboln), "%sIsEnabled", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsList) { + void ** procp = (void **) &disp->IsList; + snprintf(symboln, sizeof(symboln), "%sIsList", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DepthRange) { + void ** procp = (void **) &disp->DepthRange; + snprintf(symboln, sizeof(symboln), "%sDepthRange", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Frustum) { + void ** procp = (void **) &disp->Frustum; + snprintf(symboln, sizeof(symboln), "%sFrustum", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LoadIdentity) { + void ** procp = (void **) &disp->LoadIdentity; + snprintf(symboln, sizeof(symboln), "%sLoadIdentity", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LoadMatrixf) { + void ** procp = (void **) &disp->LoadMatrixf; + snprintf(symboln, sizeof(symboln), "%sLoadMatrixf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LoadMatrixd) { + void ** procp = (void **) &disp->LoadMatrixd; + snprintf(symboln, sizeof(symboln), "%sLoadMatrixd", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MatrixMode) { + void ** procp = (void **) &disp->MatrixMode; + snprintf(symboln, sizeof(symboln), "%sMatrixMode", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultMatrixf) { + void ** procp = (void **) &disp->MultMatrixf; + snprintf(symboln, sizeof(symboln), "%sMultMatrixf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultMatrixd) { + void ** procp = (void **) &disp->MultMatrixd; + snprintf(symboln, sizeof(symboln), "%sMultMatrixd", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Ortho) { + void ** procp = (void **) &disp->Ortho; + snprintf(symboln, sizeof(symboln), "%sOrtho", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PopMatrix) { + void ** procp = (void **) &disp->PopMatrix; + snprintf(symboln, sizeof(symboln), "%sPopMatrix", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PushMatrix) { + void ** procp = (void **) &disp->PushMatrix; + snprintf(symboln, sizeof(symboln), "%sPushMatrix", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Rotated) { + void ** procp = (void **) &disp->Rotated; + snprintf(symboln, sizeof(symboln), "%sRotated", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Rotatef) { + void ** procp = (void **) &disp->Rotatef; + snprintf(symboln, sizeof(symboln), "%sRotatef", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Scaled) { + void ** procp = (void **) &disp->Scaled; + snprintf(symboln, sizeof(symboln), "%sScaled", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Scalef) { + void ** procp = (void **) &disp->Scalef; + snprintf(symboln, sizeof(symboln), "%sScalef", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Translated) { + void ** procp = (void **) &disp->Translated; + snprintf(symboln, sizeof(symboln), "%sTranslated", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Translatef) { + void ** procp = (void **) &disp->Translatef; + snprintf(symboln, sizeof(symboln), "%sTranslatef", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Viewport) { + void ** procp = (void **) &disp->Viewport; + snprintf(symboln, sizeof(symboln), "%sViewport", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ArrayElement) { + void ** procp = (void **) &disp->ArrayElement; + snprintf(symboln, sizeof(symboln), "%sArrayElement", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ArrayElement) { + void ** procp = (void **) &disp->ArrayElement; + snprintf(symboln, sizeof(symboln), "%sArrayElementEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindTexture) { + void ** procp = (void **) &disp->BindTexture; + snprintf(symboln, sizeof(symboln), "%sBindTexture", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindTexture) { + void ** procp = (void **) &disp->BindTexture; + snprintf(symboln, sizeof(symboln), "%sBindTextureEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorPointer) { + void ** procp = (void **) &disp->ColorPointer; + snprintf(symboln, sizeof(symboln), "%sColorPointer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DisableClientState) { + void ** procp = (void **) &disp->DisableClientState; + snprintf(symboln, sizeof(symboln), "%sDisableClientState", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawArrays) { + void ** procp = (void **) &disp->DrawArrays; + snprintf(symboln, sizeof(symboln), "%sDrawArrays", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawArrays) { + void ** procp = (void **) &disp->DrawArrays; + snprintf(symboln, sizeof(symboln), "%sDrawArraysEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawElements) { + void ** procp = (void **) &disp->DrawElements; + snprintf(symboln, sizeof(symboln), "%sDrawElements", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EdgeFlagPointer) { + void ** procp = (void **) &disp->EdgeFlagPointer; + snprintf(symboln, sizeof(symboln), "%sEdgeFlagPointer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EnableClientState) { + void ** procp = (void **) &disp->EnableClientState; + snprintf(symboln, sizeof(symboln), "%sEnableClientState", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IndexPointer) { + void ** procp = (void **) &disp->IndexPointer; + snprintf(symboln, sizeof(symboln), "%sIndexPointer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Indexub) { + void ** procp = (void **) &disp->Indexub; + snprintf(symboln, sizeof(symboln), "%sIndexub", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Indexubv) { + void ** procp = (void **) &disp->Indexubv; + snprintf(symboln, sizeof(symboln), "%sIndexubv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->InterleavedArrays) { + void ** procp = (void **) &disp->InterleavedArrays; + snprintf(symboln, sizeof(symboln), "%sInterleavedArrays", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->NormalPointer) { + void ** procp = (void **) &disp->NormalPointer; + snprintf(symboln, sizeof(symboln), "%sNormalPointer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PolygonOffset) { + void ** procp = (void **) &disp->PolygonOffset; + snprintf(symboln, sizeof(symboln), "%sPolygonOffset", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoordPointer) { + void ** procp = (void **) &disp->TexCoordPointer; + snprintf(symboln, sizeof(symboln), "%sTexCoordPointer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexPointer) { + void ** procp = (void **) &disp->VertexPointer; + snprintf(symboln, sizeof(symboln), "%sVertexPointer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->AreTexturesResident) { + void ** procp = (void **) &disp->AreTexturesResident; + snprintf(symboln, sizeof(symboln), "%sAreTexturesResident", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->AreTexturesResident) { + void ** procp = (void **) &disp->AreTexturesResident; + snprintf(symboln, sizeof(symboln), "%sAreTexturesResidentEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyTexImage1D) { + void ** procp = (void **) &disp->CopyTexImage1D; + snprintf(symboln, sizeof(symboln), "%sCopyTexImage1D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyTexImage1D) { + void ** procp = (void **) &disp->CopyTexImage1D; + snprintf(symboln, sizeof(symboln), "%sCopyTexImage1DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyTexImage2D) { + void ** procp = (void **) &disp->CopyTexImage2D; + snprintf(symboln, sizeof(symboln), "%sCopyTexImage2D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyTexImage2D) { + void ** procp = (void **) &disp->CopyTexImage2D; + snprintf(symboln, sizeof(symboln), "%sCopyTexImage2DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyTexSubImage1D) { + void ** procp = (void **) &disp->CopyTexSubImage1D; + snprintf(symboln, sizeof(symboln), "%sCopyTexSubImage1D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyTexSubImage1D) { + void ** procp = (void **) &disp->CopyTexSubImage1D; + snprintf(symboln, sizeof(symboln), "%sCopyTexSubImage1DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyTexSubImage2D) { + void ** procp = (void **) &disp->CopyTexSubImage2D; + snprintf(symboln, sizeof(symboln), "%sCopyTexSubImage2D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyTexSubImage2D) { + void ** procp = (void **) &disp->CopyTexSubImage2D; + snprintf(symboln, sizeof(symboln), "%sCopyTexSubImage2DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteTextures) { + void ** procp = (void **) &disp->DeleteTextures; + snprintf(symboln, sizeof(symboln), "%sDeleteTextures", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteTextures) { + void ** procp = (void **) &disp->DeleteTextures; + snprintf(symboln, sizeof(symboln), "%sDeleteTexturesEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenTextures) { + void ** procp = (void **) &disp->GenTextures; + snprintf(symboln, sizeof(symboln), "%sGenTextures", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenTextures) { + void ** procp = (void **) &disp->GenTextures; + snprintf(symboln, sizeof(symboln), "%sGenTexturesEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetPointerv) { + void ** procp = (void **) &disp->GetPointerv; + snprintf(symboln, sizeof(symboln), "%sGetPointerv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetPointerv) { + void ** procp = (void **) &disp->GetPointerv; + snprintf(symboln, sizeof(symboln), "%sGetPointervEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsTexture) { + void ** procp = (void **) &disp->IsTexture; + snprintf(symboln, sizeof(symboln), "%sIsTexture", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsTexture) { + void ** procp = (void **) &disp->IsTexture; + snprintf(symboln, sizeof(symboln), "%sIsTextureEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PrioritizeTextures) { + void ** procp = (void **) &disp->PrioritizeTextures; + snprintf(symboln, sizeof(symboln), "%sPrioritizeTextures", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PrioritizeTextures) { + void ** procp = (void **) &disp->PrioritizeTextures; + snprintf(symboln, sizeof(symboln), "%sPrioritizeTexturesEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexSubImage1D) { + void ** procp = (void **) &disp->TexSubImage1D; + snprintf(symboln, sizeof(symboln), "%sTexSubImage1D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexSubImage1D) { + void ** procp = (void **) &disp->TexSubImage1D; + snprintf(symboln, sizeof(symboln), "%sTexSubImage1DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexSubImage2D) { + void ** procp = (void **) &disp->TexSubImage2D; + snprintf(symboln, sizeof(symboln), "%sTexSubImage2D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexSubImage2D) { + void ** procp = (void **) &disp->TexSubImage2D; + snprintf(symboln, sizeof(symboln), "%sTexSubImage2DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PopClientAttrib) { + void ** procp = (void **) &disp->PopClientAttrib; + snprintf(symboln, sizeof(symboln), "%sPopClientAttrib", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PushClientAttrib) { + void ** procp = (void **) &disp->PushClientAttrib; + snprintf(symboln, sizeof(symboln), "%sPushClientAttrib", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendColor) { + void ** procp = (void **) &disp->BlendColor; + snprintf(symboln, sizeof(symboln), "%sBlendColor", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendColor) { + void ** procp = (void **) &disp->BlendColor; + snprintf(symboln, sizeof(symboln), "%sBlendColorEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendEquation) { + void ** procp = (void **) &disp->BlendEquation; + snprintf(symboln, sizeof(symboln), "%sBlendEquation", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendEquation) { + void ** procp = (void **) &disp->BlendEquation; + snprintf(symboln, sizeof(symboln), "%sBlendEquationEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawRangeElements) { + void ** procp = (void **) &disp->DrawRangeElements; + snprintf(symboln, sizeof(symboln), "%sDrawRangeElements", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawRangeElements) { + void ** procp = (void **) &disp->DrawRangeElements; + snprintf(symboln, sizeof(symboln), "%sDrawRangeElementsEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorTable) { + void ** procp = (void **) &disp->ColorTable; + snprintf(symboln, sizeof(symboln), "%sColorTable", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorTable) { + void ** procp = (void **) &disp->ColorTable; + snprintf(symboln, sizeof(symboln), "%sColorTableSGI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorTable) { + void ** procp = (void **) &disp->ColorTable; + snprintf(symboln, sizeof(symboln), "%sColorTableEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorTableParameterfv) { + void ** procp = (void **) &disp->ColorTableParameterfv; + snprintf(symboln, sizeof(symboln), "%sColorTableParameterfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorTableParameterfv) { + void ** procp = (void **) &disp->ColorTableParameterfv; + snprintf(symboln, sizeof(symboln), "%sColorTableParameterfvSGI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorTableParameteriv) { + void ** procp = (void **) &disp->ColorTableParameteriv; + snprintf(symboln, sizeof(symboln), "%sColorTableParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorTableParameteriv) { + void ** procp = (void **) &disp->ColorTableParameteriv; + snprintf(symboln, sizeof(symboln), "%sColorTableParameterivSGI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyColorTable) { + void ** procp = (void **) &disp->CopyColorTable; + snprintf(symboln, sizeof(symboln), "%sCopyColorTable", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyColorTable) { + void ** procp = (void **) &disp->CopyColorTable; + snprintf(symboln, sizeof(symboln), "%sCopyColorTableSGI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetColorTable) { + void ** procp = (void **) &disp->GetColorTable; + snprintf(symboln, sizeof(symboln), "%sGetColorTable", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetColorTable) { + void ** procp = (void **) &disp->GetColorTable; + snprintf(symboln, sizeof(symboln), "%sGetColorTableSGI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetColorTable) { + void ** procp = (void **) &disp->GetColorTable; + snprintf(symboln, sizeof(symboln), "%sGetColorTableEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetColorTableParameterfv) { + void ** procp = (void **) &disp->GetColorTableParameterfv; + snprintf(symboln, sizeof(symboln), "%sGetColorTableParameterfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetColorTableParameterfv) { + void ** procp = (void **) &disp->GetColorTableParameterfv; + snprintf(symboln, sizeof(symboln), "%sGetColorTableParameterfvSGI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetColorTableParameterfv) { + void ** procp = (void **) &disp->GetColorTableParameterfv; + snprintf(symboln, sizeof(symboln), "%sGetColorTableParameterfvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetColorTableParameteriv) { + void ** procp = (void **) &disp->GetColorTableParameteriv; + snprintf(symboln, sizeof(symboln), "%sGetColorTableParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetColorTableParameteriv) { + void ** procp = (void **) &disp->GetColorTableParameteriv; + snprintf(symboln, sizeof(symboln), "%sGetColorTableParameterivSGI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetColorTableParameteriv) { + void ** procp = (void **) &disp->GetColorTableParameteriv; + snprintf(symboln, sizeof(symboln), "%sGetColorTableParameterivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorSubTable) { + void ** procp = (void **) &disp->ColorSubTable; + snprintf(symboln, sizeof(symboln), "%sColorSubTable", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorSubTable) { + void ** procp = (void **) &disp->ColorSubTable; + snprintf(symboln, sizeof(symboln), "%sColorSubTableEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyColorSubTable) { + void ** procp = (void **) &disp->CopyColorSubTable; + snprintf(symboln, sizeof(symboln), "%sCopyColorSubTable", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyColorSubTable) { + void ** procp = (void **) &disp->CopyColorSubTable; + snprintf(symboln, sizeof(symboln), "%sCopyColorSubTableEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ConvolutionFilter1D) { + void ** procp = (void **) &disp->ConvolutionFilter1D; + snprintf(symboln, sizeof(symboln), "%sConvolutionFilter1D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ConvolutionFilter1D) { + void ** procp = (void **) &disp->ConvolutionFilter1D; + snprintf(symboln, sizeof(symboln), "%sConvolutionFilter1DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ConvolutionFilter2D) { + void ** procp = (void **) &disp->ConvolutionFilter2D; + snprintf(symboln, sizeof(symboln), "%sConvolutionFilter2D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ConvolutionFilter2D) { + void ** procp = (void **) &disp->ConvolutionFilter2D; + snprintf(symboln, sizeof(symboln), "%sConvolutionFilter2DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ConvolutionParameterf) { + void ** procp = (void **) &disp->ConvolutionParameterf; + snprintf(symboln, sizeof(symboln), "%sConvolutionParameterf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ConvolutionParameterf) { + void ** procp = (void **) &disp->ConvolutionParameterf; + snprintf(symboln, sizeof(symboln), "%sConvolutionParameterfEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ConvolutionParameterfv) { + void ** procp = (void **) &disp->ConvolutionParameterfv; + snprintf(symboln, sizeof(symboln), "%sConvolutionParameterfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ConvolutionParameterfv) { + void ** procp = (void **) &disp->ConvolutionParameterfv; + snprintf(symboln, sizeof(symboln), "%sConvolutionParameterfvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ConvolutionParameteri) { + void ** procp = (void **) &disp->ConvolutionParameteri; + snprintf(symboln, sizeof(symboln), "%sConvolutionParameteri", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ConvolutionParameteri) { + void ** procp = (void **) &disp->ConvolutionParameteri; + snprintf(symboln, sizeof(symboln), "%sConvolutionParameteriEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ConvolutionParameteriv) { + void ** procp = (void **) &disp->ConvolutionParameteriv; + snprintf(symboln, sizeof(symboln), "%sConvolutionParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ConvolutionParameteriv) { + void ** procp = (void **) &disp->ConvolutionParameteriv; + snprintf(symboln, sizeof(symboln), "%sConvolutionParameterivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyConvolutionFilter1D) { + void ** procp = (void **) &disp->CopyConvolutionFilter1D; + snprintf(symboln, sizeof(symboln), "%sCopyConvolutionFilter1D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyConvolutionFilter1D) { + void ** procp = (void **) &disp->CopyConvolutionFilter1D; + snprintf(symboln, sizeof(symboln), "%sCopyConvolutionFilter1DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyConvolutionFilter2D) { + void ** procp = (void **) &disp->CopyConvolutionFilter2D; + snprintf(symboln, sizeof(symboln), "%sCopyConvolutionFilter2D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyConvolutionFilter2D) { + void ** procp = (void **) &disp->CopyConvolutionFilter2D; + snprintf(symboln, sizeof(symboln), "%sCopyConvolutionFilter2DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetConvolutionFilter) { + void ** procp = (void **) &disp->GetConvolutionFilter; + snprintf(symboln, sizeof(symboln), "%sGetConvolutionFilter", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetConvolutionFilter) { + void ** procp = (void **) &disp->GetConvolutionFilter; + snprintf(symboln, sizeof(symboln), "%sGetConvolutionFilterEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetConvolutionParameterfv) { + void ** procp = (void **) &disp->GetConvolutionParameterfv; + snprintf(symboln, sizeof(symboln), "%sGetConvolutionParameterfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetConvolutionParameterfv) { + void ** procp = (void **) &disp->GetConvolutionParameterfv; + snprintf(symboln, sizeof(symboln), "%sGetConvolutionParameterfvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetConvolutionParameteriv) { + void ** procp = (void **) &disp->GetConvolutionParameteriv; + snprintf(symboln, sizeof(symboln), "%sGetConvolutionParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetConvolutionParameteriv) { + void ** procp = (void **) &disp->GetConvolutionParameteriv; + snprintf(symboln, sizeof(symboln), "%sGetConvolutionParameterivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetSeparableFilter) { + void ** procp = (void **) &disp->GetSeparableFilter; + snprintf(symboln, sizeof(symboln), "%sGetSeparableFilter", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetSeparableFilter) { + void ** procp = (void **) &disp->GetSeparableFilter; + snprintf(symboln, sizeof(symboln), "%sGetSeparableFilterEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SeparableFilter2D) { + void ** procp = (void **) &disp->SeparableFilter2D; + snprintf(symboln, sizeof(symboln), "%sSeparableFilter2D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SeparableFilter2D) { + void ** procp = (void **) &disp->SeparableFilter2D; + snprintf(symboln, sizeof(symboln), "%sSeparableFilter2DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetHistogram) { + void ** procp = (void **) &disp->GetHistogram; + snprintf(symboln, sizeof(symboln), "%sGetHistogram", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetHistogram) { + void ** procp = (void **) &disp->GetHistogram; + snprintf(symboln, sizeof(symboln), "%sGetHistogramEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetHistogramParameterfv) { + void ** procp = (void **) &disp->GetHistogramParameterfv; + snprintf(symboln, sizeof(symboln), "%sGetHistogramParameterfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetHistogramParameterfv) { + void ** procp = (void **) &disp->GetHistogramParameterfv; + snprintf(symboln, sizeof(symboln), "%sGetHistogramParameterfvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetHistogramParameteriv) { + void ** procp = (void **) &disp->GetHistogramParameteriv; + snprintf(symboln, sizeof(symboln), "%sGetHistogramParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetHistogramParameteriv) { + void ** procp = (void **) &disp->GetHistogramParameteriv; + snprintf(symboln, sizeof(symboln), "%sGetHistogramParameterivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetMinmax) { + void ** procp = (void **) &disp->GetMinmax; + snprintf(symboln, sizeof(symboln), "%sGetMinmax", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetMinmax) { + void ** procp = (void **) &disp->GetMinmax; + snprintf(symboln, sizeof(symboln), "%sGetMinmaxEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetMinmaxParameterfv) { + void ** procp = (void **) &disp->GetMinmaxParameterfv; + snprintf(symboln, sizeof(symboln), "%sGetMinmaxParameterfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetMinmaxParameterfv) { + void ** procp = (void **) &disp->GetMinmaxParameterfv; + snprintf(symboln, sizeof(symboln), "%sGetMinmaxParameterfvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetMinmaxParameteriv) { + void ** procp = (void **) &disp->GetMinmaxParameteriv; + snprintf(symboln, sizeof(symboln), "%sGetMinmaxParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetMinmaxParameteriv) { + void ** procp = (void **) &disp->GetMinmaxParameteriv; + snprintf(symboln, sizeof(symboln), "%sGetMinmaxParameterivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Histogram) { + void ** procp = (void **) &disp->Histogram; + snprintf(symboln, sizeof(symboln), "%sHistogram", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Histogram) { + void ** procp = (void **) &disp->Histogram; + snprintf(symboln, sizeof(symboln), "%sHistogramEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Minmax) { + void ** procp = (void **) &disp->Minmax; + snprintf(symboln, sizeof(symboln), "%sMinmax", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Minmax) { + void ** procp = (void **) &disp->Minmax; + snprintf(symboln, sizeof(symboln), "%sMinmaxEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ResetHistogram) { + void ** procp = (void **) &disp->ResetHistogram; + snprintf(symboln, sizeof(symboln), "%sResetHistogram", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ResetHistogram) { + void ** procp = (void **) &disp->ResetHistogram; + snprintf(symboln, sizeof(symboln), "%sResetHistogramEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ResetMinmax) { + void ** procp = (void **) &disp->ResetMinmax; + snprintf(symboln, sizeof(symboln), "%sResetMinmax", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ResetMinmax) { + void ** procp = (void **) &disp->ResetMinmax; + snprintf(symboln, sizeof(symboln), "%sResetMinmaxEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexImage3D) { + void ** procp = (void **) &disp->TexImage3D; + snprintf(symboln, sizeof(symboln), "%sTexImage3D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexImage3D) { + void ** procp = (void **) &disp->TexImage3D; + snprintf(symboln, sizeof(symboln), "%sTexImage3DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexSubImage3D) { + void ** procp = (void **) &disp->TexSubImage3D; + snprintf(symboln, sizeof(symboln), "%sTexSubImage3D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexSubImage3D) { + void ** procp = (void **) &disp->TexSubImage3D; + snprintf(symboln, sizeof(symboln), "%sTexSubImage3DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyTexSubImage3D) { + void ** procp = (void **) &disp->CopyTexSubImage3D; + snprintf(symboln, sizeof(symboln), "%sCopyTexSubImage3D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyTexSubImage3D) { + void ** procp = (void **) &disp->CopyTexSubImage3D; + snprintf(symboln, sizeof(symboln), "%sCopyTexSubImage3DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ActiveTextureARB) { + void ** procp = (void **) &disp->ActiveTextureARB; + snprintf(symboln, sizeof(symboln), "%sActiveTexture", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ActiveTextureARB) { + void ** procp = (void **) &disp->ActiveTextureARB; + snprintf(symboln, sizeof(symboln), "%sActiveTextureARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClientActiveTextureARB) { + void ** procp = (void **) &disp->ClientActiveTextureARB; + snprintf(symboln, sizeof(symboln), "%sClientActiveTexture", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClientActiveTextureARB) { + void ** procp = (void **) &disp->ClientActiveTextureARB; + snprintf(symboln, sizeof(symboln), "%sClientActiveTextureARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1dARB) { + void ** procp = (void **) &disp->MultiTexCoord1dARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1dARB) { + void ** procp = (void **) &disp->MultiTexCoord1dARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1dARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1dvARB) { + void ** procp = (void **) &disp->MultiTexCoord1dvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1dvARB) { + void ** procp = (void **) &disp->MultiTexCoord1dvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1dvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1fARB) { + void ** procp = (void **) &disp->MultiTexCoord1fARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1fARB) { + void ** procp = (void **) &disp->MultiTexCoord1fARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1fvARB) { + void ** procp = (void **) &disp->MultiTexCoord1fvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1fvARB) { + void ** procp = (void **) &disp->MultiTexCoord1fvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1iARB) { + void ** procp = (void **) &disp->MultiTexCoord1iARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1iARB) { + void ** procp = (void **) &disp->MultiTexCoord1iARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1iARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1ivARB) { + void ** procp = (void **) &disp->MultiTexCoord1ivARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1ivARB) { + void ** procp = (void **) &disp->MultiTexCoord1ivARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1ivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1sARB) { + void ** procp = (void **) &disp->MultiTexCoord1sARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1sARB) { + void ** procp = (void **) &disp->MultiTexCoord1sARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1sARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1svARB) { + void ** procp = (void **) &disp->MultiTexCoord1svARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord1svARB) { + void ** procp = (void **) &disp->MultiTexCoord1svARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord1svARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2dARB) { + void ** procp = (void **) &disp->MultiTexCoord2dARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2dARB) { + void ** procp = (void **) &disp->MultiTexCoord2dARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2dARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2dvARB) { + void ** procp = (void **) &disp->MultiTexCoord2dvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2dvARB) { + void ** procp = (void **) &disp->MultiTexCoord2dvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2dvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2fARB) { + void ** procp = (void **) &disp->MultiTexCoord2fARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2fARB) { + void ** procp = (void **) &disp->MultiTexCoord2fARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2fvARB) { + void ** procp = (void **) &disp->MultiTexCoord2fvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2fvARB) { + void ** procp = (void **) &disp->MultiTexCoord2fvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2iARB) { + void ** procp = (void **) &disp->MultiTexCoord2iARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2iARB) { + void ** procp = (void **) &disp->MultiTexCoord2iARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2iARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2ivARB) { + void ** procp = (void **) &disp->MultiTexCoord2ivARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2ivARB) { + void ** procp = (void **) &disp->MultiTexCoord2ivARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2ivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2sARB) { + void ** procp = (void **) &disp->MultiTexCoord2sARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2sARB) { + void ** procp = (void **) &disp->MultiTexCoord2sARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2sARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2svARB) { + void ** procp = (void **) &disp->MultiTexCoord2svARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord2svARB) { + void ** procp = (void **) &disp->MultiTexCoord2svARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord2svARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3dARB) { + void ** procp = (void **) &disp->MultiTexCoord3dARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3dARB) { + void ** procp = (void **) &disp->MultiTexCoord3dARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3dARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3dvARB) { + void ** procp = (void **) &disp->MultiTexCoord3dvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3dvARB) { + void ** procp = (void **) &disp->MultiTexCoord3dvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3dvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3fARB) { + void ** procp = (void **) &disp->MultiTexCoord3fARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3fARB) { + void ** procp = (void **) &disp->MultiTexCoord3fARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3fvARB) { + void ** procp = (void **) &disp->MultiTexCoord3fvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3fvARB) { + void ** procp = (void **) &disp->MultiTexCoord3fvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3iARB) { + void ** procp = (void **) &disp->MultiTexCoord3iARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3iARB) { + void ** procp = (void **) &disp->MultiTexCoord3iARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3iARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3ivARB) { + void ** procp = (void **) &disp->MultiTexCoord3ivARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3ivARB) { + void ** procp = (void **) &disp->MultiTexCoord3ivARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3ivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3sARB) { + void ** procp = (void **) &disp->MultiTexCoord3sARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3sARB) { + void ** procp = (void **) &disp->MultiTexCoord3sARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3sARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3svARB) { + void ** procp = (void **) &disp->MultiTexCoord3svARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord3svARB) { + void ** procp = (void **) &disp->MultiTexCoord3svARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord3svARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4dARB) { + void ** procp = (void **) &disp->MultiTexCoord4dARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4dARB) { + void ** procp = (void **) &disp->MultiTexCoord4dARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4dARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4dvARB) { + void ** procp = (void **) &disp->MultiTexCoord4dvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4dvARB) { + void ** procp = (void **) &disp->MultiTexCoord4dvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4dvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4fARB) { + void ** procp = (void **) &disp->MultiTexCoord4fARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4fARB) { + void ** procp = (void **) &disp->MultiTexCoord4fARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4fvARB) { + void ** procp = (void **) &disp->MultiTexCoord4fvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4fvARB) { + void ** procp = (void **) &disp->MultiTexCoord4fvARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4iARB) { + void ** procp = (void **) &disp->MultiTexCoord4iARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4iARB) { + void ** procp = (void **) &disp->MultiTexCoord4iARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4iARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4ivARB) { + void ** procp = (void **) &disp->MultiTexCoord4ivARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4ivARB) { + void ** procp = (void **) &disp->MultiTexCoord4ivARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4ivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4sARB) { + void ** procp = (void **) &disp->MultiTexCoord4sARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4sARB) { + void ** procp = (void **) &disp->MultiTexCoord4sARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4sARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4svARB) { + void ** procp = (void **) &disp->MultiTexCoord4svARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiTexCoord4svARB) { + void ** procp = (void **) &disp->MultiTexCoord4svARB; + snprintf(symboln, sizeof(symboln), "%sMultiTexCoord4svARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->AttachShader) { + void ** procp = (void **) &disp->AttachShader; + snprintf(symboln, sizeof(symboln), "%sAttachShader", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CreateProgram) { + void ** procp = (void **) &disp->CreateProgram; + snprintf(symboln, sizeof(symboln), "%sCreateProgram", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CreateShader) { + void ** procp = (void **) &disp->CreateShader; + snprintf(symboln, sizeof(symboln), "%sCreateShader", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteProgram) { + void ** procp = (void **) &disp->DeleteProgram; + snprintf(symboln, sizeof(symboln), "%sDeleteProgram", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteShader) { + void ** procp = (void **) &disp->DeleteShader; + snprintf(symboln, sizeof(symboln), "%sDeleteShader", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DetachShader) { + void ** procp = (void **) &disp->DetachShader; + snprintf(symboln, sizeof(symboln), "%sDetachShader", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetAttachedShaders) { + void ** procp = (void **) &disp->GetAttachedShaders; + snprintf(symboln, sizeof(symboln), "%sGetAttachedShaders", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramInfoLog) { + void ** procp = (void **) &disp->GetProgramInfoLog; + snprintf(symboln, sizeof(symboln), "%sGetProgramInfoLog", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramiv) { + void ** procp = (void **) &disp->GetProgramiv; + snprintf(symboln, sizeof(symboln), "%sGetProgramiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetShaderInfoLog) { + void ** procp = (void **) &disp->GetShaderInfoLog; + snprintf(symboln, sizeof(symboln), "%sGetShaderInfoLog", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetShaderiv) { + void ** procp = (void **) &disp->GetShaderiv; + snprintf(symboln, sizeof(symboln), "%sGetShaderiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsProgram) { + void ** procp = (void **) &disp->IsProgram; + snprintf(symboln, sizeof(symboln), "%sIsProgram", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsShader) { + void ** procp = (void **) &disp->IsShader; + snprintf(symboln, sizeof(symboln), "%sIsShader", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->StencilFuncSeparate) { + void ** procp = (void **) &disp->StencilFuncSeparate; + snprintf(symboln, sizeof(symboln), "%sStencilFuncSeparate", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->StencilMaskSeparate) { + void ** procp = (void **) &disp->StencilMaskSeparate; + snprintf(symboln, sizeof(symboln), "%sStencilMaskSeparate", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->StencilOpSeparate) { + void ** procp = (void **) &disp->StencilOpSeparate; + snprintf(symboln, sizeof(symboln), "%sStencilOpSeparate", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->StencilOpSeparate) { + void ** procp = (void **) &disp->StencilOpSeparate; + snprintf(symboln, sizeof(symboln), "%sStencilOpSeparateATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UniformMatrix2x3fv) { + void ** procp = (void **) &disp->UniformMatrix2x3fv; + snprintf(symboln, sizeof(symboln), "%sUniformMatrix2x3fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UniformMatrix2x4fv) { + void ** procp = (void **) &disp->UniformMatrix2x4fv; + snprintf(symboln, sizeof(symboln), "%sUniformMatrix2x4fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UniformMatrix3x2fv) { + void ** procp = (void **) &disp->UniformMatrix3x2fv; + snprintf(symboln, sizeof(symboln), "%sUniformMatrix3x2fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UniformMatrix3x4fv) { + void ** procp = (void **) &disp->UniformMatrix3x4fv; + snprintf(symboln, sizeof(symboln), "%sUniformMatrix3x4fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UniformMatrix4x2fv) { + void ** procp = (void **) &disp->UniformMatrix4x2fv; + snprintf(symboln, sizeof(symboln), "%sUniformMatrix4x2fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UniformMatrix4x3fv) { + void ** procp = (void **) &disp->UniformMatrix4x3fv; + snprintf(symboln, sizeof(symboln), "%sUniformMatrix4x3fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClampColor) { + void ** procp = (void **) &disp->ClampColor; + snprintf(symboln, sizeof(symboln), "%sClampColor", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClearBufferfi) { + void ** procp = (void **) &disp->ClearBufferfi; + snprintf(symboln, sizeof(symboln), "%sClearBufferfi", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClearBufferfv) { + void ** procp = (void **) &disp->ClearBufferfv; + snprintf(symboln, sizeof(symboln), "%sClearBufferfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClearBufferiv) { + void ** procp = (void **) &disp->ClearBufferiv; + snprintf(symboln, sizeof(symboln), "%sClearBufferiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClearBufferuiv) { + void ** procp = (void **) &disp->ClearBufferuiv; + snprintf(symboln, sizeof(symboln), "%sClearBufferuiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetStringi) { + void ** procp = (void **) &disp->GetStringi; + snprintf(symboln, sizeof(symboln), "%sGetStringi", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexBuffer) { + void ** procp = (void **) &disp->TexBuffer; + snprintf(symboln, sizeof(symboln), "%sTexBuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FramebufferTexture) { + void ** procp = (void **) &disp->FramebufferTexture; + snprintf(symboln, sizeof(symboln), "%sFramebufferTexture", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetBufferParameteri64v) { + void ** procp = (void **) &disp->GetBufferParameteri64v; + snprintf(symboln, sizeof(symboln), "%sGetBufferParameteri64v", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetInteger64i_v) { + void ** procp = (void **) &disp->GetInteger64i_v; + snprintf(symboln, sizeof(symboln), "%sGetInteger64i_v", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribDivisor) { + void ** procp = (void **) &disp->VertexAttribDivisor; + snprintf(symboln, sizeof(symboln), "%sVertexAttribDivisor", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LoadTransposeMatrixdARB) { + void ** procp = (void **) &disp->LoadTransposeMatrixdARB; + snprintf(symboln, sizeof(symboln), "%sLoadTransposeMatrixd", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LoadTransposeMatrixdARB) { + void ** procp = (void **) &disp->LoadTransposeMatrixdARB; + snprintf(symboln, sizeof(symboln), "%sLoadTransposeMatrixdARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LoadTransposeMatrixfARB) { + void ** procp = (void **) &disp->LoadTransposeMatrixfARB; + snprintf(symboln, sizeof(symboln), "%sLoadTransposeMatrixf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LoadTransposeMatrixfARB) { + void ** procp = (void **) &disp->LoadTransposeMatrixfARB; + snprintf(symboln, sizeof(symboln), "%sLoadTransposeMatrixfARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultTransposeMatrixdARB) { + void ** procp = (void **) &disp->MultTransposeMatrixdARB; + snprintf(symboln, sizeof(symboln), "%sMultTransposeMatrixd", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultTransposeMatrixdARB) { + void ** procp = (void **) &disp->MultTransposeMatrixdARB; + snprintf(symboln, sizeof(symboln), "%sMultTransposeMatrixdARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultTransposeMatrixfARB) { + void ** procp = (void **) &disp->MultTransposeMatrixfARB; + snprintf(symboln, sizeof(symboln), "%sMultTransposeMatrixf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultTransposeMatrixfARB) { + void ** procp = (void **) &disp->MultTransposeMatrixfARB; + snprintf(symboln, sizeof(symboln), "%sMultTransposeMatrixfARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SampleCoverageARB) { + void ** procp = (void **) &disp->SampleCoverageARB; + snprintf(symboln, sizeof(symboln), "%sSampleCoverage", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SampleCoverageARB) { + void ** procp = (void **) &disp->SampleCoverageARB; + snprintf(symboln, sizeof(symboln), "%sSampleCoverageARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompressedTexImage1DARB) { + void ** procp = (void **) &disp->CompressedTexImage1DARB; + snprintf(symboln, sizeof(symboln), "%sCompressedTexImage1D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompressedTexImage1DARB) { + void ** procp = (void **) &disp->CompressedTexImage1DARB; + snprintf(symboln, sizeof(symboln), "%sCompressedTexImage1DARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompressedTexImage2DARB) { + void ** procp = (void **) &disp->CompressedTexImage2DARB; + snprintf(symboln, sizeof(symboln), "%sCompressedTexImage2D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompressedTexImage2DARB) { + void ** procp = (void **) &disp->CompressedTexImage2DARB; + snprintf(symboln, sizeof(symboln), "%sCompressedTexImage2DARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompressedTexImage3DARB) { + void ** procp = (void **) &disp->CompressedTexImage3DARB; + snprintf(symboln, sizeof(symboln), "%sCompressedTexImage3D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompressedTexImage3DARB) { + void ** procp = (void **) &disp->CompressedTexImage3DARB; + snprintf(symboln, sizeof(symboln), "%sCompressedTexImage3DARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompressedTexSubImage1DARB) { + void ** procp = (void **) &disp->CompressedTexSubImage1DARB; + snprintf(symboln, sizeof(symboln), "%sCompressedTexSubImage1D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompressedTexSubImage1DARB) { + void ** procp = (void **) &disp->CompressedTexSubImage1DARB; + snprintf(symboln, sizeof(symboln), "%sCompressedTexSubImage1DARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompressedTexSubImage2DARB) { + void ** procp = (void **) &disp->CompressedTexSubImage2DARB; + snprintf(symboln, sizeof(symboln), "%sCompressedTexSubImage2D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompressedTexSubImage2DARB) { + void ** procp = (void **) &disp->CompressedTexSubImage2DARB; + snprintf(symboln, sizeof(symboln), "%sCompressedTexSubImage2DARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompressedTexSubImage3DARB) { + void ** procp = (void **) &disp->CompressedTexSubImage3DARB; + snprintf(symboln, sizeof(symboln), "%sCompressedTexSubImage3D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompressedTexSubImage3DARB) { + void ** procp = (void **) &disp->CompressedTexSubImage3DARB; + snprintf(symboln, sizeof(symboln), "%sCompressedTexSubImage3DARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetCompressedTexImageARB) { + void ** procp = (void **) &disp->GetCompressedTexImageARB; + snprintf(symboln, sizeof(symboln), "%sGetCompressedTexImage", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetCompressedTexImageARB) { + void ** procp = (void **) &disp->GetCompressedTexImageARB; + snprintf(symboln, sizeof(symboln), "%sGetCompressedTexImageARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DisableVertexAttribArrayARB) { + void ** procp = (void **) &disp->DisableVertexAttribArrayARB; + snprintf(symboln, sizeof(symboln), "%sDisableVertexAttribArray", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DisableVertexAttribArrayARB) { + void ** procp = (void **) &disp->DisableVertexAttribArrayARB; + snprintf(symboln, sizeof(symboln), "%sDisableVertexAttribArrayARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EnableVertexAttribArrayARB) { + void ** procp = (void **) &disp->EnableVertexAttribArrayARB; + snprintf(symboln, sizeof(symboln), "%sEnableVertexAttribArray", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EnableVertexAttribArrayARB) { + void ** procp = (void **) &disp->EnableVertexAttribArrayARB; + snprintf(symboln, sizeof(symboln), "%sEnableVertexAttribArrayARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramEnvParameterdvARB) { + void ** procp = (void **) &disp->GetProgramEnvParameterdvARB; + snprintf(symboln, sizeof(symboln), "%sGetProgramEnvParameterdvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramEnvParameterfvARB) { + void ** procp = (void **) &disp->GetProgramEnvParameterfvARB; + snprintf(symboln, sizeof(symboln), "%sGetProgramEnvParameterfvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramLocalParameterdvARB) { + void ** procp = (void **) &disp->GetProgramLocalParameterdvARB; + snprintf(symboln, sizeof(symboln), "%sGetProgramLocalParameterdvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramLocalParameterfvARB) { + void ** procp = (void **) &disp->GetProgramLocalParameterfvARB; + snprintf(symboln, sizeof(symboln), "%sGetProgramLocalParameterfvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramStringARB) { + void ** procp = (void **) &disp->GetProgramStringARB; + snprintf(symboln, sizeof(symboln), "%sGetProgramStringARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramivARB) { + void ** procp = (void **) &disp->GetProgramivARB; + snprintf(symboln, sizeof(symboln), "%sGetProgramivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribdvARB) { + void ** procp = (void **) &disp->GetVertexAttribdvARB; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribdv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribdvARB) { + void ** procp = (void **) &disp->GetVertexAttribdvARB; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribdvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribfvARB) { + void ** procp = (void **) &disp->GetVertexAttribfvARB; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribfvARB) { + void ** procp = (void **) &disp->GetVertexAttribfvARB; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribfvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribivARB) { + void ** procp = (void **) &disp->GetVertexAttribivARB; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribivARB) { + void ** procp = (void **) &disp->GetVertexAttribivARB; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramEnvParameter4dARB) { + void ** procp = (void **) &disp->ProgramEnvParameter4dARB; + snprintf(symboln, sizeof(symboln), "%sProgramEnvParameter4dARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramEnvParameter4dARB) { + void ** procp = (void **) &disp->ProgramEnvParameter4dARB; + snprintf(symboln, sizeof(symboln), "%sProgramParameter4dNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramEnvParameter4dvARB) { + void ** procp = (void **) &disp->ProgramEnvParameter4dvARB; + snprintf(symboln, sizeof(symboln), "%sProgramEnvParameter4dvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramEnvParameter4dvARB) { + void ** procp = (void **) &disp->ProgramEnvParameter4dvARB; + snprintf(symboln, sizeof(symboln), "%sProgramParameter4dvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramEnvParameter4fARB) { + void ** procp = (void **) &disp->ProgramEnvParameter4fARB; + snprintf(symboln, sizeof(symboln), "%sProgramEnvParameter4fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramEnvParameter4fARB) { + void ** procp = (void **) &disp->ProgramEnvParameter4fARB; + snprintf(symboln, sizeof(symboln), "%sProgramParameter4fNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramEnvParameter4fvARB) { + void ** procp = (void **) &disp->ProgramEnvParameter4fvARB; + snprintf(symboln, sizeof(symboln), "%sProgramEnvParameter4fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramEnvParameter4fvARB) { + void ** procp = (void **) &disp->ProgramEnvParameter4fvARB; + snprintf(symboln, sizeof(symboln), "%sProgramParameter4fvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramLocalParameter4dARB) { + void ** procp = (void **) &disp->ProgramLocalParameter4dARB; + snprintf(symboln, sizeof(symboln), "%sProgramLocalParameter4dARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramLocalParameter4dvARB) { + void ** procp = (void **) &disp->ProgramLocalParameter4dvARB; + snprintf(symboln, sizeof(symboln), "%sProgramLocalParameter4dvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramLocalParameter4fARB) { + void ** procp = (void **) &disp->ProgramLocalParameter4fARB; + snprintf(symboln, sizeof(symboln), "%sProgramLocalParameter4fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramLocalParameter4fvARB) { + void ** procp = (void **) &disp->ProgramLocalParameter4fvARB; + snprintf(symboln, sizeof(symboln), "%sProgramLocalParameter4fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramStringARB) { + void ** procp = (void **) &disp->ProgramStringARB; + snprintf(symboln, sizeof(symboln), "%sProgramStringARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1dARB) { + void ** procp = (void **) &disp->VertexAttrib1dARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1dARB) { + void ** procp = (void **) &disp->VertexAttrib1dARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1dARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1dvARB) { + void ** procp = (void **) &disp->VertexAttrib1dvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1dvARB) { + void ** procp = (void **) &disp->VertexAttrib1dvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1dvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1fARB) { + void ** procp = (void **) &disp->VertexAttrib1fARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1fARB) { + void ** procp = (void **) &disp->VertexAttrib1fARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1fvARB) { + void ** procp = (void **) &disp->VertexAttrib1fvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1fvARB) { + void ** procp = (void **) &disp->VertexAttrib1fvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1sARB) { + void ** procp = (void **) &disp->VertexAttrib1sARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1sARB) { + void ** procp = (void **) &disp->VertexAttrib1sARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1sARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1svARB) { + void ** procp = (void **) &disp->VertexAttrib1svARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1svARB) { + void ** procp = (void **) &disp->VertexAttrib1svARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1svARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2dARB) { + void ** procp = (void **) &disp->VertexAttrib2dARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2dARB) { + void ** procp = (void **) &disp->VertexAttrib2dARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2dARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2dvARB) { + void ** procp = (void **) &disp->VertexAttrib2dvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2dvARB) { + void ** procp = (void **) &disp->VertexAttrib2dvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2dvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2fARB) { + void ** procp = (void **) &disp->VertexAttrib2fARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2fARB) { + void ** procp = (void **) &disp->VertexAttrib2fARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2fvARB) { + void ** procp = (void **) &disp->VertexAttrib2fvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2fvARB) { + void ** procp = (void **) &disp->VertexAttrib2fvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2sARB) { + void ** procp = (void **) &disp->VertexAttrib2sARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2sARB) { + void ** procp = (void **) &disp->VertexAttrib2sARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2sARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2svARB) { + void ** procp = (void **) &disp->VertexAttrib2svARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2svARB) { + void ** procp = (void **) &disp->VertexAttrib2svARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2svARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3dARB) { + void ** procp = (void **) &disp->VertexAttrib3dARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3dARB) { + void ** procp = (void **) &disp->VertexAttrib3dARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3dARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3dvARB) { + void ** procp = (void **) &disp->VertexAttrib3dvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3dvARB) { + void ** procp = (void **) &disp->VertexAttrib3dvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3dvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3fARB) { + void ** procp = (void **) &disp->VertexAttrib3fARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3fARB) { + void ** procp = (void **) &disp->VertexAttrib3fARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3fvARB) { + void ** procp = (void **) &disp->VertexAttrib3fvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3fvARB) { + void ** procp = (void **) &disp->VertexAttrib3fvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3sARB) { + void ** procp = (void **) &disp->VertexAttrib3sARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3sARB) { + void ** procp = (void **) &disp->VertexAttrib3sARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3sARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3svARB) { + void ** procp = (void **) &disp->VertexAttrib3svARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3svARB) { + void ** procp = (void **) &disp->VertexAttrib3svARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3svARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NbvARB) { + void ** procp = (void **) &disp->VertexAttrib4NbvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4Nbv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NbvARB) { + void ** procp = (void **) &disp->VertexAttrib4NbvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4NbvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NivARB) { + void ** procp = (void **) &disp->VertexAttrib4NivARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4Niv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NivARB) { + void ** procp = (void **) &disp->VertexAttrib4NivARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4NivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NsvARB) { + void ** procp = (void **) &disp->VertexAttrib4NsvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4Nsv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NsvARB) { + void ** procp = (void **) &disp->VertexAttrib4NsvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4NsvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NubARB) { + void ** procp = (void **) &disp->VertexAttrib4NubARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4Nub", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NubARB) { + void ** procp = (void **) &disp->VertexAttrib4NubARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4NubARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NubvARB) { + void ** procp = (void **) &disp->VertexAttrib4NubvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4Nubv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NubvARB) { + void ** procp = (void **) &disp->VertexAttrib4NubvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4NubvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NuivARB) { + void ** procp = (void **) &disp->VertexAttrib4NuivARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4Nuiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NuivARB) { + void ** procp = (void **) &disp->VertexAttrib4NuivARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4NuivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NusvARB) { + void ** procp = (void **) &disp->VertexAttrib4NusvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4Nusv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4NusvARB) { + void ** procp = (void **) &disp->VertexAttrib4NusvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4NusvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4bvARB) { + void ** procp = (void **) &disp->VertexAttrib4bvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4bv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4bvARB) { + void ** procp = (void **) &disp->VertexAttrib4bvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4bvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4dARB) { + void ** procp = (void **) &disp->VertexAttrib4dARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4dARB) { + void ** procp = (void **) &disp->VertexAttrib4dARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4dARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4dvARB) { + void ** procp = (void **) &disp->VertexAttrib4dvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4dvARB) { + void ** procp = (void **) &disp->VertexAttrib4dvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4dvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4fARB) { + void ** procp = (void **) &disp->VertexAttrib4fARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4fARB) { + void ** procp = (void **) &disp->VertexAttrib4fARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4fvARB) { + void ** procp = (void **) &disp->VertexAttrib4fvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4fvARB) { + void ** procp = (void **) &disp->VertexAttrib4fvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4ivARB) { + void ** procp = (void **) &disp->VertexAttrib4ivARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4ivARB) { + void ** procp = (void **) &disp->VertexAttrib4ivARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4ivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4sARB) { + void ** procp = (void **) &disp->VertexAttrib4sARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4sARB) { + void ** procp = (void **) &disp->VertexAttrib4sARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4sARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4svARB) { + void ** procp = (void **) &disp->VertexAttrib4svARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4svARB) { + void ** procp = (void **) &disp->VertexAttrib4svARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4svARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4ubvARB) { + void ** procp = (void **) &disp->VertexAttrib4ubvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4ubv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4ubvARB) { + void ** procp = (void **) &disp->VertexAttrib4ubvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4ubvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4uivARB) { + void ** procp = (void **) &disp->VertexAttrib4uivARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4uiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4uivARB) { + void ** procp = (void **) &disp->VertexAttrib4uivARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4uivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4usvARB) { + void ** procp = (void **) &disp->VertexAttrib4usvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4usv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4usvARB) { + void ** procp = (void **) &disp->VertexAttrib4usvARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4usvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribPointerARB) { + void ** procp = (void **) &disp->VertexAttribPointerARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttribPointer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribPointerARB) { + void ** procp = (void **) &disp->VertexAttribPointerARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttribPointerARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindBufferARB) { + void ** procp = (void **) &disp->BindBufferARB; + snprintf(symboln, sizeof(symboln), "%sBindBuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindBufferARB) { + void ** procp = (void **) &disp->BindBufferARB; + snprintf(symboln, sizeof(symboln), "%sBindBufferARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BufferDataARB) { + void ** procp = (void **) &disp->BufferDataARB; + snprintf(symboln, sizeof(symboln), "%sBufferData", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BufferDataARB) { + void ** procp = (void **) &disp->BufferDataARB; + snprintf(symboln, sizeof(symboln), "%sBufferDataARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BufferSubDataARB) { + void ** procp = (void **) &disp->BufferSubDataARB; + snprintf(symboln, sizeof(symboln), "%sBufferSubData", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BufferSubDataARB) { + void ** procp = (void **) &disp->BufferSubDataARB; + snprintf(symboln, sizeof(symboln), "%sBufferSubDataARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteBuffersARB) { + void ** procp = (void **) &disp->DeleteBuffersARB; + snprintf(symboln, sizeof(symboln), "%sDeleteBuffers", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteBuffersARB) { + void ** procp = (void **) &disp->DeleteBuffersARB; + snprintf(symboln, sizeof(symboln), "%sDeleteBuffersARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenBuffersARB) { + void ** procp = (void **) &disp->GenBuffersARB; + snprintf(symboln, sizeof(symboln), "%sGenBuffers", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenBuffersARB) { + void ** procp = (void **) &disp->GenBuffersARB; + snprintf(symboln, sizeof(symboln), "%sGenBuffersARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetBufferParameterivARB) { + void ** procp = (void **) &disp->GetBufferParameterivARB; + snprintf(symboln, sizeof(symboln), "%sGetBufferParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetBufferParameterivARB) { + void ** procp = (void **) &disp->GetBufferParameterivARB; + snprintf(symboln, sizeof(symboln), "%sGetBufferParameterivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetBufferPointervARB) { + void ** procp = (void **) &disp->GetBufferPointervARB; + snprintf(symboln, sizeof(symboln), "%sGetBufferPointerv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetBufferPointervARB) { + void ** procp = (void **) &disp->GetBufferPointervARB; + snprintf(symboln, sizeof(symboln), "%sGetBufferPointervARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetBufferSubDataARB) { + void ** procp = (void **) &disp->GetBufferSubDataARB; + snprintf(symboln, sizeof(symboln), "%sGetBufferSubData", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetBufferSubDataARB) { + void ** procp = (void **) &disp->GetBufferSubDataARB; + snprintf(symboln, sizeof(symboln), "%sGetBufferSubDataARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsBufferARB) { + void ** procp = (void **) &disp->IsBufferARB; + snprintf(symboln, sizeof(symboln), "%sIsBuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsBufferARB) { + void ** procp = (void **) &disp->IsBufferARB; + snprintf(symboln, sizeof(symboln), "%sIsBufferARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MapBufferARB) { + void ** procp = (void **) &disp->MapBufferARB; + snprintf(symboln, sizeof(symboln), "%sMapBuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MapBufferARB) { + void ** procp = (void **) &disp->MapBufferARB; + snprintf(symboln, sizeof(symboln), "%sMapBufferARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UnmapBufferARB) { + void ** procp = (void **) &disp->UnmapBufferARB; + snprintf(symboln, sizeof(symboln), "%sUnmapBuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UnmapBufferARB) { + void ** procp = (void **) &disp->UnmapBufferARB; + snprintf(symboln, sizeof(symboln), "%sUnmapBufferARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BeginQueryARB) { + void ** procp = (void **) &disp->BeginQueryARB; + snprintf(symboln, sizeof(symboln), "%sBeginQuery", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BeginQueryARB) { + void ** procp = (void **) &disp->BeginQueryARB; + snprintf(symboln, sizeof(symboln), "%sBeginQueryARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteQueriesARB) { + void ** procp = (void **) &disp->DeleteQueriesARB; + snprintf(symboln, sizeof(symboln), "%sDeleteQueries", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteQueriesARB) { + void ** procp = (void **) &disp->DeleteQueriesARB; + snprintf(symboln, sizeof(symboln), "%sDeleteQueriesARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EndQueryARB) { + void ** procp = (void **) &disp->EndQueryARB; + snprintf(symboln, sizeof(symboln), "%sEndQuery", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EndQueryARB) { + void ** procp = (void **) &disp->EndQueryARB; + snprintf(symboln, sizeof(symboln), "%sEndQueryARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenQueriesARB) { + void ** procp = (void **) &disp->GenQueriesARB; + snprintf(symboln, sizeof(symboln), "%sGenQueries", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenQueriesARB) { + void ** procp = (void **) &disp->GenQueriesARB; + snprintf(symboln, sizeof(symboln), "%sGenQueriesARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetQueryObjectivARB) { + void ** procp = (void **) &disp->GetQueryObjectivARB; + snprintf(symboln, sizeof(symboln), "%sGetQueryObjectiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetQueryObjectivARB) { + void ** procp = (void **) &disp->GetQueryObjectivARB; + snprintf(symboln, sizeof(symboln), "%sGetQueryObjectivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetQueryObjectuivARB) { + void ** procp = (void **) &disp->GetQueryObjectuivARB; + snprintf(symboln, sizeof(symboln), "%sGetQueryObjectuiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetQueryObjectuivARB) { + void ** procp = (void **) &disp->GetQueryObjectuivARB; + snprintf(symboln, sizeof(symboln), "%sGetQueryObjectuivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetQueryivARB) { + void ** procp = (void **) &disp->GetQueryivARB; + snprintf(symboln, sizeof(symboln), "%sGetQueryiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetQueryivARB) { + void ** procp = (void **) &disp->GetQueryivARB; + snprintf(symboln, sizeof(symboln), "%sGetQueryivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsQueryARB) { + void ** procp = (void **) &disp->IsQueryARB; + snprintf(symboln, sizeof(symboln), "%sIsQuery", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsQueryARB) { + void ** procp = (void **) &disp->IsQueryARB; + snprintf(symboln, sizeof(symboln), "%sIsQueryARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->AttachObjectARB) { + void ** procp = (void **) &disp->AttachObjectARB; + snprintf(symboln, sizeof(symboln), "%sAttachObjectARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompileShaderARB) { + void ** procp = (void **) &disp->CompileShaderARB; + snprintf(symboln, sizeof(symboln), "%sCompileShader", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CompileShaderARB) { + void ** procp = (void **) &disp->CompileShaderARB; + snprintf(symboln, sizeof(symboln), "%sCompileShaderARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CreateProgramObjectARB) { + void ** procp = (void **) &disp->CreateProgramObjectARB; + snprintf(symboln, sizeof(symboln), "%sCreateProgramObjectARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CreateShaderObjectARB) { + void ** procp = (void **) &disp->CreateShaderObjectARB; + snprintf(symboln, sizeof(symboln), "%sCreateShaderObjectARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteObjectARB) { + void ** procp = (void **) &disp->DeleteObjectARB; + snprintf(symboln, sizeof(symboln), "%sDeleteObjectARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DetachObjectARB) { + void ** procp = (void **) &disp->DetachObjectARB; + snprintf(symboln, sizeof(symboln), "%sDetachObjectARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetActiveUniformARB) { + void ** procp = (void **) &disp->GetActiveUniformARB; + snprintf(symboln, sizeof(symboln), "%sGetActiveUniform", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetActiveUniformARB) { + void ** procp = (void **) &disp->GetActiveUniformARB; + snprintf(symboln, sizeof(symboln), "%sGetActiveUniformARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetAttachedObjectsARB) { + void ** procp = (void **) &disp->GetAttachedObjectsARB; + snprintf(symboln, sizeof(symboln), "%sGetAttachedObjectsARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetHandleARB) { + void ** procp = (void **) &disp->GetHandleARB; + snprintf(symboln, sizeof(symboln), "%sGetHandleARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetInfoLogARB) { + void ** procp = (void **) &disp->GetInfoLogARB; + snprintf(symboln, sizeof(symboln), "%sGetInfoLogARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetObjectParameterfvARB) { + void ** procp = (void **) &disp->GetObjectParameterfvARB; + snprintf(symboln, sizeof(symboln), "%sGetObjectParameterfvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetObjectParameterivARB) { + void ** procp = (void **) &disp->GetObjectParameterivARB; + snprintf(symboln, sizeof(symboln), "%sGetObjectParameterivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetShaderSourceARB) { + void ** procp = (void **) &disp->GetShaderSourceARB; + snprintf(symboln, sizeof(symboln), "%sGetShaderSource", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetShaderSourceARB) { + void ** procp = (void **) &disp->GetShaderSourceARB; + snprintf(symboln, sizeof(symboln), "%sGetShaderSourceARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetUniformLocationARB) { + void ** procp = (void **) &disp->GetUniformLocationARB; + snprintf(symboln, sizeof(symboln), "%sGetUniformLocation", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetUniformLocationARB) { + void ** procp = (void **) &disp->GetUniformLocationARB; + snprintf(symboln, sizeof(symboln), "%sGetUniformLocationARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetUniformfvARB) { + void ** procp = (void **) &disp->GetUniformfvARB; + snprintf(symboln, sizeof(symboln), "%sGetUniformfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetUniformfvARB) { + void ** procp = (void **) &disp->GetUniformfvARB; + snprintf(symboln, sizeof(symboln), "%sGetUniformfvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetUniformivARB) { + void ** procp = (void **) &disp->GetUniformivARB; + snprintf(symboln, sizeof(symboln), "%sGetUniformiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetUniformivARB) { + void ** procp = (void **) &disp->GetUniformivARB; + snprintf(symboln, sizeof(symboln), "%sGetUniformivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LinkProgramARB) { + void ** procp = (void **) &disp->LinkProgramARB; + snprintf(symboln, sizeof(symboln), "%sLinkProgram", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LinkProgramARB) { + void ** procp = (void **) &disp->LinkProgramARB; + snprintf(symboln, sizeof(symboln), "%sLinkProgramARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ShaderSourceARB) { + void ** procp = (void **) &disp->ShaderSourceARB; + snprintf(symboln, sizeof(symboln), "%sShaderSource", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ShaderSourceARB) { + void ** procp = (void **) &disp->ShaderSourceARB; + snprintf(symboln, sizeof(symboln), "%sShaderSourceARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform1fARB) { + void ** procp = (void **) &disp->Uniform1fARB; + snprintf(symboln, sizeof(symboln), "%sUniform1f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform1fARB) { + void ** procp = (void **) &disp->Uniform1fARB; + snprintf(symboln, sizeof(symboln), "%sUniform1fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform1fvARB) { + void ** procp = (void **) &disp->Uniform1fvARB; + snprintf(symboln, sizeof(symboln), "%sUniform1fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform1fvARB) { + void ** procp = (void **) &disp->Uniform1fvARB; + snprintf(symboln, sizeof(symboln), "%sUniform1fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform1iARB) { + void ** procp = (void **) &disp->Uniform1iARB; + snprintf(symboln, sizeof(symboln), "%sUniform1i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform1iARB) { + void ** procp = (void **) &disp->Uniform1iARB; + snprintf(symboln, sizeof(symboln), "%sUniform1iARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform1ivARB) { + void ** procp = (void **) &disp->Uniform1ivARB; + snprintf(symboln, sizeof(symboln), "%sUniform1iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform1ivARB) { + void ** procp = (void **) &disp->Uniform1ivARB; + snprintf(symboln, sizeof(symboln), "%sUniform1ivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform2fARB) { + void ** procp = (void **) &disp->Uniform2fARB; + snprintf(symboln, sizeof(symboln), "%sUniform2f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform2fARB) { + void ** procp = (void **) &disp->Uniform2fARB; + snprintf(symboln, sizeof(symboln), "%sUniform2fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform2fvARB) { + void ** procp = (void **) &disp->Uniform2fvARB; + snprintf(symboln, sizeof(symboln), "%sUniform2fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform2fvARB) { + void ** procp = (void **) &disp->Uniform2fvARB; + snprintf(symboln, sizeof(symboln), "%sUniform2fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform2iARB) { + void ** procp = (void **) &disp->Uniform2iARB; + snprintf(symboln, sizeof(symboln), "%sUniform2i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform2iARB) { + void ** procp = (void **) &disp->Uniform2iARB; + snprintf(symboln, sizeof(symboln), "%sUniform2iARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform2ivARB) { + void ** procp = (void **) &disp->Uniform2ivARB; + snprintf(symboln, sizeof(symboln), "%sUniform2iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform2ivARB) { + void ** procp = (void **) &disp->Uniform2ivARB; + snprintf(symboln, sizeof(symboln), "%sUniform2ivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform3fARB) { + void ** procp = (void **) &disp->Uniform3fARB; + snprintf(symboln, sizeof(symboln), "%sUniform3f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform3fARB) { + void ** procp = (void **) &disp->Uniform3fARB; + snprintf(symboln, sizeof(symboln), "%sUniform3fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform3fvARB) { + void ** procp = (void **) &disp->Uniform3fvARB; + snprintf(symboln, sizeof(symboln), "%sUniform3fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform3fvARB) { + void ** procp = (void **) &disp->Uniform3fvARB; + snprintf(symboln, sizeof(symboln), "%sUniform3fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform3iARB) { + void ** procp = (void **) &disp->Uniform3iARB; + snprintf(symboln, sizeof(symboln), "%sUniform3i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform3iARB) { + void ** procp = (void **) &disp->Uniform3iARB; + snprintf(symboln, sizeof(symboln), "%sUniform3iARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform3ivARB) { + void ** procp = (void **) &disp->Uniform3ivARB; + snprintf(symboln, sizeof(symboln), "%sUniform3iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform3ivARB) { + void ** procp = (void **) &disp->Uniform3ivARB; + snprintf(symboln, sizeof(symboln), "%sUniform3ivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform4fARB) { + void ** procp = (void **) &disp->Uniform4fARB; + snprintf(symboln, sizeof(symboln), "%sUniform4f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform4fARB) { + void ** procp = (void **) &disp->Uniform4fARB; + snprintf(symboln, sizeof(symboln), "%sUniform4fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform4fvARB) { + void ** procp = (void **) &disp->Uniform4fvARB; + snprintf(symboln, sizeof(symboln), "%sUniform4fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform4fvARB) { + void ** procp = (void **) &disp->Uniform4fvARB; + snprintf(symboln, sizeof(symboln), "%sUniform4fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform4iARB) { + void ** procp = (void **) &disp->Uniform4iARB; + snprintf(symboln, sizeof(symboln), "%sUniform4i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform4iARB) { + void ** procp = (void **) &disp->Uniform4iARB; + snprintf(symboln, sizeof(symboln), "%sUniform4iARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform4ivARB) { + void ** procp = (void **) &disp->Uniform4ivARB; + snprintf(symboln, sizeof(symboln), "%sUniform4iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform4ivARB) { + void ** procp = (void **) &disp->Uniform4ivARB; + snprintf(symboln, sizeof(symboln), "%sUniform4ivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UniformMatrix2fvARB) { + void ** procp = (void **) &disp->UniformMatrix2fvARB; + snprintf(symboln, sizeof(symboln), "%sUniformMatrix2fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UniformMatrix2fvARB) { + void ** procp = (void **) &disp->UniformMatrix2fvARB; + snprintf(symboln, sizeof(symboln), "%sUniformMatrix2fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UniformMatrix3fvARB) { + void ** procp = (void **) &disp->UniformMatrix3fvARB; + snprintf(symboln, sizeof(symboln), "%sUniformMatrix3fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UniformMatrix3fvARB) { + void ** procp = (void **) &disp->UniformMatrix3fvARB; + snprintf(symboln, sizeof(symboln), "%sUniformMatrix3fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UniformMatrix4fvARB) { + void ** procp = (void **) &disp->UniformMatrix4fvARB; + snprintf(symboln, sizeof(symboln), "%sUniformMatrix4fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UniformMatrix4fvARB) { + void ** procp = (void **) &disp->UniformMatrix4fvARB; + snprintf(symboln, sizeof(symboln), "%sUniformMatrix4fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UseProgramObjectARB) { + void ** procp = (void **) &disp->UseProgramObjectARB; + snprintf(symboln, sizeof(symboln), "%sUseProgram", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UseProgramObjectARB) { + void ** procp = (void **) &disp->UseProgramObjectARB; + snprintf(symboln, sizeof(symboln), "%sUseProgramObjectARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ValidateProgramARB) { + void ** procp = (void **) &disp->ValidateProgramARB; + snprintf(symboln, sizeof(symboln), "%sValidateProgram", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ValidateProgramARB) { + void ** procp = (void **) &disp->ValidateProgramARB; + snprintf(symboln, sizeof(symboln), "%sValidateProgramARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindAttribLocationARB) { + void ** procp = (void **) &disp->BindAttribLocationARB; + snprintf(symboln, sizeof(symboln), "%sBindAttribLocation", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindAttribLocationARB) { + void ** procp = (void **) &disp->BindAttribLocationARB; + snprintf(symboln, sizeof(symboln), "%sBindAttribLocationARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetActiveAttribARB) { + void ** procp = (void **) &disp->GetActiveAttribARB; + snprintf(symboln, sizeof(symboln), "%sGetActiveAttrib", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetActiveAttribARB) { + void ** procp = (void **) &disp->GetActiveAttribARB; + snprintf(symboln, sizeof(symboln), "%sGetActiveAttribARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetAttribLocationARB) { + void ** procp = (void **) &disp->GetAttribLocationARB; + snprintf(symboln, sizeof(symboln), "%sGetAttribLocation", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetAttribLocationARB) { + void ** procp = (void **) &disp->GetAttribLocationARB; + snprintf(symboln, sizeof(symboln), "%sGetAttribLocationARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawBuffersARB) { + void ** procp = (void **) &disp->DrawBuffersARB; + snprintf(symboln, sizeof(symboln), "%sDrawBuffers", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawBuffersARB) { + void ** procp = (void **) &disp->DrawBuffersARB; + snprintf(symboln, sizeof(symboln), "%sDrawBuffersARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawBuffersARB) { + void ** procp = (void **) &disp->DrawBuffersARB; + snprintf(symboln, sizeof(symboln), "%sDrawBuffersATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClampColorARB) { + void ** procp = (void **) &disp->ClampColorARB; + snprintf(symboln, sizeof(symboln), "%sClampColorARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawArraysInstancedARB) { + void ** procp = (void **) &disp->DrawArraysInstancedARB; + snprintf(symboln, sizeof(symboln), "%sDrawArraysInstancedARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawArraysInstancedARB) { + void ** procp = (void **) &disp->DrawArraysInstancedARB; + snprintf(symboln, sizeof(symboln), "%sDrawArraysInstancedEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawArraysInstancedARB) { + void ** procp = (void **) &disp->DrawArraysInstancedARB; + snprintf(symboln, sizeof(symboln), "%sDrawArraysInstanced", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawElementsInstancedARB) { + void ** procp = (void **) &disp->DrawElementsInstancedARB; + snprintf(symboln, sizeof(symboln), "%sDrawElementsInstancedARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawElementsInstancedARB) { + void ** procp = (void **) &disp->DrawElementsInstancedARB; + snprintf(symboln, sizeof(symboln), "%sDrawElementsInstancedEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawElementsInstancedARB) { + void ** procp = (void **) &disp->DrawElementsInstancedARB; + snprintf(symboln, sizeof(symboln), "%sDrawElementsInstanced", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RenderbufferStorageMultisample) { + void ** procp = (void **) &disp->RenderbufferStorageMultisample; + snprintf(symboln, sizeof(symboln), "%sRenderbufferStorageMultisample", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RenderbufferStorageMultisample) { + void ** procp = (void **) &disp->RenderbufferStorageMultisample; + snprintf(symboln, sizeof(symboln), "%sRenderbufferStorageMultisampleEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FramebufferTextureARB) { + void ** procp = (void **) &disp->FramebufferTextureARB; + snprintf(symboln, sizeof(symboln), "%sFramebufferTextureARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FramebufferTextureFaceARB) { + void ** procp = (void **) &disp->FramebufferTextureFaceARB; + snprintf(symboln, sizeof(symboln), "%sFramebufferTextureFaceARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramParameteriARB) { + void ** procp = (void **) &disp->ProgramParameteriARB; + snprintf(symboln, sizeof(symboln), "%sProgramParameteriARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribDivisorARB) { + void ** procp = (void **) &disp->VertexAttribDivisorARB; + snprintf(symboln, sizeof(symboln), "%sVertexAttribDivisorARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FlushMappedBufferRange) { + void ** procp = (void **) &disp->FlushMappedBufferRange; + snprintf(symboln, sizeof(symboln), "%sFlushMappedBufferRange", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MapBufferRange) { + void ** procp = (void **) &disp->MapBufferRange; + snprintf(symboln, sizeof(symboln), "%sMapBufferRange", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexBufferARB) { + void ** procp = (void **) &disp->TexBufferARB; + snprintf(symboln, sizeof(symboln), "%sTexBufferARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindVertexArray) { + void ** procp = (void **) &disp->BindVertexArray; + snprintf(symboln, sizeof(symboln), "%sBindVertexArray", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenVertexArrays) { + void ** procp = (void **) &disp->GenVertexArrays; + snprintf(symboln, sizeof(symboln), "%sGenVertexArrays", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CopyBufferSubData) { + void ** procp = (void **) &disp->CopyBufferSubData; + snprintf(symboln, sizeof(symboln), "%sCopyBufferSubData", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClientWaitSync) { + void ** procp = (void **) &disp->ClientWaitSync; + snprintf(symboln, sizeof(symboln), "%sClientWaitSync", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteSync) { + void ** procp = (void **) &disp->DeleteSync; + snprintf(symboln, sizeof(symboln), "%sDeleteSync", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FenceSync) { + void ** procp = (void **) &disp->FenceSync; + snprintf(symboln, sizeof(symboln), "%sFenceSync", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetInteger64v) { + void ** procp = (void **) &disp->GetInteger64v; + snprintf(symboln, sizeof(symboln), "%sGetInteger64v", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetSynciv) { + void ** procp = (void **) &disp->GetSynciv; + snprintf(symboln, sizeof(symboln), "%sGetSynciv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsSync) { + void ** procp = (void **) &disp->IsSync; + snprintf(symboln, sizeof(symboln), "%sIsSync", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WaitSync) { + void ** procp = (void **) &disp->WaitSync; + snprintf(symboln, sizeof(symboln), "%sWaitSync", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawElementsBaseVertex) { + void ** procp = (void **) &disp->DrawElementsBaseVertex; + snprintf(symboln, sizeof(symboln), "%sDrawElementsBaseVertex", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawElementsInstancedBaseVertex) { + void ** procp = (void **) &disp->DrawElementsInstancedBaseVertex; + snprintf(symboln, sizeof(symboln), "%sDrawElementsInstancedBaseVertex", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawRangeElementsBaseVertex) { + void ** procp = (void **) &disp->DrawRangeElementsBaseVertex; + snprintf(symboln, sizeof(symboln), "%sDrawRangeElementsBaseVertex", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiDrawElementsBaseVertex) { + void ** procp = (void **) &disp->MultiDrawElementsBaseVertex; + snprintf(symboln, sizeof(symboln), "%sMultiDrawElementsBaseVertex", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendEquationSeparateiARB) { + void ** procp = (void **) &disp->BlendEquationSeparateiARB; + snprintf(symboln, sizeof(symboln), "%sBlendEquationSeparateiARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendEquationSeparateiARB) { + void ** procp = (void **) &disp->BlendEquationSeparateiARB; + snprintf(symboln, sizeof(symboln), "%sBlendEquationSeparateIndexedAMD", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendEquationiARB) { + void ** procp = (void **) &disp->BlendEquationiARB; + snprintf(symboln, sizeof(symboln), "%sBlendEquationiARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendEquationiARB) { + void ** procp = (void **) &disp->BlendEquationiARB; + snprintf(symboln, sizeof(symboln), "%sBlendEquationIndexedAMD", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendFuncSeparateiARB) { + void ** procp = (void **) &disp->BlendFuncSeparateiARB; + snprintf(symboln, sizeof(symboln), "%sBlendFuncSeparateiARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendFuncSeparateiARB) { + void ** procp = (void **) &disp->BlendFuncSeparateiARB; + snprintf(symboln, sizeof(symboln), "%sBlendFuncSeparateIndexedAMD", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendFunciARB) { + void ** procp = (void **) &disp->BlendFunciARB; + snprintf(symboln, sizeof(symboln), "%sBlendFunciARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendFunciARB) { + void ** procp = (void **) &disp->BlendFunciARB; + snprintf(symboln, sizeof(symboln), "%sBlendFuncIndexedAMD", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindSampler) { + void ** procp = (void **) &disp->BindSampler; + snprintf(symboln, sizeof(symboln), "%sBindSampler", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteSamplers) { + void ** procp = (void **) &disp->DeleteSamplers; + snprintf(symboln, sizeof(symboln), "%sDeleteSamplers", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenSamplers) { + void ** procp = (void **) &disp->GenSamplers; + snprintf(symboln, sizeof(symboln), "%sGenSamplers", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetSamplerParameterIiv) { + void ** procp = (void **) &disp->GetSamplerParameterIiv; + snprintf(symboln, sizeof(symboln), "%sGetSamplerParameterIiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetSamplerParameterIuiv) { + void ** procp = (void **) &disp->GetSamplerParameterIuiv; + snprintf(symboln, sizeof(symboln), "%sGetSamplerParameterIuiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetSamplerParameterfv) { + void ** procp = (void **) &disp->GetSamplerParameterfv; + snprintf(symboln, sizeof(symboln), "%sGetSamplerParameterfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetSamplerParameteriv) { + void ** procp = (void **) &disp->GetSamplerParameteriv; + snprintf(symboln, sizeof(symboln), "%sGetSamplerParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsSampler) { + void ** procp = (void **) &disp->IsSampler; + snprintf(symboln, sizeof(symboln), "%sIsSampler", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SamplerParameterIiv) { + void ** procp = (void **) &disp->SamplerParameterIiv; + snprintf(symboln, sizeof(symboln), "%sSamplerParameterIiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SamplerParameterIuiv) { + void ** procp = (void **) &disp->SamplerParameterIuiv; + snprintf(symboln, sizeof(symboln), "%sSamplerParameterIuiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SamplerParameterf) { + void ** procp = (void **) &disp->SamplerParameterf; + snprintf(symboln, sizeof(symboln), "%sSamplerParameterf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SamplerParameterfv) { + void ** procp = (void **) &disp->SamplerParameterfv; + snprintf(symboln, sizeof(symboln), "%sSamplerParameterfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SamplerParameteri) { + void ** procp = (void **) &disp->SamplerParameteri; + snprintf(symboln, sizeof(symboln), "%sSamplerParameteri", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SamplerParameteriv) { + void ** procp = (void **) &disp->SamplerParameteriv; + snprintf(symboln, sizeof(symboln), "%sSamplerParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindTransformFeedback) { + void ** procp = (void **) &disp->BindTransformFeedback; + snprintf(symboln, sizeof(symboln), "%sBindTransformFeedback", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteTransformFeedbacks) { + void ** procp = (void **) &disp->DeleteTransformFeedbacks; + snprintf(symboln, sizeof(symboln), "%sDeleteTransformFeedbacks", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DrawTransformFeedback) { + void ** procp = (void **) &disp->DrawTransformFeedback; + snprintf(symboln, sizeof(symboln), "%sDrawTransformFeedback", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenTransformFeedbacks) { + void ** procp = (void **) &disp->GenTransformFeedbacks; + snprintf(symboln, sizeof(symboln), "%sGenTransformFeedbacks", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsTransformFeedback) { + void ** procp = (void **) &disp->IsTransformFeedback; + snprintf(symboln, sizeof(symboln), "%sIsTransformFeedback", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PauseTransformFeedback) { + void ** procp = (void **) &disp->PauseTransformFeedback; + snprintf(symboln, sizeof(symboln), "%sPauseTransformFeedback", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ResumeTransformFeedback) { + void ** procp = (void **) &disp->ResumeTransformFeedback; + snprintf(symboln, sizeof(symboln), "%sResumeTransformFeedback", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClearDepthf) { + void ** procp = (void **) &disp->ClearDepthf; + snprintf(symboln, sizeof(symboln), "%sClearDepthf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DepthRangef) { + void ** procp = (void **) &disp->DepthRangef; + snprintf(symboln, sizeof(symboln), "%sDepthRangef", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetShaderPrecisionFormat) { + void ** procp = (void **) &disp->GetShaderPrecisionFormat; + snprintf(symboln, sizeof(symboln), "%sGetShaderPrecisionFormat", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ReleaseShaderCompiler) { + void ** procp = (void **) &disp->ReleaseShaderCompiler; + snprintf(symboln, sizeof(symboln), "%sReleaseShaderCompiler", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ShaderBinary) { + void ** procp = (void **) &disp->ShaderBinary; + snprintf(symboln, sizeof(symboln), "%sShaderBinary", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetGraphicsResetStatusARB) { + void ** procp = (void **) &disp->GetGraphicsResetStatusARB; + snprintf(symboln, sizeof(symboln), "%sGetGraphicsResetStatusARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnColorTableARB) { + void ** procp = (void **) &disp->GetnColorTableARB; + snprintf(symboln, sizeof(symboln), "%sGetnColorTableARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnCompressedTexImageARB) { + void ** procp = (void **) &disp->GetnCompressedTexImageARB; + snprintf(symboln, sizeof(symboln), "%sGetnCompressedTexImageARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnConvolutionFilterARB) { + void ** procp = (void **) &disp->GetnConvolutionFilterARB; + snprintf(symboln, sizeof(symboln), "%sGetnConvolutionFilterARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnHistogramARB) { + void ** procp = (void **) &disp->GetnHistogramARB; + snprintf(symboln, sizeof(symboln), "%sGetnHistogramARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnMapdvARB) { + void ** procp = (void **) &disp->GetnMapdvARB; + snprintf(symboln, sizeof(symboln), "%sGetnMapdvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnMapfvARB) { + void ** procp = (void **) &disp->GetnMapfvARB; + snprintf(symboln, sizeof(symboln), "%sGetnMapfvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnMapivARB) { + void ** procp = (void **) &disp->GetnMapivARB; + snprintf(symboln, sizeof(symboln), "%sGetnMapivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnMinmaxARB) { + void ** procp = (void **) &disp->GetnMinmaxARB; + snprintf(symboln, sizeof(symboln), "%sGetnMinmaxARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnPixelMapfvARB) { + void ** procp = (void **) &disp->GetnPixelMapfvARB; + snprintf(symboln, sizeof(symboln), "%sGetnPixelMapfvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnPixelMapuivARB) { + void ** procp = (void **) &disp->GetnPixelMapuivARB; + snprintf(symboln, sizeof(symboln), "%sGetnPixelMapuivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnPixelMapusvARB) { + void ** procp = (void **) &disp->GetnPixelMapusvARB; + snprintf(symboln, sizeof(symboln), "%sGetnPixelMapusvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnPolygonStippleARB) { + void ** procp = (void **) &disp->GetnPolygonStippleARB; + snprintf(symboln, sizeof(symboln), "%sGetnPolygonStippleARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnSeparableFilterARB) { + void ** procp = (void **) &disp->GetnSeparableFilterARB; + snprintf(symboln, sizeof(symboln), "%sGetnSeparableFilterARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnTexImageARB) { + void ** procp = (void **) &disp->GetnTexImageARB; + snprintf(symboln, sizeof(symboln), "%sGetnTexImageARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnUniformdvARB) { + void ** procp = (void **) &disp->GetnUniformdvARB; + snprintf(symboln, sizeof(symboln), "%sGetnUniformdvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnUniformfvARB) { + void ** procp = (void **) &disp->GetnUniformfvARB; + snprintf(symboln, sizeof(symboln), "%sGetnUniformfvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnUniformivARB) { + void ** procp = (void **) &disp->GetnUniformivARB; + snprintf(symboln, sizeof(symboln), "%sGetnUniformivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetnUniformuivARB) { + void ** procp = (void **) &disp->GetnUniformuivARB; + snprintf(symboln, sizeof(symboln), "%sGetnUniformuivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ReadnPixelsARB) { + void ** procp = (void **) &disp->ReadnPixelsARB; + snprintf(symboln, sizeof(symboln), "%sReadnPixelsARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PolygonOffsetEXT) { + void ** procp = (void **) &disp->PolygonOffsetEXT; + snprintf(symboln, sizeof(symboln), "%sPolygonOffsetEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetPixelTexGenParameterfvSGIS) { + void ** procp = (void **) &disp->GetPixelTexGenParameterfvSGIS; + snprintf(symboln, sizeof(symboln), "%sGetPixelTexGenParameterfvSGIS", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetPixelTexGenParameterivSGIS) { + void ** procp = (void **) &disp->GetPixelTexGenParameterivSGIS; + snprintf(symboln, sizeof(symboln), "%sGetPixelTexGenParameterivSGIS", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PixelTexGenParameterfSGIS) { + void ** procp = (void **) &disp->PixelTexGenParameterfSGIS; + snprintf(symboln, sizeof(symboln), "%sPixelTexGenParameterfSGIS", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PixelTexGenParameterfvSGIS) { + void ** procp = (void **) &disp->PixelTexGenParameterfvSGIS; + snprintf(symboln, sizeof(symboln), "%sPixelTexGenParameterfvSGIS", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PixelTexGenParameteriSGIS) { + void ** procp = (void **) &disp->PixelTexGenParameteriSGIS; + snprintf(symboln, sizeof(symboln), "%sPixelTexGenParameteriSGIS", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PixelTexGenParameterivSGIS) { + void ** procp = (void **) &disp->PixelTexGenParameterivSGIS; + snprintf(symboln, sizeof(symboln), "%sPixelTexGenParameterivSGIS", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SampleMaskSGIS) { + void ** procp = (void **) &disp->SampleMaskSGIS; + snprintf(symboln, sizeof(symboln), "%sSampleMaskSGIS", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SampleMaskSGIS) { + void ** procp = (void **) &disp->SampleMaskSGIS; + snprintf(symboln, sizeof(symboln), "%sSampleMaskEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SamplePatternSGIS) { + void ** procp = (void **) &disp->SamplePatternSGIS; + snprintf(symboln, sizeof(symboln), "%sSamplePatternSGIS", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SamplePatternSGIS) { + void ** procp = (void **) &disp->SamplePatternSGIS; + snprintf(symboln, sizeof(symboln), "%sSamplePatternEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorPointerEXT) { + void ** procp = (void **) &disp->ColorPointerEXT; + snprintf(symboln, sizeof(symboln), "%sColorPointerEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EdgeFlagPointerEXT) { + void ** procp = (void **) &disp->EdgeFlagPointerEXT; + snprintf(symboln, sizeof(symboln), "%sEdgeFlagPointerEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IndexPointerEXT) { + void ** procp = (void **) &disp->IndexPointerEXT; + snprintf(symboln, sizeof(symboln), "%sIndexPointerEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->NormalPointerEXT) { + void ** procp = (void **) &disp->NormalPointerEXT; + snprintf(symboln, sizeof(symboln), "%sNormalPointerEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexCoordPointerEXT) { + void ** procp = (void **) &disp->TexCoordPointerEXT; + snprintf(symboln, sizeof(symboln), "%sTexCoordPointerEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexPointerEXT) { + void ** procp = (void **) &disp->VertexPointerEXT; + snprintf(symboln, sizeof(symboln), "%sVertexPointerEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PointParameterfEXT) { + void ** procp = (void **) &disp->PointParameterfEXT; + snprintf(symboln, sizeof(symboln), "%sPointParameterf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PointParameterfEXT) { + void ** procp = (void **) &disp->PointParameterfEXT; + snprintf(symboln, sizeof(symboln), "%sPointParameterfARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PointParameterfEXT) { + void ** procp = (void **) &disp->PointParameterfEXT; + snprintf(symboln, sizeof(symboln), "%sPointParameterfEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PointParameterfEXT) { + void ** procp = (void **) &disp->PointParameterfEXT; + snprintf(symboln, sizeof(symboln), "%sPointParameterfSGIS", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PointParameterfvEXT) { + void ** procp = (void **) &disp->PointParameterfvEXT; + snprintf(symboln, sizeof(symboln), "%sPointParameterfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PointParameterfvEXT) { + void ** procp = (void **) &disp->PointParameterfvEXT; + snprintf(symboln, sizeof(symboln), "%sPointParameterfvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PointParameterfvEXT) { + void ** procp = (void **) &disp->PointParameterfvEXT; + snprintf(symboln, sizeof(symboln), "%sPointParameterfvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PointParameterfvEXT) { + void ** procp = (void **) &disp->PointParameterfvEXT; + snprintf(symboln, sizeof(symboln), "%sPointParameterfvSGIS", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LockArraysEXT) { + void ** procp = (void **) &disp->LockArraysEXT; + snprintf(symboln, sizeof(symboln), "%sLockArraysEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UnlockArraysEXT) { + void ** procp = (void **) &disp->UnlockArraysEXT; + snprintf(symboln, sizeof(symboln), "%sUnlockArraysEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3bEXT) { + void ** procp = (void **) &disp->SecondaryColor3bEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3b", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3bEXT) { + void ** procp = (void **) &disp->SecondaryColor3bEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3bEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3bvEXT) { + void ** procp = (void **) &disp->SecondaryColor3bvEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3bv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3bvEXT) { + void ** procp = (void **) &disp->SecondaryColor3bvEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3bvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3dEXT) { + void ** procp = (void **) &disp->SecondaryColor3dEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3dEXT) { + void ** procp = (void **) &disp->SecondaryColor3dEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3dEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3dvEXT) { + void ** procp = (void **) &disp->SecondaryColor3dvEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3dvEXT) { + void ** procp = (void **) &disp->SecondaryColor3dvEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3dvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3fEXT) { + void ** procp = (void **) &disp->SecondaryColor3fEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3fEXT) { + void ** procp = (void **) &disp->SecondaryColor3fEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3fEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3fvEXT) { + void ** procp = (void **) &disp->SecondaryColor3fvEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3fvEXT) { + void ** procp = (void **) &disp->SecondaryColor3fvEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3fvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3iEXT) { + void ** procp = (void **) &disp->SecondaryColor3iEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3iEXT) { + void ** procp = (void **) &disp->SecondaryColor3iEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3iEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3ivEXT) { + void ** procp = (void **) &disp->SecondaryColor3ivEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3ivEXT) { + void ** procp = (void **) &disp->SecondaryColor3ivEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3ivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3sEXT) { + void ** procp = (void **) &disp->SecondaryColor3sEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3sEXT) { + void ** procp = (void **) &disp->SecondaryColor3sEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3sEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3svEXT) { + void ** procp = (void **) &disp->SecondaryColor3svEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3svEXT) { + void ** procp = (void **) &disp->SecondaryColor3svEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3svEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3ubEXT) { + void ** procp = (void **) &disp->SecondaryColor3ubEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3ub", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3ubEXT) { + void ** procp = (void **) &disp->SecondaryColor3ubEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3ubEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3ubvEXT) { + void ** procp = (void **) &disp->SecondaryColor3ubvEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3ubv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3ubvEXT) { + void ** procp = (void **) &disp->SecondaryColor3ubvEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3ubvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3uiEXT) { + void ** procp = (void **) &disp->SecondaryColor3uiEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3ui", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3uiEXT) { + void ** procp = (void **) &disp->SecondaryColor3uiEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3uiEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3uivEXT) { + void ** procp = (void **) &disp->SecondaryColor3uivEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3uiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3uivEXT) { + void ** procp = (void **) &disp->SecondaryColor3uivEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3uivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3usEXT) { + void ** procp = (void **) &disp->SecondaryColor3usEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3us", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3usEXT) { + void ** procp = (void **) &disp->SecondaryColor3usEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3usEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3usvEXT) { + void ** procp = (void **) &disp->SecondaryColor3usvEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3usv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColor3usvEXT) { + void ** procp = (void **) &disp->SecondaryColor3usvEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColor3usvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColorPointerEXT) { + void ** procp = (void **) &disp->SecondaryColorPointerEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColorPointer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SecondaryColorPointerEXT) { + void ** procp = (void **) &disp->SecondaryColorPointerEXT; + snprintf(symboln, sizeof(symboln), "%sSecondaryColorPointerEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiDrawArraysEXT) { + void ** procp = (void **) &disp->MultiDrawArraysEXT; + snprintf(symboln, sizeof(symboln), "%sMultiDrawArrays", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiDrawArraysEXT) { + void ** procp = (void **) &disp->MultiDrawArraysEXT; + snprintf(symboln, sizeof(symboln), "%sMultiDrawArraysEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiDrawElementsEXT) { + void ** procp = (void **) &disp->MultiDrawElementsEXT; + snprintf(symboln, sizeof(symboln), "%sMultiDrawElements", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiDrawElementsEXT) { + void ** procp = (void **) &disp->MultiDrawElementsEXT; + snprintf(symboln, sizeof(symboln), "%sMultiDrawElementsEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FogCoordPointerEXT) { + void ** procp = (void **) &disp->FogCoordPointerEXT; + snprintf(symboln, sizeof(symboln), "%sFogCoordPointer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FogCoordPointerEXT) { + void ** procp = (void **) &disp->FogCoordPointerEXT; + snprintf(symboln, sizeof(symboln), "%sFogCoordPointerEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FogCoorddEXT) { + void ** procp = (void **) &disp->FogCoorddEXT; + snprintf(symboln, sizeof(symboln), "%sFogCoordd", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FogCoorddEXT) { + void ** procp = (void **) &disp->FogCoorddEXT; + snprintf(symboln, sizeof(symboln), "%sFogCoorddEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FogCoorddvEXT) { + void ** procp = (void **) &disp->FogCoorddvEXT; + snprintf(symboln, sizeof(symboln), "%sFogCoorddv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FogCoorddvEXT) { + void ** procp = (void **) &disp->FogCoorddvEXT; + snprintf(symboln, sizeof(symboln), "%sFogCoorddvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FogCoordfEXT) { + void ** procp = (void **) &disp->FogCoordfEXT; + snprintf(symboln, sizeof(symboln), "%sFogCoordf", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FogCoordfEXT) { + void ** procp = (void **) &disp->FogCoordfEXT; + snprintf(symboln, sizeof(symboln), "%sFogCoordfEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FogCoordfvEXT) { + void ** procp = (void **) &disp->FogCoordfvEXT; + snprintf(symboln, sizeof(symboln), "%sFogCoordfv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FogCoordfvEXT) { + void ** procp = (void **) &disp->FogCoordfvEXT; + snprintf(symboln, sizeof(symboln), "%sFogCoordfvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PixelTexGenSGIX) { + void ** procp = (void **) &disp->PixelTexGenSGIX; + snprintf(symboln, sizeof(symboln), "%sPixelTexGenSGIX", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendFuncSeparateEXT) { + void ** procp = (void **) &disp->BlendFuncSeparateEXT; + snprintf(symboln, sizeof(symboln), "%sBlendFuncSeparate", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendFuncSeparateEXT) { + void ** procp = (void **) &disp->BlendFuncSeparateEXT; + snprintf(symboln, sizeof(symboln), "%sBlendFuncSeparateEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendFuncSeparateEXT) { + void ** procp = (void **) &disp->BlendFuncSeparateEXT; + snprintf(symboln, sizeof(symboln), "%sBlendFuncSeparateINGR", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FlushVertexArrayRangeNV) { + void ** procp = (void **) &disp->FlushVertexArrayRangeNV; + snprintf(symboln, sizeof(symboln), "%sFlushVertexArrayRangeNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexArrayRangeNV) { + void ** procp = (void **) &disp->VertexArrayRangeNV; + snprintf(symboln, sizeof(symboln), "%sVertexArrayRangeNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CombinerInputNV) { + void ** procp = (void **) &disp->CombinerInputNV; + snprintf(symboln, sizeof(symboln), "%sCombinerInputNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CombinerOutputNV) { + void ** procp = (void **) &disp->CombinerOutputNV; + snprintf(symboln, sizeof(symboln), "%sCombinerOutputNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CombinerParameterfNV) { + void ** procp = (void **) &disp->CombinerParameterfNV; + snprintf(symboln, sizeof(symboln), "%sCombinerParameterfNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CombinerParameterfvNV) { + void ** procp = (void **) &disp->CombinerParameterfvNV; + snprintf(symboln, sizeof(symboln), "%sCombinerParameterfvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CombinerParameteriNV) { + void ** procp = (void **) &disp->CombinerParameteriNV; + snprintf(symboln, sizeof(symboln), "%sCombinerParameteriNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CombinerParameterivNV) { + void ** procp = (void **) &disp->CombinerParameterivNV; + snprintf(symboln, sizeof(symboln), "%sCombinerParameterivNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FinalCombinerInputNV) { + void ** procp = (void **) &disp->FinalCombinerInputNV; + snprintf(symboln, sizeof(symboln), "%sFinalCombinerInputNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetCombinerInputParameterfvNV) { + void ** procp = (void **) &disp->GetCombinerInputParameterfvNV; + snprintf(symboln, sizeof(symboln), "%sGetCombinerInputParameterfvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetCombinerInputParameterivNV) { + void ** procp = (void **) &disp->GetCombinerInputParameterivNV; + snprintf(symboln, sizeof(symboln), "%sGetCombinerInputParameterivNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetCombinerOutputParameterfvNV) { + void ** procp = (void **) &disp->GetCombinerOutputParameterfvNV; + snprintf(symboln, sizeof(symboln), "%sGetCombinerOutputParameterfvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetCombinerOutputParameterivNV) { + void ** procp = (void **) &disp->GetCombinerOutputParameterivNV; + snprintf(symboln, sizeof(symboln), "%sGetCombinerOutputParameterivNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetFinalCombinerInputParameterfvNV) { + void ** procp = (void **) &disp->GetFinalCombinerInputParameterfvNV; + snprintf(symboln, sizeof(symboln), "%sGetFinalCombinerInputParameterfvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetFinalCombinerInputParameterivNV) { + void ** procp = (void **) &disp->GetFinalCombinerInputParameterivNV; + snprintf(symboln, sizeof(symboln), "%sGetFinalCombinerInputParameterivNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ResizeBuffersMESA) { + void ** procp = (void **) &disp->ResizeBuffersMESA; + snprintf(symboln, sizeof(symboln), "%sResizeBuffersMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2dMESA) { + void ** procp = (void **) &disp->WindowPos2dMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2dMESA) { + void ** procp = (void **) &disp->WindowPos2dMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2dARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2dMESA) { + void ** procp = (void **) &disp->WindowPos2dMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2dMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2dvMESA) { + void ** procp = (void **) &disp->WindowPos2dvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2dvMESA) { + void ** procp = (void **) &disp->WindowPos2dvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2dvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2dvMESA) { + void ** procp = (void **) &disp->WindowPos2dvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2dvMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2fMESA) { + void ** procp = (void **) &disp->WindowPos2fMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2fMESA) { + void ** procp = (void **) &disp->WindowPos2fMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2fMESA) { + void ** procp = (void **) &disp->WindowPos2fMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2fMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2fvMESA) { + void ** procp = (void **) &disp->WindowPos2fvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2fvMESA) { + void ** procp = (void **) &disp->WindowPos2fvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2fvMESA) { + void ** procp = (void **) &disp->WindowPos2fvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2fvMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2iMESA) { + void ** procp = (void **) &disp->WindowPos2iMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2iMESA) { + void ** procp = (void **) &disp->WindowPos2iMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2iARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2iMESA) { + void ** procp = (void **) &disp->WindowPos2iMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2iMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2ivMESA) { + void ** procp = (void **) &disp->WindowPos2ivMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2ivMESA) { + void ** procp = (void **) &disp->WindowPos2ivMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2ivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2ivMESA) { + void ** procp = (void **) &disp->WindowPos2ivMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2ivMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2sMESA) { + void ** procp = (void **) &disp->WindowPos2sMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2sMESA) { + void ** procp = (void **) &disp->WindowPos2sMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2sARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2sMESA) { + void ** procp = (void **) &disp->WindowPos2sMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2sMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2svMESA) { + void ** procp = (void **) &disp->WindowPos2svMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2svMESA) { + void ** procp = (void **) &disp->WindowPos2svMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2svARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos2svMESA) { + void ** procp = (void **) &disp->WindowPos2svMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos2svMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3dMESA) { + void ** procp = (void **) &disp->WindowPos3dMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3d", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3dMESA) { + void ** procp = (void **) &disp->WindowPos3dMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3dARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3dMESA) { + void ** procp = (void **) &disp->WindowPos3dMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3dMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3dvMESA) { + void ** procp = (void **) &disp->WindowPos3dvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3dv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3dvMESA) { + void ** procp = (void **) &disp->WindowPos3dvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3dvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3dvMESA) { + void ** procp = (void **) &disp->WindowPos3dvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3dvMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3fMESA) { + void ** procp = (void **) &disp->WindowPos3fMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3f", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3fMESA) { + void ** procp = (void **) &disp->WindowPos3fMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3fARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3fMESA) { + void ** procp = (void **) &disp->WindowPos3fMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3fMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3fvMESA) { + void ** procp = (void **) &disp->WindowPos3fvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3fv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3fvMESA) { + void ** procp = (void **) &disp->WindowPos3fvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3fvARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3fvMESA) { + void ** procp = (void **) &disp->WindowPos3fvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3fvMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3iMESA) { + void ** procp = (void **) &disp->WindowPos3iMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3iMESA) { + void ** procp = (void **) &disp->WindowPos3iMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3iARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3iMESA) { + void ** procp = (void **) &disp->WindowPos3iMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3iMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3ivMESA) { + void ** procp = (void **) &disp->WindowPos3ivMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3ivMESA) { + void ** procp = (void **) &disp->WindowPos3ivMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3ivARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3ivMESA) { + void ** procp = (void **) &disp->WindowPos3ivMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3ivMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3sMESA) { + void ** procp = (void **) &disp->WindowPos3sMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3s", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3sMESA) { + void ** procp = (void **) &disp->WindowPos3sMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3sARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3sMESA) { + void ** procp = (void **) &disp->WindowPos3sMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3sMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3svMESA) { + void ** procp = (void **) &disp->WindowPos3svMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3svMESA) { + void ** procp = (void **) &disp->WindowPos3svMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3svARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos3svMESA) { + void ** procp = (void **) &disp->WindowPos3svMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos3svMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos4dMESA) { + void ** procp = (void **) &disp->WindowPos4dMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos4dMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos4dvMESA) { + void ** procp = (void **) &disp->WindowPos4dvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos4dvMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos4fMESA) { + void ** procp = (void **) &disp->WindowPos4fMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos4fMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos4fvMESA) { + void ** procp = (void **) &disp->WindowPos4fvMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos4fvMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos4iMESA) { + void ** procp = (void **) &disp->WindowPos4iMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos4iMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos4ivMESA) { + void ** procp = (void **) &disp->WindowPos4ivMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos4ivMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos4sMESA) { + void ** procp = (void **) &disp->WindowPos4sMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos4sMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->WindowPos4svMESA) { + void ** procp = (void **) &disp->WindowPos4svMESA; + snprintf(symboln, sizeof(symboln), "%sWindowPos4svMESA", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiModeDrawArraysIBM) { + void ** procp = (void **) &disp->MultiModeDrawArraysIBM; + snprintf(symboln, sizeof(symboln), "%sMultiModeDrawArraysIBM", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->MultiModeDrawElementsIBM) { + void ** procp = (void **) &disp->MultiModeDrawElementsIBM; + snprintf(symboln, sizeof(symboln), "%sMultiModeDrawElementsIBM", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteFencesNV) { + void ** procp = (void **) &disp->DeleteFencesNV; + snprintf(symboln, sizeof(symboln), "%sDeleteFencesNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FinishFenceNV) { + void ** procp = (void **) &disp->FinishFenceNV; + snprintf(symboln, sizeof(symboln), "%sFinishFenceNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenFencesNV) { + void ** procp = (void **) &disp->GenFencesNV; + snprintf(symboln, sizeof(symboln), "%sGenFencesNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetFenceivNV) { + void ** procp = (void **) &disp->GetFenceivNV; + snprintf(symboln, sizeof(symboln), "%sGetFenceivNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsFenceNV) { + void ** procp = (void **) &disp->IsFenceNV; + snprintf(symboln, sizeof(symboln), "%sIsFenceNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SetFenceNV) { + void ** procp = (void **) &disp->SetFenceNV; + snprintf(symboln, sizeof(symboln), "%sSetFenceNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TestFenceNV) { + void ** procp = (void **) &disp->TestFenceNV; + snprintf(symboln, sizeof(symboln), "%sTestFenceNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->AreProgramsResidentNV) { + void ** procp = (void **) &disp->AreProgramsResidentNV; + snprintf(symboln, sizeof(symboln), "%sAreProgramsResidentNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindProgramNV) { + void ** procp = (void **) &disp->BindProgramNV; + snprintf(symboln, sizeof(symboln), "%sBindProgramARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindProgramNV) { + void ** procp = (void **) &disp->BindProgramNV; + snprintf(symboln, sizeof(symboln), "%sBindProgramNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteProgramsNV) { + void ** procp = (void **) &disp->DeleteProgramsNV; + snprintf(symboln, sizeof(symboln), "%sDeleteProgramsARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteProgramsNV) { + void ** procp = (void **) &disp->DeleteProgramsNV; + snprintf(symboln, sizeof(symboln), "%sDeleteProgramsNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ExecuteProgramNV) { + void ** procp = (void **) &disp->ExecuteProgramNV; + snprintf(symboln, sizeof(symboln), "%sExecuteProgramNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenProgramsNV) { + void ** procp = (void **) &disp->GenProgramsNV; + snprintf(symboln, sizeof(symboln), "%sGenProgramsARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenProgramsNV) { + void ** procp = (void **) &disp->GenProgramsNV; + snprintf(symboln, sizeof(symboln), "%sGenProgramsNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramParameterdvNV) { + void ** procp = (void **) &disp->GetProgramParameterdvNV; + snprintf(symboln, sizeof(symboln), "%sGetProgramParameterdvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramParameterfvNV) { + void ** procp = (void **) &disp->GetProgramParameterfvNV; + snprintf(symboln, sizeof(symboln), "%sGetProgramParameterfvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramStringNV) { + void ** procp = (void **) &disp->GetProgramStringNV; + snprintf(symboln, sizeof(symboln), "%sGetProgramStringNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramivNV) { + void ** procp = (void **) &disp->GetProgramivNV; + snprintf(symboln, sizeof(symboln), "%sGetProgramivNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTrackMatrixivNV) { + void ** procp = (void **) &disp->GetTrackMatrixivNV; + snprintf(symboln, sizeof(symboln), "%sGetTrackMatrixivNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribPointervNV) { + void ** procp = (void **) &disp->GetVertexAttribPointervNV; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribPointerv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribPointervNV) { + void ** procp = (void **) &disp->GetVertexAttribPointervNV; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribPointervARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribPointervNV) { + void ** procp = (void **) &disp->GetVertexAttribPointervNV; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribPointervNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribdvNV) { + void ** procp = (void **) &disp->GetVertexAttribdvNV; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribdvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribfvNV) { + void ** procp = (void **) &disp->GetVertexAttribfvNV; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribfvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribivNV) { + void ** procp = (void **) &disp->GetVertexAttribivNV; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribivNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsProgramNV) { + void ** procp = (void **) &disp->IsProgramNV; + snprintf(symboln, sizeof(symboln), "%sIsProgramARB", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsProgramNV) { + void ** procp = (void **) &disp->IsProgramNV; + snprintf(symboln, sizeof(symboln), "%sIsProgramNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->LoadProgramNV) { + void ** procp = (void **) &disp->LoadProgramNV; + snprintf(symboln, sizeof(symboln), "%sLoadProgramNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramParameters4dvNV) { + void ** procp = (void **) &disp->ProgramParameters4dvNV; + snprintf(symboln, sizeof(symboln), "%sProgramParameters4dvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramParameters4fvNV) { + void ** procp = (void **) &disp->ProgramParameters4fvNV; + snprintf(symboln, sizeof(symboln), "%sProgramParameters4fvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RequestResidentProgramsNV) { + void ** procp = (void **) &disp->RequestResidentProgramsNV; + snprintf(symboln, sizeof(symboln), "%sRequestResidentProgramsNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TrackMatrixNV) { + void ** procp = (void **) &disp->TrackMatrixNV; + snprintf(symboln, sizeof(symboln), "%sTrackMatrixNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1dNV) { + void ** procp = (void **) &disp->VertexAttrib1dNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1dNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1dvNV) { + void ** procp = (void **) &disp->VertexAttrib1dvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1dvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1fNV) { + void ** procp = (void **) &disp->VertexAttrib1fNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1fNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1fvNV) { + void ** procp = (void **) &disp->VertexAttrib1fvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1fvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1sNV) { + void ** procp = (void **) &disp->VertexAttrib1sNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1sNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib1svNV) { + void ** procp = (void **) &disp->VertexAttrib1svNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib1svNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2dNV) { + void ** procp = (void **) &disp->VertexAttrib2dNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2dNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2dvNV) { + void ** procp = (void **) &disp->VertexAttrib2dvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2dvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2fNV) { + void ** procp = (void **) &disp->VertexAttrib2fNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2fNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2fvNV) { + void ** procp = (void **) &disp->VertexAttrib2fvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2fvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2sNV) { + void ** procp = (void **) &disp->VertexAttrib2sNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2sNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib2svNV) { + void ** procp = (void **) &disp->VertexAttrib2svNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib2svNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3dNV) { + void ** procp = (void **) &disp->VertexAttrib3dNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3dNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3dvNV) { + void ** procp = (void **) &disp->VertexAttrib3dvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3dvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3fNV) { + void ** procp = (void **) &disp->VertexAttrib3fNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3fNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3fvNV) { + void ** procp = (void **) &disp->VertexAttrib3fvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3fvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3sNV) { + void ** procp = (void **) &disp->VertexAttrib3sNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3sNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib3svNV) { + void ** procp = (void **) &disp->VertexAttrib3svNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib3svNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4dNV) { + void ** procp = (void **) &disp->VertexAttrib4dNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4dNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4dvNV) { + void ** procp = (void **) &disp->VertexAttrib4dvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4dvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4fNV) { + void ** procp = (void **) &disp->VertexAttrib4fNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4fNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4fvNV) { + void ** procp = (void **) &disp->VertexAttrib4fvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4fvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4sNV) { + void ** procp = (void **) &disp->VertexAttrib4sNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4sNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4svNV) { + void ** procp = (void **) &disp->VertexAttrib4svNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4svNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4ubNV) { + void ** procp = (void **) &disp->VertexAttrib4ubNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4ubNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttrib4ubvNV) { + void ** procp = (void **) &disp->VertexAttrib4ubvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttrib4ubvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribPointerNV) { + void ** procp = (void **) &disp->VertexAttribPointerNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribPointerNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribs1dvNV) { + void ** procp = (void **) &disp->VertexAttribs1dvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribs1dvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribs1fvNV) { + void ** procp = (void **) &disp->VertexAttribs1fvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribs1fvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribs1svNV) { + void ** procp = (void **) &disp->VertexAttribs1svNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribs1svNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribs2dvNV) { + void ** procp = (void **) &disp->VertexAttribs2dvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribs2dvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribs2fvNV) { + void ** procp = (void **) &disp->VertexAttribs2fvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribs2fvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribs2svNV) { + void ** procp = (void **) &disp->VertexAttribs2svNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribs2svNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribs3dvNV) { + void ** procp = (void **) &disp->VertexAttribs3dvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribs3dvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribs3fvNV) { + void ** procp = (void **) &disp->VertexAttribs3fvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribs3fvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribs3svNV) { + void ** procp = (void **) &disp->VertexAttribs3svNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribs3svNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribs4dvNV) { + void ** procp = (void **) &disp->VertexAttribs4dvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribs4dvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribs4fvNV) { + void ** procp = (void **) &disp->VertexAttribs4fvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribs4fvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribs4svNV) { + void ** procp = (void **) &disp->VertexAttribs4svNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribs4svNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribs4ubvNV) { + void ** procp = (void **) &disp->VertexAttribs4ubvNV; + snprintf(symboln, sizeof(symboln), "%sVertexAttribs4ubvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexBumpParameterfvATI) { + void ** procp = (void **) &disp->GetTexBumpParameterfvATI; + snprintf(symboln, sizeof(symboln), "%sGetTexBumpParameterfvATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexBumpParameterivATI) { + void ** procp = (void **) &disp->GetTexBumpParameterivATI; + snprintf(symboln, sizeof(symboln), "%sGetTexBumpParameterivATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexBumpParameterfvATI) { + void ** procp = (void **) &disp->TexBumpParameterfvATI; + snprintf(symboln, sizeof(symboln), "%sTexBumpParameterfvATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexBumpParameterivATI) { + void ** procp = (void **) &disp->TexBumpParameterivATI; + snprintf(symboln, sizeof(symboln), "%sTexBumpParameterivATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->AlphaFragmentOp1ATI) { + void ** procp = (void **) &disp->AlphaFragmentOp1ATI; + snprintf(symboln, sizeof(symboln), "%sAlphaFragmentOp1ATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->AlphaFragmentOp2ATI) { + void ** procp = (void **) &disp->AlphaFragmentOp2ATI; + snprintf(symboln, sizeof(symboln), "%sAlphaFragmentOp2ATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->AlphaFragmentOp3ATI) { + void ** procp = (void **) &disp->AlphaFragmentOp3ATI; + snprintf(symboln, sizeof(symboln), "%sAlphaFragmentOp3ATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BeginFragmentShaderATI) { + void ** procp = (void **) &disp->BeginFragmentShaderATI; + snprintf(symboln, sizeof(symboln), "%sBeginFragmentShaderATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindFragmentShaderATI) { + void ** procp = (void **) &disp->BindFragmentShaderATI; + snprintf(symboln, sizeof(symboln), "%sBindFragmentShaderATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorFragmentOp1ATI) { + void ** procp = (void **) &disp->ColorFragmentOp1ATI; + snprintf(symboln, sizeof(symboln), "%sColorFragmentOp1ATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorFragmentOp2ATI) { + void ** procp = (void **) &disp->ColorFragmentOp2ATI; + snprintf(symboln, sizeof(symboln), "%sColorFragmentOp2ATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorFragmentOp3ATI) { + void ** procp = (void **) &disp->ColorFragmentOp3ATI; + snprintf(symboln, sizeof(symboln), "%sColorFragmentOp3ATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteFragmentShaderATI) { + void ** procp = (void **) &disp->DeleteFragmentShaderATI; + snprintf(symboln, sizeof(symboln), "%sDeleteFragmentShaderATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EndFragmentShaderATI) { + void ** procp = (void **) &disp->EndFragmentShaderATI; + snprintf(symboln, sizeof(symboln), "%sEndFragmentShaderATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenFragmentShadersATI) { + void ** procp = (void **) &disp->GenFragmentShadersATI; + snprintf(symboln, sizeof(symboln), "%sGenFragmentShadersATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PassTexCoordATI) { + void ** procp = (void **) &disp->PassTexCoordATI; + snprintf(symboln, sizeof(symboln), "%sPassTexCoordATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SampleMapATI) { + void ** procp = (void **) &disp->SampleMapATI; + snprintf(symboln, sizeof(symboln), "%sSampleMapATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->SetFragmentShaderConstantATI) { + void ** procp = (void **) &disp->SetFragmentShaderConstantATI; + snprintf(symboln, sizeof(symboln), "%sSetFragmentShaderConstantATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PointParameteriNV) { + void ** procp = (void **) &disp->PointParameteriNV; + snprintf(symboln, sizeof(symboln), "%sPointParameteri", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PointParameteriNV) { + void ** procp = (void **) &disp->PointParameteriNV; + snprintf(symboln, sizeof(symboln), "%sPointParameteriNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PointParameterivNV) { + void ** procp = (void **) &disp->PointParameterivNV; + snprintf(symboln, sizeof(symboln), "%sPointParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PointParameterivNV) { + void ** procp = (void **) &disp->PointParameterivNV; + snprintf(symboln, sizeof(symboln), "%sPointParameterivNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ActiveStencilFaceEXT) { + void ** procp = (void **) &disp->ActiveStencilFaceEXT; + snprintf(symboln, sizeof(symboln), "%sActiveStencilFaceEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindVertexArrayAPPLE) { + void ** procp = (void **) &disp->BindVertexArrayAPPLE; + snprintf(symboln, sizeof(symboln), "%sBindVertexArrayAPPLE", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteVertexArraysAPPLE) { + void ** procp = (void **) &disp->DeleteVertexArraysAPPLE; + snprintf(symboln, sizeof(symboln), "%sDeleteVertexArrays", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteVertexArraysAPPLE) { + void ** procp = (void **) &disp->DeleteVertexArraysAPPLE; + snprintf(symboln, sizeof(symboln), "%sDeleteVertexArraysAPPLE", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenVertexArraysAPPLE) { + void ** procp = (void **) &disp->GenVertexArraysAPPLE; + snprintf(symboln, sizeof(symboln), "%sGenVertexArraysAPPLE", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsVertexArrayAPPLE) { + void ** procp = (void **) &disp->IsVertexArrayAPPLE; + snprintf(symboln, sizeof(symboln), "%sIsVertexArray", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsVertexArrayAPPLE) { + void ** procp = (void **) &disp->IsVertexArrayAPPLE; + snprintf(symboln, sizeof(symboln), "%sIsVertexArrayAPPLE", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramNamedParameterdvNV) { + void ** procp = (void **) &disp->GetProgramNamedParameterdvNV; + snprintf(symboln, sizeof(symboln), "%sGetProgramNamedParameterdvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetProgramNamedParameterfvNV) { + void ** procp = (void **) &disp->GetProgramNamedParameterfvNV; + snprintf(symboln, sizeof(symboln), "%sGetProgramNamedParameterfvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramNamedParameter4dNV) { + void ** procp = (void **) &disp->ProgramNamedParameter4dNV; + snprintf(symboln, sizeof(symboln), "%sProgramNamedParameter4dNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramNamedParameter4dvNV) { + void ** procp = (void **) &disp->ProgramNamedParameter4dvNV; + snprintf(symboln, sizeof(symboln), "%sProgramNamedParameter4dvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramNamedParameter4fNV) { + void ** procp = (void **) &disp->ProgramNamedParameter4fNV; + snprintf(symboln, sizeof(symboln), "%sProgramNamedParameter4fNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramNamedParameter4fvNV) { + void ** procp = (void **) &disp->ProgramNamedParameter4fvNV; + snprintf(symboln, sizeof(symboln), "%sProgramNamedParameter4fvNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PrimitiveRestartIndexNV) { + void ** procp = (void **) &disp->PrimitiveRestartIndexNV; + snprintf(symboln, sizeof(symboln), "%sPrimitiveRestartIndexNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PrimitiveRestartIndexNV) { + void ** procp = (void **) &disp->PrimitiveRestartIndexNV; + snprintf(symboln, sizeof(symboln), "%sPrimitiveRestartIndex", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->PrimitiveRestartNV) { + void ** procp = (void **) &disp->PrimitiveRestartNV; + snprintf(symboln, sizeof(symboln), "%sPrimitiveRestartNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DepthBoundsEXT) { + void ** procp = (void **) &disp->DepthBoundsEXT; + snprintf(symboln, sizeof(symboln), "%sDepthBoundsEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendEquationSeparateEXT) { + void ** procp = (void **) &disp->BlendEquationSeparateEXT; + snprintf(symboln, sizeof(symboln), "%sBlendEquationSeparate", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendEquationSeparateEXT) { + void ** procp = (void **) &disp->BlendEquationSeparateEXT; + snprintf(symboln, sizeof(symboln), "%sBlendEquationSeparateEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlendEquationSeparateEXT) { + void ** procp = (void **) &disp->BlendEquationSeparateEXT; + snprintf(symboln, sizeof(symboln), "%sBlendEquationSeparateATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindFramebufferEXT) { + void ** procp = (void **) &disp->BindFramebufferEXT; + snprintf(symboln, sizeof(symboln), "%sBindFramebuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindFramebufferEXT) { + void ** procp = (void **) &disp->BindFramebufferEXT; + snprintf(symboln, sizeof(symboln), "%sBindFramebufferEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindRenderbufferEXT) { + void ** procp = (void **) &disp->BindRenderbufferEXT; + snprintf(symboln, sizeof(symboln), "%sBindRenderbuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindRenderbufferEXT) { + void ** procp = (void **) &disp->BindRenderbufferEXT; + snprintf(symboln, sizeof(symboln), "%sBindRenderbufferEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CheckFramebufferStatusEXT) { + void ** procp = (void **) &disp->CheckFramebufferStatusEXT; + snprintf(symboln, sizeof(symboln), "%sCheckFramebufferStatus", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CheckFramebufferStatusEXT) { + void ** procp = (void **) &disp->CheckFramebufferStatusEXT; + snprintf(symboln, sizeof(symboln), "%sCheckFramebufferStatusEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteFramebuffersEXT) { + void ** procp = (void **) &disp->DeleteFramebuffersEXT; + snprintf(symboln, sizeof(symboln), "%sDeleteFramebuffers", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteFramebuffersEXT) { + void ** procp = (void **) &disp->DeleteFramebuffersEXT; + snprintf(symboln, sizeof(symboln), "%sDeleteFramebuffersEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteRenderbuffersEXT) { + void ** procp = (void **) &disp->DeleteRenderbuffersEXT; + snprintf(symboln, sizeof(symboln), "%sDeleteRenderbuffers", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DeleteRenderbuffersEXT) { + void ** procp = (void **) &disp->DeleteRenderbuffersEXT; + snprintf(symboln, sizeof(symboln), "%sDeleteRenderbuffersEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FramebufferRenderbufferEXT) { + void ** procp = (void **) &disp->FramebufferRenderbufferEXT; + snprintf(symboln, sizeof(symboln), "%sFramebufferRenderbuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FramebufferRenderbufferEXT) { + void ** procp = (void **) &disp->FramebufferRenderbufferEXT; + snprintf(symboln, sizeof(symboln), "%sFramebufferRenderbufferEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FramebufferTexture1DEXT) { + void ** procp = (void **) &disp->FramebufferTexture1DEXT; + snprintf(symboln, sizeof(symboln), "%sFramebufferTexture1D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FramebufferTexture1DEXT) { + void ** procp = (void **) &disp->FramebufferTexture1DEXT; + snprintf(symboln, sizeof(symboln), "%sFramebufferTexture1DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FramebufferTexture2DEXT) { + void ** procp = (void **) &disp->FramebufferTexture2DEXT; + snprintf(symboln, sizeof(symboln), "%sFramebufferTexture2D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FramebufferTexture2DEXT) { + void ** procp = (void **) &disp->FramebufferTexture2DEXT; + snprintf(symboln, sizeof(symboln), "%sFramebufferTexture2DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FramebufferTexture3DEXT) { + void ** procp = (void **) &disp->FramebufferTexture3DEXT; + snprintf(symboln, sizeof(symboln), "%sFramebufferTexture3D", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FramebufferTexture3DEXT) { + void ** procp = (void **) &disp->FramebufferTexture3DEXT; + snprintf(symboln, sizeof(symboln), "%sFramebufferTexture3DEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenFramebuffersEXT) { + void ** procp = (void **) &disp->GenFramebuffersEXT; + snprintf(symboln, sizeof(symboln), "%sGenFramebuffers", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenFramebuffersEXT) { + void ** procp = (void **) &disp->GenFramebuffersEXT; + snprintf(symboln, sizeof(symboln), "%sGenFramebuffersEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenRenderbuffersEXT) { + void ** procp = (void **) &disp->GenRenderbuffersEXT; + snprintf(symboln, sizeof(symboln), "%sGenRenderbuffers", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenRenderbuffersEXT) { + void ** procp = (void **) &disp->GenRenderbuffersEXT; + snprintf(symboln, sizeof(symboln), "%sGenRenderbuffersEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenerateMipmapEXT) { + void ** procp = (void **) &disp->GenerateMipmapEXT; + snprintf(symboln, sizeof(symboln), "%sGenerateMipmap", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GenerateMipmapEXT) { + void ** procp = (void **) &disp->GenerateMipmapEXT; + snprintf(symboln, sizeof(symboln), "%sGenerateMipmapEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetFramebufferAttachmentParameterivEXT) { + void ** procp = (void **) &disp->GetFramebufferAttachmentParameterivEXT; + snprintf(symboln, sizeof(symboln), "%sGetFramebufferAttachmentParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetFramebufferAttachmentParameterivEXT) { + void ** procp = (void **) &disp->GetFramebufferAttachmentParameterivEXT; + snprintf(symboln, sizeof(symboln), "%sGetFramebufferAttachmentParameterivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetRenderbufferParameterivEXT) { + void ** procp = (void **) &disp->GetRenderbufferParameterivEXT; + snprintf(symboln, sizeof(symboln), "%sGetRenderbufferParameteriv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetRenderbufferParameterivEXT) { + void ** procp = (void **) &disp->GetRenderbufferParameterivEXT; + snprintf(symboln, sizeof(symboln), "%sGetRenderbufferParameterivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsFramebufferEXT) { + void ** procp = (void **) &disp->IsFramebufferEXT; + snprintf(symboln, sizeof(symboln), "%sIsFramebuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsFramebufferEXT) { + void ** procp = (void **) &disp->IsFramebufferEXT; + snprintf(symboln, sizeof(symboln), "%sIsFramebufferEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsRenderbufferEXT) { + void ** procp = (void **) &disp->IsRenderbufferEXT; + snprintf(symboln, sizeof(symboln), "%sIsRenderbuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsRenderbufferEXT) { + void ** procp = (void **) &disp->IsRenderbufferEXT; + snprintf(symboln, sizeof(symboln), "%sIsRenderbufferEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RenderbufferStorageEXT) { + void ** procp = (void **) &disp->RenderbufferStorageEXT; + snprintf(symboln, sizeof(symboln), "%sRenderbufferStorage", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->RenderbufferStorageEXT) { + void ** procp = (void **) &disp->RenderbufferStorageEXT; + snprintf(symboln, sizeof(symboln), "%sRenderbufferStorageEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlitFramebufferEXT) { + void ** procp = (void **) &disp->BlitFramebufferEXT; + snprintf(symboln, sizeof(symboln), "%sBlitFramebuffer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BlitFramebufferEXT) { + void ** procp = (void **) &disp->BlitFramebufferEXT; + snprintf(symboln, sizeof(symboln), "%sBlitFramebufferEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BufferParameteriAPPLE) { + void ** procp = (void **) &disp->BufferParameteriAPPLE; + snprintf(symboln, sizeof(symboln), "%sBufferParameteriAPPLE", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FlushMappedBufferRangeAPPLE) { + void ** procp = (void **) &disp->FlushMappedBufferRangeAPPLE; + snprintf(symboln, sizeof(symboln), "%sFlushMappedBufferRangeAPPLE", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindFragDataLocationEXT) { + void ** procp = (void **) &disp->BindFragDataLocationEXT; + snprintf(symboln, sizeof(symboln), "%sBindFragDataLocationEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindFragDataLocationEXT) { + void ** procp = (void **) &disp->BindFragDataLocationEXT; + snprintf(symboln, sizeof(symboln), "%sBindFragDataLocation", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetFragDataLocationEXT) { + void ** procp = (void **) &disp->GetFragDataLocationEXT; + snprintf(symboln, sizeof(symboln), "%sGetFragDataLocationEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetFragDataLocationEXT) { + void ** procp = (void **) &disp->GetFragDataLocationEXT; + snprintf(symboln, sizeof(symboln), "%sGetFragDataLocation", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetUniformuivEXT) { + void ** procp = (void **) &disp->GetUniformuivEXT; + snprintf(symboln, sizeof(symboln), "%sGetUniformuivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetUniformuivEXT) { + void ** procp = (void **) &disp->GetUniformuivEXT; + snprintf(symboln, sizeof(symboln), "%sGetUniformuiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribIivEXT) { + void ** procp = (void **) &disp->GetVertexAttribIivEXT; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribIivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribIivEXT) { + void ** procp = (void **) &disp->GetVertexAttribIivEXT; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribIiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribIuivEXT) { + void ** procp = (void **) &disp->GetVertexAttribIuivEXT; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribIuivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetVertexAttribIuivEXT) { + void ** procp = (void **) &disp->GetVertexAttribIuivEXT; + snprintf(symboln, sizeof(symboln), "%sGetVertexAttribIuiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform1uiEXT) { + void ** procp = (void **) &disp->Uniform1uiEXT; + snprintf(symboln, sizeof(symboln), "%sUniform1uiEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform1uiEXT) { + void ** procp = (void **) &disp->Uniform1uiEXT; + snprintf(symboln, sizeof(symboln), "%sUniform1ui", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform1uivEXT) { + void ** procp = (void **) &disp->Uniform1uivEXT; + snprintf(symboln, sizeof(symboln), "%sUniform1uivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform1uivEXT) { + void ** procp = (void **) &disp->Uniform1uivEXT; + snprintf(symboln, sizeof(symboln), "%sUniform1uiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform2uiEXT) { + void ** procp = (void **) &disp->Uniform2uiEXT; + snprintf(symboln, sizeof(symboln), "%sUniform2uiEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform2uiEXT) { + void ** procp = (void **) &disp->Uniform2uiEXT; + snprintf(symboln, sizeof(symboln), "%sUniform2ui", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform2uivEXT) { + void ** procp = (void **) &disp->Uniform2uivEXT; + snprintf(symboln, sizeof(symboln), "%sUniform2uivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform2uivEXT) { + void ** procp = (void **) &disp->Uniform2uivEXT; + snprintf(symboln, sizeof(symboln), "%sUniform2uiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform3uiEXT) { + void ** procp = (void **) &disp->Uniform3uiEXT; + snprintf(symboln, sizeof(symboln), "%sUniform3uiEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform3uiEXT) { + void ** procp = (void **) &disp->Uniform3uiEXT; + snprintf(symboln, sizeof(symboln), "%sUniform3ui", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform3uivEXT) { + void ** procp = (void **) &disp->Uniform3uivEXT; + snprintf(symboln, sizeof(symboln), "%sUniform3uivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform3uivEXT) { + void ** procp = (void **) &disp->Uniform3uivEXT; + snprintf(symboln, sizeof(symboln), "%sUniform3uiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform4uiEXT) { + void ** procp = (void **) &disp->Uniform4uiEXT; + snprintf(symboln, sizeof(symboln), "%sUniform4uiEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform4uiEXT) { + void ** procp = (void **) &disp->Uniform4uiEXT; + snprintf(symboln, sizeof(symboln), "%sUniform4ui", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform4uivEXT) { + void ** procp = (void **) &disp->Uniform4uivEXT; + snprintf(symboln, sizeof(symboln), "%sUniform4uivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->Uniform4uivEXT) { + void ** procp = (void **) &disp->Uniform4uivEXT; + snprintf(symboln, sizeof(symboln), "%sUniform4uiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI1iEXT) { + void ** procp = (void **) &disp->VertexAttribI1iEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI1iEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI1iEXT) { + void ** procp = (void **) &disp->VertexAttribI1iEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI1i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI1ivEXT) { + void ** procp = (void **) &disp->VertexAttribI1ivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI1ivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI1ivEXT) { + void ** procp = (void **) &disp->VertexAttribI1ivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI1iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI1uiEXT) { + void ** procp = (void **) &disp->VertexAttribI1uiEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI1uiEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI1uiEXT) { + void ** procp = (void **) &disp->VertexAttribI1uiEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI1ui", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI1uivEXT) { + void ** procp = (void **) &disp->VertexAttribI1uivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI1uivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI1uivEXT) { + void ** procp = (void **) &disp->VertexAttribI1uivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI1uiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI2iEXT) { + void ** procp = (void **) &disp->VertexAttribI2iEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI2iEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI2iEXT) { + void ** procp = (void **) &disp->VertexAttribI2iEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI2i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI2ivEXT) { + void ** procp = (void **) &disp->VertexAttribI2ivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI2ivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI2ivEXT) { + void ** procp = (void **) &disp->VertexAttribI2ivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI2iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI2uiEXT) { + void ** procp = (void **) &disp->VertexAttribI2uiEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI2uiEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI2uiEXT) { + void ** procp = (void **) &disp->VertexAttribI2uiEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI2ui", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI2uivEXT) { + void ** procp = (void **) &disp->VertexAttribI2uivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI2uivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI2uivEXT) { + void ** procp = (void **) &disp->VertexAttribI2uivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI2uiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI3iEXT) { + void ** procp = (void **) &disp->VertexAttribI3iEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI3iEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI3iEXT) { + void ** procp = (void **) &disp->VertexAttribI3iEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI3i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI3ivEXT) { + void ** procp = (void **) &disp->VertexAttribI3ivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI3ivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI3ivEXT) { + void ** procp = (void **) &disp->VertexAttribI3ivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI3iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI3uiEXT) { + void ** procp = (void **) &disp->VertexAttribI3uiEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI3uiEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI3uiEXT) { + void ** procp = (void **) &disp->VertexAttribI3uiEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI3ui", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI3uivEXT) { + void ** procp = (void **) &disp->VertexAttribI3uivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI3uivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI3uivEXT) { + void ** procp = (void **) &disp->VertexAttribI3uivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI3uiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4bvEXT) { + void ** procp = (void **) &disp->VertexAttribI4bvEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4bvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4bvEXT) { + void ** procp = (void **) &disp->VertexAttribI4bvEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4bv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4iEXT) { + void ** procp = (void **) &disp->VertexAttribI4iEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4iEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4iEXT) { + void ** procp = (void **) &disp->VertexAttribI4iEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4i", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4ivEXT) { + void ** procp = (void **) &disp->VertexAttribI4ivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4ivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4ivEXT) { + void ** procp = (void **) &disp->VertexAttribI4ivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4iv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4svEXT) { + void ** procp = (void **) &disp->VertexAttribI4svEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4svEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4svEXT) { + void ** procp = (void **) &disp->VertexAttribI4svEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4sv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4ubvEXT) { + void ** procp = (void **) &disp->VertexAttribI4ubvEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4ubvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4ubvEXT) { + void ** procp = (void **) &disp->VertexAttribI4ubvEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4ubv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4uiEXT) { + void ** procp = (void **) &disp->VertexAttribI4uiEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4uiEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4uiEXT) { + void ** procp = (void **) &disp->VertexAttribI4uiEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4ui", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4uivEXT) { + void ** procp = (void **) &disp->VertexAttribI4uivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4uivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4uivEXT) { + void ** procp = (void **) &disp->VertexAttribI4uivEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4uiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4usvEXT) { + void ** procp = (void **) &disp->VertexAttribI4usvEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4usvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribI4usvEXT) { + void ** procp = (void **) &disp->VertexAttribI4usvEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribI4usv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribIPointerEXT) { + void ** procp = (void **) &disp->VertexAttribIPointerEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribIPointerEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->VertexAttribIPointerEXT) { + void ** procp = (void **) &disp->VertexAttribIPointerEXT; + snprintf(symboln, sizeof(symboln), "%sVertexAttribIPointer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FramebufferTextureLayerEXT) { + void ** procp = (void **) &disp->FramebufferTextureLayerEXT; + snprintf(symboln, sizeof(symboln), "%sFramebufferTextureLayer", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->FramebufferTextureLayerEXT) { + void ** procp = (void **) &disp->FramebufferTextureLayerEXT; + snprintf(symboln, sizeof(symboln), "%sFramebufferTextureLayerEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorMaskIndexedEXT) { + void ** procp = (void **) &disp->ColorMaskIndexedEXT; + snprintf(symboln, sizeof(symboln), "%sColorMaskIndexedEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ColorMaskIndexedEXT) { + void ** procp = (void **) &disp->ColorMaskIndexedEXT; + snprintf(symboln, sizeof(symboln), "%sColorMaski", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DisableIndexedEXT) { + void ** procp = (void **) &disp->DisableIndexedEXT; + snprintf(symboln, sizeof(symboln), "%sDisableIndexedEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->DisableIndexedEXT) { + void ** procp = (void **) &disp->DisableIndexedEXT; + snprintf(symboln, sizeof(symboln), "%sDisablei", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EnableIndexedEXT) { + void ** procp = (void **) &disp->EnableIndexedEXT; + snprintf(symboln, sizeof(symboln), "%sEnableIndexedEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EnableIndexedEXT) { + void ** procp = (void **) &disp->EnableIndexedEXT; + snprintf(symboln, sizeof(symboln), "%sEnablei", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetBooleanIndexedvEXT) { + void ** procp = (void **) &disp->GetBooleanIndexedvEXT; + snprintf(symboln, sizeof(symboln), "%sGetBooleanIndexedvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetBooleanIndexedvEXT) { + void ** procp = (void **) &disp->GetBooleanIndexedvEXT; + snprintf(symboln, sizeof(symboln), "%sGetBooleani_v", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetIntegerIndexedvEXT) { + void ** procp = (void **) &disp->GetIntegerIndexedvEXT; + snprintf(symboln, sizeof(symboln), "%sGetIntegerIndexedvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetIntegerIndexedvEXT) { + void ** procp = (void **) &disp->GetIntegerIndexedvEXT; + snprintf(symboln, sizeof(symboln), "%sGetIntegeri_v", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsEnabledIndexedEXT) { + void ** procp = (void **) &disp->IsEnabledIndexedEXT; + snprintf(symboln, sizeof(symboln), "%sIsEnabledIndexedEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->IsEnabledIndexedEXT) { + void ** procp = (void **) &disp->IsEnabledIndexedEXT; + snprintf(symboln, sizeof(symboln), "%sIsEnabledi", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClearColorIiEXT) { + void ** procp = (void **) &disp->ClearColorIiEXT; + snprintf(symboln, sizeof(symboln), "%sClearColorIiEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ClearColorIuiEXT) { + void ** procp = (void **) &disp->ClearColorIuiEXT; + snprintf(symboln, sizeof(symboln), "%sClearColorIuiEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexParameterIivEXT) { + void ** procp = (void **) &disp->GetTexParameterIivEXT; + snprintf(symboln, sizeof(symboln), "%sGetTexParameterIivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexParameterIivEXT) { + void ** procp = (void **) &disp->GetTexParameterIivEXT; + snprintf(symboln, sizeof(symboln), "%sGetTexParameterIiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexParameterIuivEXT) { + void ** procp = (void **) &disp->GetTexParameterIuivEXT; + snprintf(symboln, sizeof(symboln), "%sGetTexParameterIuivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexParameterIuivEXT) { + void ** procp = (void **) &disp->GetTexParameterIuivEXT; + snprintf(symboln, sizeof(symboln), "%sGetTexParameterIuiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexParameterIivEXT) { + void ** procp = (void **) &disp->TexParameterIivEXT; + snprintf(symboln, sizeof(symboln), "%sTexParameterIivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexParameterIivEXT) { + void ** procp = (void **) &disp->TexParameterIivEXT; + snprintf(symboln, sizeof(symboln), "%sTexParameterIiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexParameterIuivEXT) { + void ** procp = (void **) &disp->TexParameterIuivEXT; + snprintf(symboln, sizeof(symboln), "%sTexParameterIuivEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TexParameterIuivEXT) { + void ** procp = (void **) &disp->TexParameterIuivEXT; + snprintf(symboln, sizeof(symboln), "%sTexParameterIuiv", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BeginConditionalRenderNV) { + void ** procp = (void **) &disp->BeginConditionalRenderNV; + snprintf(symboln, sizeof(symboln), "%sBeginConditionalRenderNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BeginConditionalRenderNV) { + void ** procp = (void **) &disp->BeginConditionalRenderNV; + snprintf(symboln, sizeof(symboln), "%sBeginConditionalRender", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EndConditionalRenderNV) { + void ** procp = (void **) &disp->EndConditionalRenderNV; + snprintf(symboln, sizeof(symboln), "%sEndConditionalRenderNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EndConditionalRenderNV) { + void ** procp = (void **) &disp->EndConditionalRenderNV; + snprintf(symboln, sizeof(symboln), "%sEndConditionalRender", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BeginTransformFeedbackEXT) { + void ** procp = (void **) &disp->BeginTransformFeedbackEXT; + snprintf(symboln, sizeof(symboln), "%sBeginTransformFeedbackEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BeginTransformFeedbackEXT) { + void ** procp = (void **) &disp->BeginTransformFeedbackEXT; + snprintf(symboln, sizeof(symboln), "%sBeginTransformFeedback", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindBufferBaseEXT) { + void ** procp = (void **) &disp->BindBufferBaseEXT; + snprintf(symboln, sizeof(symboln), "%sBindBufferBaseEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindBufferBaseEXT) { + void ** procp = (void **) &disp->BindBufferBaseEXT; + snprintf(symboln, sizeof(symboln), "%sBindBufferBase", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindBufferOffsetEXT) { + void ** procp = (void **) &disp->BindBufferOffsetEXT; + snprintf(symboln, sizeof(symboln), "%sBindBufferOffsetEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindBufferRangeEXT) { + void ** procp = (void **) &disp->BindBufferRangeEXT; + snprintf(symboln, sizeof(symboln), "%sBindBufferRangeEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->BindBufferRangeEXT) { + void ** procp = (void **) &disp->BindBufferRangeEXT; + snprintf(symboln, sizeof(symboln), "%sBindBufferRange", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EndTransformFeedbackEXT) { + void ** procp = (void **) &disp->EndTransformFeedbackEXT; + snprintf(symboln, sizeof(symboln), "%sEndTransformFeedbackEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EndTransformFeedbackEXT) { + void ** procp = (void **) &disp->EndTransformFeedbackEXT; + snprintf(symboln, sizeof(symboln), "%sEndTransformFeedback", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTransformFeedbackVaryingEXT) { + void ** procp = (void **) &disp->GetTransformFeedbackVaryingEXT; + snprintf(symboln, sizeof(symboln), "%sGetTransformFeedbackVaryingEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTransformFeedbackVaryingEXT) { + void ** procp = (void **) &disp->GetTransformFeedbackVaryingEXT; + snprintf(symboln, sizeof(symboln), "%sGetTransformFeedbackVarying", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TransformFeedbackVaryingsEXT) { + void ** procp = (void **) &disp->TransformFeedbackVaryingsEXT; + snprintf(symboln, sizeof(symboln), "%sTransformFeedbackVaryingsEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TransformFeedbackVaryingsEXT) { + void ** procp = (void **) &disp->TransformFeedbackVaryingsEXT; + snprintf(symboln, sizeof(symboln), "%sTransformFeedbackVaryings", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProvokingVertexEXT) { + void ** procp = (void **) &disp->ProvokingVertexEXT; + snprintf(symboln, sizeof(symboln), "%sProvokingVertexEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProvokingVertexEXT) { + void ** procp = (void **) &disp->ProvokingVertexEXT; + snprintf(symboln, sizeof(symboln), "%sProvokingVertex", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetTexParameterPointervAPPLE) { + void ** procp = (void **) &disp->GetTexParameterPointervAPPLE; + snprintf(symboln, sizeof(symboln), "%sGetTexParameterPointervAPPLE", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TextureRangeAPPLE) { + void ** procp = (void **) &disp->TextureRangeAPPLE; + snprintf(symboln, sizeof(symboln), "%sTextureRangeAPPLE", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetObjectParameterivAPPLE) { + void ** procp = (void **) &disp->GetObjectParameterivAPPLE; + snprintf(symboln, sizeof(symboln), "%sGetObjectParameterivAPPLE", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ObjectPurgeableAPPLE) { + void ** procp = (void **) &disp->ObjectPurgeableAPPLE; + snprintf(symboln, sizeof(symboln), "%sObjectPurgeableAPPLE", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ObjectUnpurgeableAPPLE) { + void ** procp = (void **) &disp->ObjectUnpurgeableAPPLE; + snprintf(symboln, sizeof(symboln), "%sObjectUnpurgeableAPPLE", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ActiveProgramEXT) { + void ** procp = (void **) &disp->ActiveProgramEXT; + snprintf(symboln, sizeof(symboln), "%sActiveProgramEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->CreateShaderProgramEXT) { + void ** procp = (void **) &disp->CreateShaderProgramEXT; + snprintf(symboln, sizeof(symboln), "%sCreateShaderProgramEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->UseShaderProgramEXT) { + void ** procp = (void **) &disp->UseShaderProgramEXT; + snprintf(symboln, sizeof(symboln), "%sUseShaderProgramEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->TextureBarrierNV) { + void ** procp = (void **) &disp->TextureBarrierNV; + snprintf(symboln, sizeof(symboln), "%sTextureBarrierNV", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->StencilFuncSeparateATI) { + void ** procp = (void **) &disp->StencilFuncSeparateATI; + snprintf(symboln, sizeof(symboln), "%sStencilFuncSeparateATI", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramEnvParameters4fvEXT) { + void ** procp = (void **) &disp->ProgramEnvParameters4fvEXT; + snprintf(symboln, sizeof(symboln), "%sProgramEnvParameters4fvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->ProgramLocalParameters4fvEXT) { + void ** procp = (void **) &disp->ProgramLocalParameters4fvEXT; + snprintf(symboln, sizeof(symboln), "%sProgramLocalParameters4fvEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetQueryObjecti64vEXT) { + void ** procp = (void **) &disp->GetQueryObjecti64vEXT; + snprintf(symboln, sizeof(symboln), "%sGetQueryObjecti64vEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->GetQueryObjectui64vEXT) { + void ** procp = (void **) &disp->GetQueryObjectui64vEXT; + snprintf(symboln, sizeof(symboln), "%sGetQueryObjectui64vEXT", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EGLImageTargetRenderbufferStorageOES) { + void ** procp = (void **) &disp->EGLImageTargetRenderbufferStorageOES; + snprintf(symboln, sizeof(symboln), "%sEGLImageTargetRenderbufferStorageOES", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + if(!disp->EGLImageTargetTexture2DOES) { + void ** procp = (void **) &disp->EGLImageTargetTexture2DOES; + snprintf(symboln, sizeof(symboln), "%sEGLImageTargetTexture2DOES", symbol_prefix); + *procp = dlsym(handle, symboln); + } + + + __glapi_gentable_set_remaining_noop(disp); + + return disp; +} + diff --git a/src/mapi/glapi/sources.mak b/src/mapi/glapi/sources.mak index 0b4d8cf65df..dfc6cc6db22 100644 --- a/src/mapi/glapi/sources.mak +++ b/src/mapi/glapi/sources.mak @@ -3,6 +3,7 @@ GLAPI_SOURCES = \ glapi_dispatch.c \ glapi_entrypoint.c \ + glapi_gentable.c \ glapi_getproc.c \ glapi_nop.c \ glthread.c \ diff --git a/src/mapi/mapi/entry_x86-64_tls.h b/src/mapi/mapi/entry_x86-64_tls.h index d3b606c8ac5..72d4125a694 100644 --- a/src/mapi/mapi/entry_x86-64_tls.h +++ b/src/mapi/mapi/entry_x86-64_tls.h @@ -76,10 +76,12 @@ entry_patch_public(void) { } +static char +x86_64_entry_start[]; + mapi_func entry_get_public(int slot) { - extern char x86_64_entry_start[]; return (mapi_func) (x86_64_entry_start + slot * 32); } diff --git a/src/mapi/mapi/entry_x86_tls.h b/src/mapi/mapi/entry_x86_tls.h index 5169069a132..de918128eee 100644 --- a/src/mapi/mapi/entry_x86_tls.h +++ b/src/mapi/mapi/entry_x86_tls.h @@ -86,12 +86,13 @@ __asm__(".text"); extern unsigned long x86_current_tls(); +static char x86_entry_start[]; +static char x86_entry_end[]; + void entry_patch_public(void) { #ifndef GLX_X86_READONLY_TEXT - extern char x86_entry_start[]; - extern char x86_entry_end[]; char patch[8] = { 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, /* movl %gs:0x0, %eax */ 0x90, 0x90 /* nop's */ @@ -108,7 +109,6 @@ entry_patch_public(void) mapi_func entry_get_public(int slot) { - extern char x86_entry_start[]; return (mapi_func) (x86_entry_start + slot * 16); } diff --git a/src/mapi/mapi/entry_x86_tsd.h b/src/mapi/mapi/entry_x86_tsd.h index 1491478d470..c479c199e23 100644 --- a/src/mapi/mapi/entry_x86_tsd.h +++ b/src/mapi/mapi/entry_x86_tsd.h @@ -60,6 +60,9 @@ __asm__(".balign 32\n" #include <string.h> #include "u_execmem.h" +static const char x86_entry_start[]; +static const char x86_entry_end[]; + void entry_patch_public(void) { @@ -68,7 +71,6 @@ entry_patch_public(void) mapi_func entry_get_public(int slot) { - extern const char x86_entry_start[]; return (mapi_func) (x86_entry_start + slot * X86_ENTRY_SIZE); } @@ -84,7 +86,6 @@ entry_patch(mapi_func entry, int slot) mapi_func entry_generate(int slot) { - extern const char x86_entry_end[]; const char *code_templ = x86_entry_end - X86_ENTRY_SIZE; void *code; mapi_func entry; diff --git a/src/mesa/SConscript b/src/mesa/SConscript index fdb4d5a5814..24e2155c387 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -121,7 +121,6 @@ main_sources = [ 'main/texobj.c', 'main/texpal.c', 'main/texparam.c', - 'main/texrender.c', 'main/texstate.c', 'main/texstore.c', 'main/texturebarrier.c', @@ -174,6 +173,7 @@ swrast_sources = [ 'swrast/s_stencil.c', 'swrast/s_texcombine.c', 'swrast/s_texfilter.c', + 'swrast/s_texrender.c', 'swrast/s_triangle.c', 'swrast/s_zoom.c', ] diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index 0dbc7c3e853..8ab129dd73d 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -40,7 +40,6 @@ #include "main/texstore.h" #include "main/bufferobj.h" #include "main/fbobject.h" -#include "main/texrender.h" #include "main/samplerobj.h" #include "main/syncobj.h" #include "main/texturebarrier.h" @@ -183,8 +182,8 @@ _mesa_init_driver_functions(struct dd_function_table *driver) driver->NewFramebuffer = _mesa_new_framebuffer; driver->NewRenderbuffer = _mesa_new_soft_renderbuffer; - driver->RenderTexture = _mesa_render_texture; - driver->FinishRenderTexture = _mesa_finish_render_texture; + driver->RenderTexture = _swrast_render_texture; + driver->FinishRenderTexture = _swrast_finish_render_texture; driver->FramebufferRenderbuffer = _mesa_framebuffer_renderbuffer; driver->ValidateFramebuffer = _mesa_validate_framebuffer; diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index 979926a7e8f..0e58aeca3f5 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -2691,12 +2691,26 @@ copy_tex_image(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, GLenum format, type; GLint bpp; void *buf; + struct gl_renderbuffer *read_rb = ctx->ReadBuffer->_ColorReadBuffer; texObj = _mesa_get_current_tex_object(ctx, target); texImage = _mesa_get_tex_image(ctx, texObj, target, level); /* Choose format/type for temporary image buffer */ format = _mesa_base_tex_format(ctx, internalFormat); + + if (format == GL_LUMINANCE && + _mesa_get_format_base_format(read_rb->Format) != GL_LUMINANCE) { + /* The glReadPixels() path will convert RGB to luminance by + * summing R+G+B. glCopyTexImage() is supposed to behave as + * glCopyPixels, which doesn't do that change, and instead + * leaves it up to glTexImage which converts RGB to luminance by + * just taking the R channel. To avoid glReadPixels() trashing + * our data, use RGBA for our temporary image. + */ + format = GL_RGBA; + } + type = get_temp_image_type(ctx, format); bpp = _mesa_bytes_per_pixel(format, type); if (bpp <= 0) { diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c index 3298dbb69f5..d4af5e51026 100644 --- a/src/mesa/drivers/dri/i915/i830_texstate.c +++ b/src/mesa/drivers/dri/i915/i830_texstate.c @@ -40,7 +40,7 @@ static GLuint -translate_texture_format(GLuint mesa_format, GLuint internal_format) +translate_texture_format(GLuint mesa_format) { switch (mesa_format) { case MESA_FORMAT_L8: @@ -156,8 +156,7 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) */ i830->state.tex_offset[unit] = dst_x * intelObj->mt->cpp + dst_y * pitch; - format = translate_texture_format(firstImage->TexFormat, - firstImage->InternalFormat); + format = translate_texture_format(firstImage->TexFormat); state[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | (LOAD_TEXTURE_MAP0 << unit) | 4); diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index 19f08077599..584df82b50c 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -31,8 +31,10 @@ #include "intel_regions.h" #include "intel_tris.h" #include "intel_fbo.h" +#include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_vertex.h" +#include "swrast_setup/swrast_setup.h" #define FILE_DEBUG_FLAG DEBUG_STATE @@ -609,6 +611,8 @@ i830_set_draw_region(struct intel_context *intel, struct gl_context *ctx = &intel->ctx; struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; struct intel_renderbuffer *irb = intel_renderbuffer(rb); + struct gl_renderbuffer *drb; + struct intel_renderbuffer *idrb = NULL; GLuint value; struct i830_hw_state *state = &i830->state; uint32_t draw_x, draw_y; @@ -649,6 +653,13 @@ i830_set_draw_region(struct intel_context *intel, } state->Buffer[I830_DESTREG_DV1] = value; + drb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; + if (!drb) + drb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; + + if (drb) + idrb = intel_renderbuffer(drb); + /* We set up the drawing rectangle to be offset into the color * region's location in the miptree. If it doesn't match with * depth's offsets, we can't render to it. @@ -660,16 +671,15 @@ i830_set_draw_region(struct intel_context *intel, * can't do in general due to tiling) */ FALLBACK(intel, I830_FALLBACK_DRAW_OFFSET, - (depth_region && color_regions[0]) && - (depth_region->draw_x != color_regions[0]->draw_x || - depth_region->draw_y != color_regions[0]->draw_y)); - - if (color_regions[0]) { - draw_x = color_regions[0]->draw_x; - draw_y = color_regions[0]->draw_y; - } else if (depth_region) { - draw_x = depth_region->draw_x; - draw_y = depth_region->draw_y; + idrb && irb && (idrb->draw_x != irb->draw_x || + idrb->draw_y != irb->draw_y)); + + if (irb) { + draw_x = irb->draw_x; + draw_y = irb->draw_y; + } else if (idrb) { + draw_x = idrb->draw_x; + draw_y = idrb->draw_y; } else { draw_x = 0; draw_y = 0; @@ -707,6 +717,12 @@ i830_assert_not_dirty( struct intel_context *intel ) static void i830_invalidate_state(struct intel_context *intel, GLuint new_state) { + struct gl_context *ctx = &intel->ctx; + + _swsetup_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); + _tnl_invalidate_vertex_state(ctx, new_state); + if (new_state & _NEW_LIGHT) i830_update_provoking_vertex(&intel->ctx); } diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index 5aa2ea18048..bcf42d59969 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -39,8 +39,7 @@ static GLuint -translate_texture_format(gl_format mesa_format, GLuint internal_format, - GLenum DepthMode) +translate_texture_format(gl_format mesa_format, GLenum DepthMode) { switch (mesa_format) { case MESA_FORMAT_L8: @@ -165,7 +164,6 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) i915->state.tex_offset[unit] = 0; /* Always the origin of the miptree */ format = translate_texture_format(firstImage->TexFormat, - firstImage->InternalFormat, sampler->DepthMode); pitch = intelObj->mt->region->pitch * intelObj->mt->cpp; diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index 820feba04ba..9721a1c0e4d 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -33,8 +33,10 @@ #include "main/macros.h" #include "main/colormac.h" +#include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_vertex.h" +#include "swrast_setup/swrast_setup.h" #include "intel_batchbuffer.h" #include "intel_regions.h" @@ -561,6 +563,8 @@ i915_set_draw_region(struct intel_context *intel, struct gl_context *ctx = &intel->ctx; struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; struct intel_renderbuffer *irb = intel_renderbuffer(rb); + struct gl_renderbuffer *drb; + struct intel_renderbuffer *idrb = NULL; GLuint value; struct i915_hw_state *state = &i915->state; uint32_t draw_x, draw_y, draw_offset; @@ -609,6 +613,13 @@ i915_set_draw_region(struct intel_context *intel, } state->Buffer[I915_DESTREG_DV1] = value; + drb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; + if (!drb) + drb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; + + if (drb) + idrb = intel_renderbuffer(drb); + /* We set up the drawing rectangle to be offset into the color * region's location in the miptree. If it doesn't match with * depth's offsets, we can't render to it. @@ -620,16 +631,15 @@ i915_set_draw_region(struct intel_context *intel, * can't do in general due to tiling) */ FALLBACK(intel, I915_FALLBACK_DRAW_OFFSET, - (depth_region && color_regions[0]) && - (depth_region->draw_x != color_regions[0]->draw_x || - depth_region->draw_y != color_regions[0]->draw_y)); - - if (color_regions[0]) { - draw_x = color_regions[0]->draw_x; - draw_y = color_regions[0]->draw_y; - } else if (depth_region) { - draw_x = depth_region->draw_x; - draw_y = depth_region->draw_y; + idrb && irb && (idrb->draw_x != irb->draw_x || + idrb->draw_y != irb->draw_y)); + + if (irb) { + draw_x = irb->draw_x; + draw_y = irb->draw_y; + } else if (idrb) { + draw_x = idrb->draw_x; + draw_y = idrb->draw_y; } else { draw_x = 0; draw_y = 0; @@ -695,6 +705,16 @@ i915_is_hiz_depth_format(struct intel_context *intel, return false; } +static void +i915_invalidate_state(struct intel_context *intel, GLuint new_state) +{ + struct gl_context *ctx = &intel->ctx; + + _swsetup_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); + _tnl_invalidate_vertex_state(ctx, new_state); +} + void i915InitVtbl(struct i915_context *i915) { @@ -709,6 +729,7 @@ i915InitVtbl(struct i915_context *i915) i915->intel.vtbl.update_texture_state = i915UpdateTextureState; i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty; i915->intel.vtbl.finish_batch = intel_finish_vb; + i915->intel.vtbl.invalidate_state = i915_invalidate_state; i915->intel.vtbl.render_target_supported = i915_render_target_supported; i915->intel.vtbl.is_hiz_depth_format = i915_is_hiz_depth_format; } diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c index c7d428ba48d..d82206bae52 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.c +++ b/src/mesa/drivers/dri/i965/brw_clip.c @@ -146,15 +146,12 @@ static void compile_clip_prog( struct brw_context *brw, printf("\n"); } - /* Upload - */ - drm_intel_bo_unreference(brw->clip.prog_bo); - brw->clip.prog_bo = brw_upload_cache(&brw->cache, - BRW_CLIP_PROG, - &c.key, sizeof(c.key), - program, program_size, - &c.prog_data, sizeof(c.prog_data), - &brw->clip.prog_data); + brw_upload_cache(&brw->cache, + BRW_CLIP_PROG, + &c.key, sizeof(c.key), + program, program_size, + &c.prog_data, sizeof(c.prog_data), + &brw->clip.prog_offset, &brw->clip.prog_data); ralloc_free(mem_ctx); } @@ -271,12 +268,11 @@ static void upload_clip_prog(struct brw_context *brw) } } - drm_intel_bo_unreference(brw->clip.prog_bo); - brw->clip.prog_bo = brw_search_cache(&brw->cache, BRW_CLIP_PROG, - &key, sizeof(key), - &brw->clip.prog_data); - if (brw->clip.prog_bo == NULL) + if (!brw_search_cache(&brw->cache, BRW_CLIP_PROG, + &key, sizeof(key), + &brw->clip.prog_offset, &brw->clip.prog_data)) { compile_clip_prog( brw, &key ); + } } diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c index 6015c8cbe9f..b9efbb74c87 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_state.c +++ b/src/mesa/drivers/dri/i965/brw_clip_state.c @@ -43,11 +43,15 @@ brw_prepare_clip_unit(struct brw_context *brw) clip = brw_state_batch(brw, sizeof(*clip), 32, &brw->clip.state_offset); memset(clip, 0, sizeof(*clip)); - /* CACHE_NEW_CLIP_PROG */ + /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_CLIP_PROG */ clip->thread0.grf_reg_count = (ALIGN(brw->clip.prog_data->total_grf, 16) / 16 - 1); - /* reloc */ - clip->thread0.kernel_start_pointer = brw->clip.prog_bo->offset >> 6; + clip->thread0.kernel_start_pointer = + brw_program_reloc(brw, + brw->clip.state_offset + + offsetof(struct brw_clip_unit_state, thread0), + brw->clip.prog_offset + + (clip->thread0.grf_reg_count << 1)) >> 6; clip->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; clip->thread1.single_program_flow = 1; @@ -110,14 +114,6 @@ brw_prepare_clip_unit(struct brw_context *brw) clip->viewport_ymin = -1; clip->viewport_ymax = 1; - /* Emit clip program relocation */ - assert(brw->clip.prog_bo); - drm_intel_bo_emit_reloc(intel->batch.bo, - (brw->clip.state_offset + - offsetof(struct brw_clip_unit_state, thread0)), - brw->clip.prog_bo, clip->thread0.grf_reg_count << 1, - I915_GEM_DOMAIN_INSTRUCTION, 0); - brw->state.dirty.cache |= CACHE_NEW_CLIP_UNIT; } @@ -125,6 +121,7 @@ const struct brw_tracked_state brw_clip_unit = { .dirty = { .mesa = _NEW_TRANSFORM, .brw = (BRW_NEW_BATCH | + BRW_NEW_PROGRAM_CACHE | BRW_NEW_CURBE_OFFSETS | BRW_NEW_URB_FENCE), .cache = CACHE_NEW_CLIP_PROG diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index d6a99ab06e2..636821839a1 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -240,6 +240,8 @@ GLboolean brwCreateContext( int api, brw->emit_state_always = 0; + intel->batch.need_workaround_flush = true; + ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 621b6f8990b..a8e2b802803 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -142,7 +142,9 @@ enum brw_state_id { BRW_STATE_NR_VS_SURFACES, BRW_STATE_INDEX_BUFFER, BRW_STATE_VS_CONSTBUF, - BRW_STATE_WM_CONSTBUF + BRW_STATE_WM_CONSTBUF, + BRW_STATE_PROGRAM_CACHE, + BRW_STATE_STATE_BASE_ADDRESS, }; #define BRW_NEW_URB_FENCE (1 << BRW_STATE_URB_FENCE) @@ -172,6 +174,8 @@ enum brw_state_id { #define BRW_NEW_INDEX_BUFFER (1 << BRW_STATE_INDEX_BUFFER) #define BRW_NEW_VS_CONSTBUF (1 << BRW_STATE_VS_CONSTBUF) #define BRW_NEW_WM_CONSTBUF (1 << BRW_STATE_WM_CONSTBUF) +#define BRW_NEW_PROGRAM_CACHE (1 << BRW_STATE_PROGRAM_CACHE) +#define BRW_NEW_STATE_BASE_ADDRESS (1 << BRW_STATE_STATE_BASE_ADDRESS) struct brw_state_flags { /** State update flags signalled by mesa internals */ @@ -363,9 +367,11 @@ struct brw_cache_item { /** 32-bit hash of the key data */ GLuint hash; GLuint key_size; /* for variable-sized keys */ + GLuint aux_size; const void *key; - drm_intel_bo *bo; + uint32_t offset; + uint32_t size; struct brw_cache_item *next; }; @@ -376,14 +382,11 @@ struct brw_cache { struct brw_context *brw; struct brw_cache_item **items; + drm_intel_bo *bo; GLuint size, n_items; - char *name[BRW_MAX_CACHE]; - - /* Record of the last BOs chosen for each cache_id. Used to set - * brw->state.dirty.cache when a new cache item is chosen. - */ - drm_intel_bo *last_bo[BRW_MAX_CACHE]; + uint32_t next_offset; + bool bo_used_by_gpu; }; @@ -634,8 +637,9 @@ struct brw_context struct brw_vs_prog_data *prog_data; int8_t *constant_map; /* variable array following prog_data */ - drm_intel_bo *prog_bo; drm_intel_bo *const_bo; + /** Offset in the program cache to the VS program */ + uint32_t prog_offset; uint32_t state_offset; /** Binding table of pointers to surf_bo entries */ @@ -651,14 +655,16 @@ struct brw_context struct brw_gs_prog_data *prog_data; GLboolean prog_active; + /** Offset in the program cache to the CLIP program pre-gen6 */ + uint32_t prog_offset; uint32_t state_offset; - drm_intel_bo *prog_bo; } gs; struct { struct brw_clip_prog_data *prog_data; - drm_intel_bo *prog_bo; + /** Offset in the program cache to the CLIP program pre-gen6 */ + uint32_t prog_offset; /* Offset in the batch to the CLIP state on pre-gen6. */ uint32_t state_offset; @@ -673,7 +679,8 @@ struct brw_context struct { struct brw_sf_prog_data *prog_data; - drm_intel_bo *prog_bo; + /** Offset in the program cache to the CLIP program pre-gen6 */ + uint32_t prog_offset; uint32_t state_offset; uint32_t vp_offset; } sf; @@ -700,12 +707,14 @@ struct brw_context GLuint sampler_count; uint32_t sampler_offset; + /** Offset in the program cache to the WM program */ + uint32_t prog_offset; + /** Binding table of pointers to surf_bo entries */ uint32_t bind_bo_offset; uint32_t surf_offset[BRW_WM_MAX_SURF]; uint32_t state_offset; /* offset in batchbuffer to pre-gen6 WM state */ - drm_intel_bo *prog_bo; drm_intel_bo *const_bo; /* pull constant buffer. */ /** * This is offset in the batch to the push constants on gen6. @@ -717,9 +726,6 @@ struct brw_context struct { - /* gen4 */ - drm_intel_bo *prog_bo; - uint32_t state_offset; uint32_t blend_state_offset; uint32_t depth_stencil_state_offset; @@ -874,6 +880,26 @@ brw_register_blocks(int reg_count) return ALIGN(reg_count, 16) / 16 - 1; } +static inline uint32_t +brw_program_reloc(struct brw_context *brw, uint32_t state_offset, + uint32_t prog_offset) +{ + struct intel_context *intel = &brw->intel; + + if (intel->gen >= 5) { + /* Using state base address. */ + return prog_offset; + } + + drm_intel_bo_emit_reloc(intel->batch.bo, + state_offset, + brw->cache.bo, + prog_offset, + I915_GEM_DOMAIN_INSTRUCTION, 0); + + return brw->cache.bo->offset + prog_offset; +} + GLboolean brw_do_cubemap_normalize(struct exec_list *instructions); #endif diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 6144f0a2bce..bdb5b672899 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -177,6 +177,8 @@ static void brw_emit_prim(struct brw_context *brw, OUT_BATCH(base_vertex_location); ADVANCE_BATCH(); + intel->batch.need_workaround_flush = true; + if (intel->always_flush_cache) { intel_batchbuffer_emit_mi_flush(intel); } @@ -434,6 +436,7 @@ void brw_draw_prims( struct gl_context *ctx, */ if (!retval) { _swsetup_Wakeup(ctx); + _tnl_wakeup(ctx); _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); } diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 3cc33720486..32a1d297479 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -207,6 +207,10 @@ static GLuint get_surface_type( GLenum type, GLuint size, case GL_UNSIGNED_INT: return uint_types_scale[size]; case GL_UNSIGNED_SHORT: return ushort_types_scale[size]; case GL_UNSIGNED_BYTE: return ubyte_types_scale[size]; + /* This produces GL_FIXED inputs as values between INT32_MIN and + * INT32_MAX, which will be scaled down by 1/65536 by the VS. + */ + case GL_FIXED: return int_types_scale[size]; default: assert(0); return 0; } } @@ -225,6 +229,7 @@ static GLuint get_size( GLenum type ) case GL_UNSIGNED_INT: return sizeof(GLuint); case GL_UNSIGNED_SHORT: return sizeof(GLushort); case GL_UNSIGNED_BYTE: return sizeof(GLubyte); + case GL_FIXED: return sizeof(GLuint); default: assert(0); return 0; } } @@ -273,6 +278,7 @@ static void brw_prepare_vertices(struct brw_context *brw) { struct gl_context *ctx = &brw->intel.ctx; struct intel_context *intel = intel_context(ctx); + /* CACHE_NEW_VS_PROG */ GLbitfield vs_inputs = brw->vs.prog_data->inputs_read; const unsigned char *ptr = NULL; GLuint interleaved = 0, total_size = 0; @@ -494,6 +500,8 @@ static void brw_prepare_vertices(struct brw_context *brw) break; d = brw->vb.buffers[i].offset - brw->vb.current_buffers[i].offset; + if (d < 0) + break; if (i == 0) delta = d / brw->vb.current_buffers[i].stride; if (delta * brw->vb.current_buffers[i].stride != d) @@ -641,7 +649,7 @@ const struct brw_tracked_state brw_vertices = { .dirty = { .mesa = 0, .brw = BRW_NEW_BATCH | BRW_NEW_VERTICES, - .cache = 0, + .cache = CACHE_NEW_VS_PROG, }, .prepare = brw_prepare_vertices, .emit = brw_emit_vertices, diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 09033aecd7c..b5ea943387d 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -100,7 +100,7 @@ fs_visitor::fail(const char *format, ...) this->fail_msg = msg; if (INTEL_DEBUG & DEBUG_WM) { - fprintf(stderr, msg); + fprintf(stderr, "%s", msg); } } @@ -1533,6 +1533,8 @@ fs_visitor::run() this->result = reg_undef; ir->accept(this); } + if (failed) + return false; emit_fb_writes(); @@ -1684,6 +1686,9 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog) key.clamp_fragment_color = true; for (int i = 0; i < BRW_MAX_TEX_UNIT; i++) { + if (fp->Base.ShadowSamplers & (1 << i)) + key.compare_funcs[i] = GL_LESS; + /* FINISHME: depth compares might use (0,0,0,W) for example */ key.tex_swizzles[i] = SWIZZLE_XYZW; } @@ -1697,14 +1702,12 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog) key.program_string_id = bfp->id; - drm_intel_bo *old_prog_bo = brw->wm.prog_bo; + uint32_t old_prog_offset = brw->wm.prog_offset; struct brw_wm_prog_data *old_prog_data = brw->wm.prog_data; - brw->wm.prog_bo = NULL; bool success = do_wm_prog(brw, prog, bfp, &key); - drm_intel_bo_unreference(brw->wm.prog_bo); - brw->wm.prog_bo = old_prog_bo; + brw->wm.prog_offset = old_prog_offset; brw->wm.prog_data = old_prog_data; return success; diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 7570dda1024..2bf850e5dea 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -441,6 +441,8 @@ public: void visit(ir_function *ir); void visit(ir_function_signature *ir); + void swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler); + fs_inst *emit(fs_inst inst); fs_inst *emit(int opcode) diff --git a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp index 7f3f52854d2..46677a6f2ef 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp @@ -191,6 +191,8 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir) case ir_unop_log: case ir_unop_exp2: case ir_unop_log2: + case ir_unop_i2u: + case ir_unop_u2i: case ir_unop_f2i: case ir_unop_i2f: case ir_unop_f2b: diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp index 6b7c434949c..1d89b8f1d11 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp @@ -273,7 +273,8 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src) } break; case FS_OPCODE_TXD: - assert(!"TXD isn't supported on gen5+ yet."); + /* There is no sample_d_c message; comparisons are done manually */ + msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_DERIVS; break; } } else { @@ -311,7 +312,9 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src) } break; case FS_OPCODE_TXD: - assert(!"TXD isn't supported on gen4 yet."); + /* There is no sample_d_c message; comparisons are done manually */ + assert(inst->mlen == 7 || inst->mlen == 10); + msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS; break; } } diff --git a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp index f88b1316775..b4689d2c293 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp @@ -101,7 +101,6 @@ fs_visitor::assign_regs() * for reg_width == 2. */ int reg_width = c->dispatch_width / 8; - int last_grf = 0; int hw_reg_mapping[this->virtual_grf_next + 1]; int first_assigned_grf = ALIGN(this->first_non_payload_grf, reg_width); int base_reg_count = (BRW_MAX_GRF - first_assigned_grf) / reg_width; @@ -263,6 +262,7 @@ fs_visitor::assign_regs() * regs in the register classes back down to real hardware reg * numbers. */ + this->grf_used = first_assigned_grf; hw_reg_mapping[0] = 0; /* unused */ for (int i = 1; i < this->virtual_grf_next; i++) { int reg = ra_get_node_reg(g, i); @@ -278,8 +278,9 @@ fs_visitor::assign_regs() assert(hw_reg >= 0); hw_reg_mapping[i] = first_assigned_grf + hw_reg * reg_width; - last_grf = MAX2(last_grf, - hw_reg_mapping[i] + this->virtual_grf_sizes[i] - 1); + this->grf_used = MAX2(this->grf_used, + hw_reg_mapping[i] + this->virtual_grf_sizes[i] * + reg_width); } foreach_iter(exec_list_iterator, iter, this->instructions) { @@ -290,8 +291,6 @@ fs_visitor::assign_regs() assign_reg(hw_reg_mapping, &inst->src[1], reg_width); } - this->grf_used = last_grf + reg_width; - ralloc_free(g); ralloc_free(regs); diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index b4857871c78..9091014976b 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -349,6 +349,14 @@ fs_visitor::visit(ir_expression *ir) emit_math(FS_OPCODE_RSQ, this->result, op[0]); break; + case ir_unop_i2u: + op[0].type = BRW_REGISTER_TYPE_UD; + this->result = op[0]; + break; + case ir_unop_u2i: + op[0].type = BRW_REGISTER_TYPE_D; + this->result = op[0]; + break; case ir_unop_i2f: case ir_unop_b2f: case ir_unop_b2i: @@ -549,7 +557,7 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate, /* g0 header. */ mlen = 1; - if (ir->shadow_comparitor) { + if (ir->shadow_comparitor && ir->op != ir_txd) { for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate); @@ -595,7 +603,42 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate, /* gen4's SIMD8 sampler always has the slots for u,v,r present. */ mlen += 3; } else if (ir->op == ir_txd) { - assert(!"TXD isn't supported on gen4 yet."); + ir->lod_info.grad.dPdx->accept(this); + fs_reg dPdx = this->result; + + ir->lod_info.grad.dPdy->accept(this); + fs_reg dPdy = this->result; + + for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { + emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate); + coordinate.reg_offset++; + } + /* the slots for u and v are always present, but r is optional */ + mlen += MAX2(ir->coordinate->type->vector_elements, 2); + + /* P = u, v, r + * dPdx = dudx, dvdx, drdx + * dPdy = dudy, dvdy, drdy + * + * 2-arg: dudx dvdx dudy dvdy + * dPdx.x dPdx.y dPdy.x dPdy.y + * m4 m5 m6 m7 + * + * 3-arg: dudx dvdx drdx dudy dvdy drdy + * dPdx.x dPdx.y dPdx.z dPdy.x dPdy.y dPdy.z + * m5 m6 m7 m8 m9 m10 + */ + for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) { + emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx); + dPdx.reg_offset++; + mlen++; + } + + for (int i = 0; i < ir->lod_info.grad.dPdy->type->vector_elements; i++) { + emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy); + dPdy.reg_offset++; + mlen++; + } } else { /* Oh joy. gen4 doesn't have SIMD8 non-shadow-compare bias/lod * instructions. We'll need to do SIMD16 here. @@ -709,7 +752,7 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, } mlen += ir->coordinate->type->vector_elements * reg_width; - if (ir->shadow_comparitor) { + if (ir->shadow_comparitor && ir->op != ir_txd) { mlen = MAX2(mlen, header_present + 4 * reg_width); this->result = reg_undef; @@ -742,7 +785,37 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, inst = emit(FS_OPCODE_TXL, dst); break; - case ir_txd: + case ir_txd: { + ir->lod_info.grad.dPdx->accept(this); + fs_reg dPdx = this->result; + + ir->lod_info.grad.dPdy->accept(this); + fs_reg dPdy = this->result; + + mlen = MAX2(mlen, header_present + 4 * reg_width); /* skip over 'ai' */ + + /** + * P = u, v, r + * dPdx = dudx, dvdx, drdx + * dPdy = dudy, dvdy, drdy + * + * Load up these values: + * - dudx dudy dvdx dvdy drdx drdy + * - dPdx.x dPdy.x dPdx.y dPdy.y dPdx.z dPdy.z + */ + for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) { + emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx); + dPdx.reg_offset++; + mlen += reg_width; + + emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy); + dPdy.reg_offset++; + mlen += reg_width; + } + + inst = emit(FS_OPCODE_TXD, dst); + break; + } case ir_txf: assert(!"GLSL 1.30 features unsupported"); break; @@ -776,7 +849,7 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, base_mrf--; } - if (ir->shadow_comparitor) { + if (ir->shadow_comparitor && ir->op != ir_txd) { ir->shadow_comparitor->accept(this); emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); mlen += reg_width; @@ -796,20 +869,52 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result); mlen += reg_width; break; - case ir_txd: + case ir_txd: { + if (c->dispatch_width == 16) + fail("Gen7 does not support sample_d/sample_d_c in SIMD16 mode."); + + ir->lod_info.grad.dPdx->accept(this); + fs_reg dPdx = this->result; + + ir->lod_info.grad.dPdy->accept(this); + fs_reg dPdy = this->result; + + /* Load dPdx and the coordinate together: + * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z + */ + for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { + fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), + coordinate); + if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) + inst->saturate = true; + coordinate.reg_offset++; + mlen += reg_width; + + emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx); + dPdx.reg_offset++; + mlen += reg_width; + + emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy); + dPdy.reg_offset++; + mlen += reg_width; + } + break; + } case ir_txf: assert(!"GLSL 1.30 features unsupported"); break; } - /* Set up the coordinate */ - for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { - fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), - coordinate); - if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) - inst->saturate = true; - coordinate.reg_offset++; - mlen += reg_width; + /* Set up the coordinate (except for TXD where it was done earlier) */ + if (ir->op != ir_txd) { + for (int i = 0; i < ir->coordinate->type->vector_elements; i++) { + fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), + coordinate); + if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler)) + inst->saturate = true; + coordinate.reg_offset++; + mlen += reg_width; + } } /* Generate the SEND */ @@ -835,9 +940,24 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate, void fs_visitor::visit(ir_texture *ir) { - int sampler; fs_inst *inst = NULL; + int sampler = _mesa_get_sampler_uniform_value(ir->sampler, prog, &fp->Base); + sampler = fp->Base.SamplerUnits[sampler]; + + /* Our hardware doesn't have a sample_d_c message, so shadow compares + * for textureGrad/TXD need to be emulated with instructions. + */ + bool hw_compare_supported = ir->op != ir_txd; + if (ir->shadow_comparitor && !hw_compare_supported) { + assert(c->key.compare_funcs[sampler] != GL_NONE); + /* No need to even sample for GL_ALWAYS or GL_NEVER...bail early */ + if (c->key.compare_funcs[sampler] == GL_ALWAYS) + return swizzle_result(ir, fs_reg(1.0f), sampler); + else if (c->key.compare_funcs[sampler] == GL_NEVER) + return swizzle_result(ir, fs_reg(0.0f), sampler); + } + this->result = reg_undef; ir->coordinate->accept(this); fs_reg coordinate = this->result; @@ -876,11 +996,6 @@ fs_visitor::visit(ir_texture *ir) /* Should be lowered by do_lower_texture_projection */ assert(!ir->projector); - sampler = _mesa_get_sampler_uniform_value(ir->sampler, - prog, - &fp->Base); - sampler = fp->Base.SamplerUnits[sampler]; - /* The 965 requires the EU to do the normalization of GL rectangle * texture coordinates. We use the program parameter state * tracking to get the scaling factor. @@ -951,20 +1066,69 @@ fs_visitor::visit(ir_texture *ir) inst->sampler = sampler; - this->result = dst; + if (ir->shadow_comparitor) { + if (hw_compare_supported) { + inst->shadow_compare = true; + } else { + ir->shadow_comparitor->accept(this); + fs_reg ref = this->result; + + fs_reg value = dst; + dst = fs_reg(this, glsl_type::vec4_type); + + /* FINISHME: This needs to be done pre-filtering. */ + + uint32_t conditional = 0; + switch (c->key.compare_funcs[sampler]) { + /* GL_ALWAYS and GL_NEVER were handled at the top of the function */ + case GL_LESS: conditional = BRW_CONDITIONAL_L; break; + case GL_GREATER: conditional = BRW_CONDITIONAL_G; break; + case GL_LEQUAL: conditional = BRW_CONDITIONAL_LE; break; + case GL_GEQUAL: conditional = BRW_CONDITIONAL_GE; break; + case GL_EQUAL: conditional = BRW_CONDITIONAL_EQ; break; + case GL_NOTEQUAL: conditional = BRW_CONDITIONAL_NEQ; break; + default: assert(!"Should not get here: bad shadow compare function"); + } + + /* Use conditional moves to load 0 or 1 as the result */ + this->current_annotation = "manual shadow comparison"; + for (int i = 0; i < 4; i++) { + inst = emit(BRW_OPCODE_MOV, dst, fs_reg(0.0f)); + + inst = emit(BRW_OPCODE_CMP, reg_null_f, ref, value); + inst->conditional_mod = conditional; + + inst = emit(BRW_OPCODE_MOV, dst, fs_reg(1.0f)); + inst->predicated = true; - if (ir->shadow_comparitor) - inst->shadow_compare = true; + dst.reg_offset++; + value.reg_offset++; + } + dst.reg_offset = 0; + } + } + + swizzle_result(ir, dst, sampler); +} + +/** + * Swizzle the result of a texture result. This is necessary for + * EXT_texture_swizzle as well as DEPTH_TEXTURE_MODE for shadow comparisons. + */ +void +fs_visitor::swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler) +{ + this->result = orig_val; if (ir->type == glsl_type::float_type) { /* Ignore DEPTH_TEXTURE_MODE swizzling. */ assert(ir->sampler->type->sampler_shadow); - } else if (c->key.tex_swizzles[inst->sampler] != SWIZZLE_NOOP) { - fs_reg swizzle_dst = fs_reg(this, glsl_type::vec4_type); + } else if (c->key.tex_swizzles[sampler] != SWIZZLE_NOOP) { + fs_reg swizzled_result = fs_reg(this, glsl_type::vec4_type); for (int i = 0; i < 4; i++) { - int swiz = GET_SWZ(c->key.tex_swizzles[inst->sampler], i); - fs_reg l = swizzle_dst; + int swiz = GET_SWZ(c->key.tex_swizzles[sampler], i); + fs_reg l = swizzled_result; l.reg_offset += i; if (swiz == SWIZZLE_ZERO) { @@ -972,12 +1136,12 @@ fs_visitor::visit(ir_texture *ir) } else if (swiz == SWIZZLE_ONE) { emit(BRW_OPCODE_MOV, l, fs_reg(1.0f)); } else { - fs_reg r = dst; - r.reg_offset += GET_SWZ(c->key.tex_swizzles[inst->sampler], i); + fs_reg r = orig_val; + r.reg_offset += GET_SWZ(c->key.tex_swizzles[sampler], i); emit(BRW_OPCODE_MOV, l, r); } } - this->result = swizzle_dst; + this->result = swizzled_result; } } @@ -1466,7 +1630,7 @@ fs_visitor::emit_dummy_fs() fs_inst *write; write = emit(FS_OPCODE_FB_WRITE, fs_reg(0), fs_reg(0)); - write->base_mrf = 0; + write->base_mrf = 2; } /* The register location here is relative to the start of the URB @@ -1627,7 +1791,7 @@ fs_visitor::emit_fb_writes() { this->current_annotation = "FB write header"; GLboolean header_present = GL_TRUE; - int nr = 0; + int nr = 2; int reg_width = c->dispatch_width / 8; if (intel->gen >= 6 && @@ -1637,7 +1801,7 @@ fs_visitor::emit_fb_writes() } if (header_present) { - /* m0, m1 header */ + /* m2, m3 header */ nr += 2; } @@ -1706,7 +1870,7 @@ fs_visitor::emit_fb_writes() fs_inst *inst = emit(FS_OPCODE_FB_WRITE); inst->target = target; - inst->base_mrf = 0; + inst->base_mrf = 2; inst->mlen = nr; if (target == c->key.nr_color_regions - 1) inst->eot = true; @@ -1724,7 +1888,7 @@ fs_visitor::emit_fb_writes() } fs_inst *inst = emit(FS_OPCODE_FB_WRITE); - inst->base_mrf = 0; + inst->base_mrf = 2; inst->mlen = nr; inst->eot = true; inst->header_present = header_present; diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c index 001cd62f8ca..3171e97d7af 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.c +++ b/src/mesa/drivers/dri/i965/brw_gs.c @@ -121,14 +121,11 @@ static void compile_gs_prog( struct brw_context *brw, printf("\n"); } - /* Upload - */ - drm_intel_bo_unreference(brw->gs.prog_bo); - brw->gs.prog_bo = brw_upload_cache(&brw->cache, BRW_GS_PROG, - &c.key, sizeof(c.key), - program, program_size, - &c.prog_data, sizeof(c.prog_data), - &brw->gs.prog_data); + brw_upload_cache(&brw->cache, BRW_GS_PROG, + &c.key, sizeof(c.key), + program, program_size, + &c.prog_data, sizeof(c.prog_data), + &brw->gs.prog_offset, &brw->gs.prog_data); ralloc_free(mem_ctx); } @@ -189,15 +186,12 @@ static void prepare_gs_prog(struct brw_context *brw) brw->gs.prog_active = key.need_gs_prog; } - drm_intel_bo_unreference(brw->gs.prog_bo); - brw->gs.prog_bo = NULL; - if (brw->gs.prog_active) { - brw->gs.prog_bo = brw_search_cache(&brw->cache, BRW_GS_PROG, - &key, sizeof(key), - &brw->gs.prog_data); - if (brw->gs.prog_bo == NULL) + if (!brw_search_cache(&brw->cache, BRW_GS_PROG, + &key, sizeof(key), + &brw->gs.prog_offset, &brw->gs.prog_data)) { compile_gs_prog( brw, &key ); + } } } diff --git a/src/mesa/drivers/dri/i965/brw_gs_state.c b/src/mesa/drivers/dri/i965/brw_gs_state.c index 542874b7706..bbfefcd816a 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_state.c +++ b/src/mesa/drivers/dri/i965/brw_gs_state.c @@ -45,12 +45,17 @@ brw_prepare_gs_unit(struct brw_context *brw) memset(gs, 0, sizeof(*gs)); - /* CACHE_NEW_GS_PROG */ + /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_GS_PROG */ if (brw->gs.prog_active) { gs->thread0.grf_reg_count = (ALIGN(brw->gs.prog_data->total_grf, 16) / 16 - 1); - /* reloc */ - gs->thread0.kernel_start_pointer = brw->gs.prog_bo->offset >> 6; + + gs->thread0.kernel_start_pointer = + brw_program_reloc(brw, + brw->gs.state_offset + + offsetof(struct brw_gs_unit_state, thread0), + brw->gs.prog_offset + + (gs->thread0.grf_reg_count << 1)) >> 6; gs->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; gs->thread1.single_program_flow = 1; @@ -69,13 +74,6 @@ brw_prepare_gs_unit(struct brw_context *brw) gs->thread4.max_threads = 1; else gs->thread4.max_threads = 0; - - /* Emit GS program relocation */ - drm_intel_bo_emit_reloc(intel->batch.bo, - (brw->gs.state_offset + - offsetof(struct brw_gs_unit_state, thread0)), - brw->gs.prog_bo, gs->thread0.grf_reg_count << 1, - I915_GEM_DOMAIN_INSTRUCTION, 0); } if (intel->gen == 5) @@ -91,6 +89,7 @@ const struct brw_tracked_state brw_gs_unit = { .dirty = { .mesa = 0, .brw = (BRW_NEW_BATCH | + BRW_NEW_PROGRAM_CACHE | BRW_NEW_CURBE_OFFSETS | BRW_NEW_URB_FENCE), .cache = CACHE_NEW_GS_PROG diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index a6de28b3add..033c77cd321 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -87,10 +87,11 @@ static void upload_binding_table_pointers(struct brw_context *brw) const struct brw_tracked_state brw_binding_table_pointers = { .dirty = { .mesa = 0, - .brw = BRW_NEW_BATCH - | BRW_NEW_VS_BINDING_TABLE - | BRW_NEW_GS_BINDING_TABLE - | BRW_NEW_PS_BINDING_TABLE, + .brw = (BRW_NEW_BATCH | + BRW_NEW_STATE_BASE_ADDRESS | + BRW_NEW_VS_BINDING_TABLE | + BRW_NEW_GS_BINDING_TABLE | + BRW_NEW_PS_BINDING_TABLE), .cache = 0, }, .emit = upload_binding_table_pointers, @@ -122,10 +123,11 @@ static void upload_gen6_binding_table_pointers(struct brw_context *brw) const struct brw_tracked_state gen6_binding_table_pointers = { .dirty = { .mesa = 0, - .brw = BRW_NEW_BATCH - | BRW_NEW_VS_BINDING_TABLE - | BRW_NEW_GS_BINDING_TABLE - | BRW_NEW_PS_BINDING_TABLE, + .brw = (BRW_NEW_BATCH | + BRW_NEW_STATE_BASE_ADDRESS | + BRW_NEW_VS_BINDING_TABLE | + BRW_NEW_GS_BINDING_TABLE | + BRW_NEW_PS_BINDING_TABLE), .cache = 0, }, .emit = upload_gen6_binding_table_pointers, @@ -180,7 +182,9 @@ static void upload_psp_urb_cbs(struct brw_context *brw ) const struct brw_tracked_state brw_psp_urb_cbs = { .dirty = { .mesa = 0, - .brw = BRW_NEW_URB_FENCE | BRW_NEW_BATCH, + .brw = (BRW_NEW_URB_FENCE | + BRW_NEW_BATCH | + BRW_NEW_STATE_BASE_ADDRESS), .cache = (CACHE_NEW_VS_UNIT | CACHE_NEW_GS_UNIT | CACHE_NEW_GS_PROG | @@ -219,20 +223,20 @@ static void emit_depthbuffer(struct brw_context *brw) struct intel_region *hiz_region = depth_irb ? depth_irb->hiz_region : NULL; unsigned int len; - /* - * If depth and stencil buffers are identical, then don't use separate - * stencil. + /* 3DSTATE_DEPTH_BUFFER, 3DSTATE_STENCIL_BUFFER are both + * non-pipelined state that will need the PIPE_CONTROL workaround. */ - if (depth_irb && depth_irb == stencil_irb) { - stencil_irb = NULL; - } + if (intel->gen == 6) + intel_emit_post_sync_nonzero_flush(intel); /* - * If stencil buffer uses combined depth/stencil format, but no depth buffer - * is attached, then use stencil buffer as depth buffer. + * If either depth or stencil buffer has packed depth/stencil format, + * then don't use separate stencil. Emit only a depth buffer. */ - if (!depth_irb && stencil_irb - && stencil_irb->Base.Format == MESA_FORMAT_S8_Z24) { + if (depth_irb && depth_irb->Base.Format == MESA_FORMAT_S8_Z24) { + stencil_irb = NULL; + } else if (!depth_irb && stencil_irb + && stencil_irb->Base.Format == MESA_FORMAT_S8_Z24) { depth_irb = stencil_irb; stencil_irb = NULL; } @@ -328,7 +332,7 @@ static void emit_depthbuffer(struct brw_context *brw) return; } - offset = intel_region_tile_offsets(region, &tile_x, &tile_y); + offset = intel_renderbuffer_tile_offsets(depth_irb, &tile_x, &tile_y); assert(intel->gen < 6 || region->tiling == I915_TILING_Y); assert(!hiz_region || region->tiling == I915_TILING_Y); @@ -361,26 +365,48 @@ static void emit_depthbuffer(struct brw_context *brw) ADVANCE_BATCH(); } - /* Emit hiz buffer. */ if (hiz_region || stencil_irb) { - BEGIN_BATCH(3); - OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2)); - OUT_BATCH(hiz_region->pitch * hiz_region->cpp - 1); - OUT_RELOC(hiz_region->buffer, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - 0); - ADVANCE_BATCH(); - } + /* + * In the 3DSTATE_DEPTH_BUFFER batch emitted above, the 'separate + * stencil enable' and 'hiz enable' bits were set. Therefore we must + * emit 3DSTATE_HIER_DEPTH_BUFFER and 3DSTATE_STENCIL_BUFFER. Even if + * there is no stencil buffer, 3DSTATE_STENCIL_BUFFER must be emitted; + * failure to do so causes hangs on gen5 and a stall on gen6. + */ - /* Emit stencil buffer. */ - if (hiz_region || stencil_irb) { - BEGIN_BATCH(3); - OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2)); - OUT_BATCH(stencil_irb->region->pitch * stencil_irb->region->cpp - 1); - OUT_RELOC(stencil_irb->region->buffer, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - 0); - ADVANCE_BATCH(); + /* Emit hiz buffer. */ + if (hiz_region) { + BEGIN_BATCH(3); + OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2)); + OUT_BATCH(hiz_region->pitch * hiz_region->cpp - 1); + OUT_RELOC(hiz_region->buffer, + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, + 0); + ADVANCE_BATCH(); + } else { + BEGIN_BATCH(3); + OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2)); + OUT_BATCH(0); + OUT_BATCH(0); + ADVANCE_BATCH(); + } + + /* Emit stencil buffer. */ + if (stencil_irb) { + BEGIN_BATCH(3); + OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2)); + OUT_BATCH(stencil_irb->region->pitch * stencil_irb->region->cpp - 1); + OUT_RELOC(stencil_irb->region->buffer, + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, + 0); + ADVANCE_BATCH(); + } else { + BEGIN_BATCH(3); + OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2)); + OUT_BATCH(0); + OUT_BATCH(0); + ADVANCE_BATCH(); + } } /* @@ -392,6 +418,9 @@ static void emit_depthbuffer(struct brw_context *brw) * when HiZ is enabled and the DEPTH_BUFFER_STATE changes. */ if (intel->gen >= 6 || hiz_region) { + if (intel->gen == 6) + intel_emit_post_sync_nonzero_flush(intel); + BEGIN_BATCH(2); OUT_BATCH(_3DSTATE_CLEAR_PARAMS << 16 | (2 - 2)); OUT_BATCH(0); @@ -424,6 +453,9 @@ static void upload_polygon_stipple(struct brw_context *brw) if (!ctx->Polygon.StippleFlag) return; + if (intel->gen == 6) + intel_emit_post_sync_nonzero_flush(intel); + BEGIN_BATCH(33); OUT_BATCH(_3DSTATE_POLY_STIPPLE_PATTERN << 16 | (33 - 2)); @@ -467,6 +499,9 @@ static void upload_polygon_stipple_offset(struct brw_context *brw) if (!ctx->Polygon.StippleFlag) return; + if (intel->gen == 6) + intel_emit_post_sync_nonzero_flush(intel); + BEGIN_BATCH(2); OUT_BATCH(_3DSTATE_POLY_STIPPLE_OFFSET << 16 | (2-2)); @@ -507,6 +542,9 @@ static void upload_aa_line_parameters(struct brw_context *brw) if (!ctx->Line.SmoothFlag || !brw->has_aa_line_parameters) return; + if (intel->gen == 6) + intel_emit_post_sync_nonzero_flush(intel); + OUT_BATCH(_3DSTATE_AA_LINE_PARAMETERS << 16 | (3 - 2)); /* use legacy aa line coverage computation */ OUT_BATCH(0); @@ -537,6 +575,9 @@ static void upload_line_stipple(struct brw_context *brw) if (!ctx->Line.StippleFlag) return; + if (intel->gen == 6) + intel_emit_post_sync_nonzero_flush(intel); + BEGIN_BATCH(3); OUT_BATCH(_3DSTATE_LINE_STIPPLE_PATTERN << 16 | (3 - 2)); OUT_BATCH(ctx->Line.StipplePattern); @@ -564,6 +605,10 @@ static void upload_invarient_state( struct brw_context *brw ) { struct intel_context *intel = &brw->intel; + /* 3DSTATE_SIP, 3DSTATE_MULTISAMPLE, etc. are nonpipelined. */ + if (intel->gen == 6) + intel_emit_post_sync_nonzero_flush(intel); + { /* 0x61040000 Pipeline Select */ /* PipelineSelect : 0 */ @@ -627,6 +672,7 @@ static void upload_invarient_state( struct brw_context *brw ) sip.header.length = 0; sip.bits0.pad = 0; sip.bits0.system_instruction_pointer = 0; + BRW_BATCH_STRUCT(brw, &sip); } @@ -666,7 +712,19 @@ static void upload_state_base_address( struct brw_context *brw ) { struct intel_context *intel = &brw->intel; + /* FINISHME: According to section 3.6.1 "STATE_BASE_ADDRESS" of + * vol1a of the G45 PRM, MI_FLUSH with the ISC invalidate should be + * programmed prior to STATE_BASE_ADDRESS. + * + * However, given that the instruction SBA (general state base + * address) on this chipset is always set to 0 across X and GL, + * maybe this isn't required for us in particular. + */ + if (intel->gen >= 6) { + if (intel->gen == 6) + intel_emit_post_sync_nonzero_flush(intel); + BEGIN_BATCH(10); OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (10 - 2)); /* General state base address: stateless DP read/write requests */ @@ -690,7 +748,9 @@ static void upload_state_base_address( struct brw_context *brw ) I915_GEM_DOMAIN_INSTRUCTION), 0, 1); OUT_BATCH(1); /* Indirect object base address: MEDIA_OBJECT data */ - OUT_BATCH(1); /* Instruction base address: shader kernels (incl. SIP) */ + OUT_RELOC(brw->cache.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, + 1); /* Instruction base address: shader kernels (incl. SIP) */ + OUT_BATCH(1); /* General state upper bound */ OUT_BATCH(1); /* Dynamic state upper bound */ OUT_BATCH(1); /* Indirect object upper bound */ @@ -703,7 +763,8 @@ static void upload_state_base_address( struct brw_context *brw ) OUT_RELOC(intel->batch.bo, I915_GEM_DOMAIN_SAMPLER, 0, 1); /* Surface state base address */ OUT_BATCH(1); /* Indirect object base address */ - OUT_BATCH(1); /* Instruction base address */ + OUT_RELOC(brw->cache.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, + 1); /* Instruction base address */ OUT_BATCH(1); /* General state upper bound */ OUT_BATCH(1); /* Indirect object upper bound */ OUT_BATCH(1); /* Instruction access upper bound */ @@ -719,12 +780,37 @@ static void upload_state_base_address( struct brw_context *brw ) OUT_BATCH(1); /* Indirect object upper bound */ ADVANCE_BATCH(); } + + /* According to section 3.6.1 of VOL1 of the 965 PRM, + * STATE_BASE_ADDRESS updates require a reissue of: + * + * 3DSTATE_PIPELINE_POINTERS + * 3DSTATE_BINDING_TABLE_POINTERS + * MEDIA_STATE_POINTERS + * + * and this continues through Ironlake. The Sandy Bridge PRM, vol + * 1 part 1 says that the folowing packets must be reissued: + * + * 3DSTATE_CC_POINTERS + * 3DSTATE_BINDING_TABLE_POINTERS + * 3DSTATE_SAMPLER_STATE_POINTERS + * 3DSTATE_VIEWPORT_STATE_POINTERS + * MEDIA_STATE_POINTERS + * + * Those are always reissued following SBA updates anyway (new + * batch time), except in the case of the program cache BO + * changing. Having a separate state flag makes the sequence more + * obvious. + */ + + brw->state.dirty.brw |= BRW_NEW_STATE_BASE_ADDRESS; } const struct brw_tracked_state brw_state_base_address = { .dirty = { .mesa = 0, - .brw = BRW_NEW_BATCH, + .brw = (BRW_NEW_BATCH | + BRW_NEW_PROGRAM_CACHE), .cache = 0, }, .emit = upload_state_base_address diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c index c2227777cfb..fca30a74aaf 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.c +++ b/src/mesa/drivers/dri/i965/brw_sf.c @@ -120,14 +120,11 @@ static void compile_sf_prog( struct brw_context *brw, printf("\n"); } - /* Upload - */ - drm_intel_bo_unreference(brw->sf.prog_bo); - brw->sf.prog_bo = brw_upload_cache(&brw->cache, BRW_SF_PROG, - &c.key, sizeof(c.key), - program, program_size, - &c.prog_data, sizeof(c.prog_data), - &brw->sf.prog_data); + brw_upload_cache(&brw->cache, BRW_SF_PROG, + &c.key, sizeof(c.key), + program, program_size, + &c.prog_data, sizeof(c.prog_data), + &brw->sf.prog_offset, &brw->sf.prog_data); ralloc_free(mem_ctx); } @@ -191,12 +188,11 @@ static void upload_sf_prog(struct brw_context *brw) key.frontface_ccw = (ctx->Polygon.FrontFace == GL_CCW) ^ (ctx->DrawBuffer->Name != 0); } - drm_intel_bo_unreference(brw->sf.prog_bo); - brw->sf.prog_bo = brw_search_cache(&brw->cache, BRW_SF_PROG, - &key, sizeof(key), - &brw->sf.prog_data); - if (brw->sf.prog_bo == NULL) + if (!brw_search_cache(&brw->cache, BRW_SF_PROG, + &key, sizeof(key), + &brw->sf.prog_offset, &brw->sf.prog_data)) { compile_sf_prog( brw, &key ); + } } diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c index 78b22c4df3d..eb3d103099b 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_state.c +++ b/src/mesa/drivers/dri/i965/brw_sf_state.c @@ -133,9 +133,14 @@ static void upload_sf_unit( struct brw_context *brw ) memset(sf, 0, sizeof(*sf)); - /* CACHE_NEW_SF_PROG */ + /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_SF_PROG */ sf->thread0.grf_reg_count = ALIGN(brw->sf.prog_data->total_grf, 16) / 16 - 1; - sf->thread0.kernel_start_pointer = brw->sf.prog_bo->offset >> 6; /* reloc */ + sf->thread0.kernel_start_pointer = + brw_program_reloc(brw, + brw->sf.state_offset + + offsetof(struct brw_sf_unit_state, thread0), + brw->sf.prog_offset + + (sf->thread0.grf_reg_count << 1)) >> 6; sf->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; @@ -282,11 +287,6 @@ static void upload_sf_unit( struct brw_context *brw ) /* STATE_PREFETCH command description describes this state as being * something loaded through the GPE (L2 ISC), so it's INSTRUCTION domain. */ - /* Emit SF program relocation */ - drm_intel_bo_emit_reloc(bo, (brw->sf.state_offset + - offsetof(struct brw_sf_unit_state, thread0)), - brw->sf.prog_bo, sf->thread0.grf_reg_count << 1, - I915_GEM_DOMAIN_INSTRUCTION, 0); /* Emit SF viewport relocation */ drm_intel_bo_emit_reloc(bo, (brw->sf.state_offset + @@ -308,6 +308,7 @@ const struct brw_tracked_state brw_sf_unit = { _NEW_SCISSOR | _NEW_BUFFERS), .brw = (BRW_NEW_BATCH | + BRW_NEW_PROGRAM_CACHE | BRW_NEW_URB_FENCE), .cache = (CACHE_NEW_SF_VP | CACHE_NEW_SF_PROG) diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 544ef7d47e6..b384651d8d0 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -145,21 +145,21 @@ void brw_clear_validated_bos(struct brw_context *brw); * brw_state_cache.c */ -drm_intel_bo *brw_upload_cache(struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *key, - GLuint key_sz, - const void *data, - GLuint data_sz, - const void *aux, - GLuint aux_sz, - void *aux_return); - -drm_intel_bo *brw_search_cache( struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *key, - GLuint key_size, - void *aux_return); +void brw_upload_cache(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_sz, + const void *data, + GLuint data_sz, + const void *aux, + GLuint aux_sz, + uint32_t *out_offset, void *out_aux); + +bool brw_search_cache(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_size, + uint32_t *inout_offset, void *out_aux); void brw_state_cache_check_size( struct brw_context *brw ); void brw_init_caches( struct brw_context *brw ); diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c index f13a41fa7cc..3988625ea91 100644 --- a/src/mesa/drivers/dri/i965/brw_state_cache.c +++ b/src/mesa/drivers/dri/i965/brw_state_cache.c @@ -45,6 +45,7 @@ */ #include "main/imports.h" +#include "intel_batchbuffer.h" #include "brw_state.h" #define FILE_DEBUG_FLAG DEBUG_STATE @@ -67,23 +68,6 @@ hash_key(struct brw_cache_item *item) return hash; } - -/** - * Marks a new buffer as being chosen for the given cache id. - */ -static void -update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id, - drm_intel_bo *bo) -{ - if (bo == cache->last_bo[cache_id]) - return; /* no change */ - - drm_intel_bo_unreference(cache->last_bo[cache_id]); - cache->last_bo[cache_id] = bo; - drm_intel_bo_reference(cache->last_bo[cache_id]); - cache->brw->state.dirty.cache |= 1 << cache_id; -} - static int brw_cache_item_equals(const struct brw_cache_item *a, const struct brw_cache_item *b) @@ -145,12 +129,13 @@ rehash(struct brw_cache *cache) /** * Returns the buffer object matching cache_id and key, or NULL. */ -drm_intel_bo * +bool brw_search_cache(struct brw_cache *cache, enum brw_cache_id cache_id, const void *key, GLuint key_size, - void *aux_return) + uint32_t *inout_offset, void *out_aux) { + struct brw_context *brw = cache->brw; struct brw_cache_item *item; struct brw_cache_item lookup; GLuint hash; @@ -164,19 +149,116 @@ brw_search_cache(struct brw_cache *cache, item = search_cache(cache, hash, &lookup); if (item == NULL) - return NULL; + return false; - if (aux_return) - *(void **)aux_return = (void *)((char *)item->key + item->key_size); + *(void **)out_aux = ((char *)item->key + item->key_size); - update_cache_last(cache, cache_id, item->bo); + if (item->offset != *inout_offset) { + brw->state.dirty.cache |= (1 << cache_id); + *inout_offset = item->offset; + } - drm_intel_bo_reference(item->bo); - return item->bo; + return true; } +static void +brw_cache_new_bo(struct brw_cache *cache, uint32_t new_size) +{ + struct brw_context *brw = cache->brw; + struct intel_context *intel = &brw->intel; + drm_intel_bo *new_bo; + + new_bo = drm_intel_bo_alloc(intel->bufmgr, "program cache", new_size, 64); + + /* Copy any existing data that needs to be saved. */ + if (cache->next_offset != 0) { + drm_intel_bo_map(cache->bo, false); + drm_intel_bo_subdata(new_bo, 0, cache->next_offset, cache->bo->virtual); + drm_intel_bo_unmap(cache->bo); + } + + drm_intel_bo_unreference(cache->bo); + cache->bo = new_bo; + cache->bo_used_by_gpu = false; + + /* Since we have a new BO in place, we need to signal the units + * that depend on it (state base address on gen5+, or unit state before). + */ + brw->state.dirty.brw |= BRW_NEW_PROGRAM_CACHE; +} + +/** + * Attempts to find an item in the cache with identical data and aux + * data to use + */ +static bool +brw_try_upload_using_copy(struct brw_cache *cache, + struct brw_cache_item *result_item, + const void *data, + const void *aux) +{ + int i; + struct brw_cache_item *item; + + for (i = 0; i < cache->size; i++) { + for (item = cache->items[i]; item; item = item->next) { + const void *item_aux = item->key + item->key_size; + int ret; + + if (item->cache_id != result_item->cache_id || + item->size != result_item->size || + item->aux_size != result_item->aux_size) { + continue; + } + + if (memcmp(item_aux, aux, item->aux_size) != 0) { + continue; + } + + drm_intel_bo_map(cache->bo, false); + ret = memcmp(cache->bo->virtual + item->offset, data, item->size); + drm_intel_bo_unmap(cache->bo); + if (ret) + continue; + + result_item->offset = item->offset; + + return true; + } + } + + return false; +} + +static void +brw_upload_item_data(struct brw_cache *cache, + struct brw_cache_item *item, + const void *data) +{ + /* Allocate space in the cache BO for our new program. */ + if (cache->next_offset + item->size > cache->bo->size) { + uint32_t new_size = cache->bo->size * 2; + + while (cache->next_offset + item->size > new_size) + new_size *= 2; + + brw_cache_new_bo(cache, new_size); + } + + /* If we would block on writing to an in-use program BO, just + * recreate it. + */ + if (cache->bo_used_by_gpu) { + brw_cache_new_bo(cache, cache->bo->size); + } + + item->offset = cache->next_offset; + + /* Programs are always 64-byte aligned, so set up the next one now */ + cache->next_offset = ALIGN(item->offset + item->size, 64); +} -drm_intel_bo * +void brw_upload_cache(struct brw_cache *cache, enum brw_cache_id cache_id, const void *key, @@ -185,23 +267,31 @@ brw_upload_cache(struct brw_cache *cache, GLuint data_size, const void *aux, GLuint aux_size, - void *aux_return) + uint32_t *out_offset, + void *out_aux) { struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item); GLuint hash; void *tmp; - drm_intel_bo *bo; item->cache_id = cache_id; + item->size = data_size; item->key = key; item->key_size = key_size; + item->aux_size = aux_size; hash = hash_key(item); item->hash = hash; - /* Create the buffer object to contain the data */ - bo = drm_intel_bo_alloc(cache->brw->intel.bufmgr, - cache->name[cache_id], data_size, 1 << 6); - + /* If we can find a matching prog/prog_data combo in the cache + * already, then reuse the existing stuff. This will mean not + * flagging CACHE_NEW_* when transitioning between the two + * equivalent hash keys. This is notably useful for programs + * generating shaders at runtime, where multiple shaders may + * compile to the thing in our backend. + */ + if (!brw_try_upload_using_copy(cache, item, data, aux)) { + brw_upload_item_data(cache, item, data); + } /* Set up the memory containing the key and aux_data */ tmp = malloc(key_size + aux_size); @@ -211,9 +301,6 @@ brw_upload_cache(struct brw_cache *cache, item->key = tmp; - item->bo = bo; - drm_intel_bo_reference(bo); - if (cache->n_items > cache->size * 1.5) rehash(cache); @@ -222,34 +309,18 @@ brw_upload_cache(struct brw_cache *cache, cache->items[hash] = item; cache->n_items++; - if (aux_return) { - *(void **)aux_return = (void *)((char *)item->key + item->key_size); - } - - DBG("upload %s: %d bytes to cache id %d\n", - cache->name[cache_id], - data_size, cache_id); - /* Copy data to the buffer */ - drm_intel_bo_subdata(bo, 0, data_size, data); - - update_cache_last(cache, cache_id, bo); + drm_intel_bo_subdata(cache->bo, item->offset, data_size, data); - return bo; -} - -static void -brw_init_cache_id(struct brw_cache *cache, - const char *name, - enum brw_cache_id id) -{ - cache->name[id] = strdup(name); + *out_offset = item->offset; + *(void **)out_aux = (void *)((char *)item->key + item->key_size); + cache->brw->state.dirty.cache |= 1 << cache_id; } - void brw_init_caches(struct brw_context *brw) { + struct intel_context *intel = &brw->intel; struct brw_cache *cache = &brw->cache; cache->brw = brw; @@ -259,36 +330,15 @@ brw_init_caches(struct brw_context *brw) cache->items = (struct brw_cache_item **) calloc(1, cache->size * sizeof(struct brw_cache_item)); - brw_init_cache_id(cache, "CC_VP", BRW_CC_VP); - brw_init_cache_id(cache, "CC_UNIT", BRW_CC_UNIT); - brw_init_cache_id(cache, "WM_PROG", BRW_WM_PROG); - brw_init_cache_id(cache, "SAMPLER", BRW_SAMPLER); - brw_init_cache_id(cache, "WM_UNIT", BRW_WM_UNIT); - brw_init_cache_id(cache, "SF_PROG", BRW_SF_PROG); - brw_init_cache_id(cache, "SF_VP", BRW_SF_VP); - - brw_init_cache_id(cache, "SF_UNIT", BRW_SF_UNIT); - - brw_init_cache_id(cache, "VS_UNIT", BRW_VS_UNIT); - - brw_init_cache_id(cache, "VS_PROG", BRW_VS_PROG); - - brw_init_cache_id(cache, "CLIP_UNIT", BRW_CLIP_UNIT); - - brw_init_cache_id(cache, "CLIP_PROG", BRW_CLIP_PROG); - brw_init_cache_id(cache, "CLIP_VP", BRW_CLIP_VP); - - brw_init_cache_id(cache, "GS_UNIT", BRW_GS_UNIT); - - brw_init_cache_id(cache, "GS_PROG", BRW_GS_PROG); - brw_init_cache_id(cache, "BLEND_STATE", BRW_BLEND_STATE); - brw_init_cache_id(cache, "COLOR_CALC_STATE", BRW_COLOR_CALC_STATE); - brw_init_cache_id(cache, "DEPTH_STENCIL_STATE", BRW_DEPTH_STENCIL_STATE); + cache->bo = drm_intel_bo_alloc(intel->bufmgr, + "program cache", + 4096, 64); } static void brw_clear_cache(struct brw_context *brw, struct brw_cache *cache) { + struct intel_context *intel = &brw->intel; struct brw_cache_item *c, *next; GLuint i; @@ -297,7 +347,6 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache) for (i = 0; i < cache->size; i++) { for (c = cache->items[i]; c; c = next) { next = c->next; - drm_intel_bo_unreference(c->bo); free((void *)c->key); free(c); } @@ -306,9 +355,18 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache) cache->n_items = 0; + /* Start putting programs into the start of the BO again, since + * we'll never find the old results. + */ + cache->next_offset = 0; + + /* We need to make sure that the programs get regenerated, since + * any offsets leftover in brw_context will no longer be valid. + */ brw->state.dirty.mesa |= ~0; brw->state.dirty.brw |= ~0; brw->state.dirty.cache |= ~0; + intel_batchbuffer_flush(intel); } void @@ -325,15 +383,10 @@ brw_state_cache_check_size(struct brw_context *brw) static void brw_destroy_cache(struct brw_context *brw, struct brw_cache *cache) { - GLuint i; DBG("%s\n", __FUNCTION__); brw_clear_cache(brw, cache); - for (i = 0; i < BRW_MAX_CACHE; i++) { - drm_intel_bo_unreference(cache->last_bo[i]); - free(cache->name[i]); - } free(cache->items); cache->items = NULL; cache->size = 0; diff --git a/src/mesa/drivers/dri/i965/brw_state_dump.c b/src/mesa/drivers/dri/i965/brw_state_dump.c index ff06cb3a91e..7a3a88f04f5 100644 --- a/src/mesa/drivers/dri/i965/brw_state_dump.c +++ b/src/mesa/drivers/dri/i965/brw_state_dump.c @@ -459,21 +459,19 @@ static void dump_blend_state(struct brw_context *brw) } -static void brw_debug_prog(const char *name, drm_intel_bo *prog) +static void brw_debug_prog(struct brw_context *brw, + const char *name, uint32_t prog_offset) { unsigned int i; uint32_t *data; - if (prog == NULL) - return; - - drm_intel_bo_map(prog, GL_FALSE); + drm_intel_bo_map(brw->cache.bo, false); - data = prog->virtual; + data = brw->cache.bo->virtual + prog_offset; - for (i = 0; i < prog->size / 4 / 4; i++) { + for (i = 0; i < brw->cache.bo->size / 4 / 4; i++) { fprintf(stderr, "%8s: 0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", - name, (unsigned int)prog->offset + i * 4 * 4, + name, (unsigned int)brw->cache.bo->offset + i * 4 * 4, data[i * 4], data[i * 4 + 1], data[i * 4 + 2], data[i * 4 + 3]); /* Stop at the end of the program. It'd be nice to keep track of the actual * intended program size instead of guessing like this. @@ -485,7 +483,7 @@ static void brw_debug_prog(const char *name, drm_intel_bo *prog) break; } - drm_intel_bo_unmap(prog); + drm_intel_bo_unmap(brw->cache.bo); } @@ -518,17 +516,19 @@ void brw_debug_batch(struct intel_context *intel) if (intel->gen < 6) state_struct_out("VS", intel->batch.bo, brw->vs.state_offset, sizeof(struct brw_vs_unit_state)); - brw_debug_prog("VS prog", brw->vs.prog_bo); + brw_debug_prog(brw, "VS prog", brw->vs.prog_offset); if (intel->gen < 6) state_struct_out("GS", intel->batch.bo, brw->gs.state_offset, sizeof(struct brw_gs_unit_state)); - brw_debug_prog("GS prog", brw->gs.prog_bo); + if (brw->gs.prog_active) { + brw_debug_prog(brw, "GS prog", brw->gs.prog_offset); + } if (intel->gen < 6) { state_struct_out("SF", intel->batch.bo, brw->sf.state_offset, sizeof(struct brw_sf_unit_state)); - brw_debug_prog("SF prog", brw->sf.prog_bo); + brw_debug_prog(brw, "SF prog", brw->sf.prog_offset); } if (intel->gen >= 7) dump_sf_clip_viewport_state(brw); @@ -540,7 +540,7 @@ void brw_debug_batch(struct intel_context *intel) if (intel->gen < 6) state_struct_out("WM", intel->batch.bo, brw->wm.state_offset, sizeof(struct brw_wm_unit_state)); - brw_debug_prog("WM prog", brw->wm.prog_bo); + brw_debug_prog(brw, "WM prog", brw->wm.prog_offset); if (intel->gen >= 6) { dump_cc_viewport_state(brw); diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 6a4c112dcf5..76ffa0daefe 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -47,11 +47,11 @@ static const struct brw_tracked_state *gen4_atoms[] = &brw_check_fallback, &brw_wm_input_sizes, - &brw_vs_prog, - &brw_gs_prog, - &brw_clip_prog, - &brw_sf_prog, - &brw_wm_prog, + &brw_vs_prog, /* must do before GS prog, state base address. */ + &brw_gs_prog, /* must do before state base address */ + &brw_clip_prog, /* must do before state base address */ + &brw_sf_prog, /* must do before state base address */ + &brw_wm_prog, /* must do before state base address */ /* Once all the programs are done, we know how large urb entry * sizes need to be and can decide if we need to change the urb @@ -110,9 +110,9 @@ static const struct brw_tracked_state *gen6_atoms[] = &brw_check_fallback, &brw_wm_input_sizes, - &brw_vs_prog, - &brw_gs_prog, - &brw_wm_prog, + &brw_vs_prog, /* must do before state base address */ + &brw_gs_prog, /* must do before state base address */ + &brw_wm_prog, /* must do before state base address */ &gen6_clip_vp, &gen6_sf_vp, @@ -365,6 +365,7 @@ static struct dirty_bit_map brw_bits[] = { DEFINE_BIT(BRW_NEW_PRIMITIVE), DEFINE_BIT(BRW_NEW_CONTEXT), DEFINE_BIT(BRW_NEW_WM_INPUT_DIMENSIONS), + DEFINE_BIT(BRW_NEW_PROGRAM_CACHE), DEFINE_BIT(BRW_NEW_PSP), DEFINE_BIT(BRW_NEW_WM_SURFACES), DEFINE_BIT(BRW_NEW_INDICES), @@ -378,6 +379,7 @@ static struct dirty_bit_map brw_bits[] = { DEFINE_BIT(BRW_NEW_VS_BINDING_TABLE), DEFINE_BIT(BRW_NEW_GS_BINDING_TABLE), DEFINE_BIT(BRW_NEW_PS_BINDING_TABLE), + DEFINE_BIT(BRW_NEW_STATE_BASE_ADDRESS), {0, 0, 0} }; diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index 4a3a2bfada2..f462f32b19a 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -88,7 +88,7 @@ GLboolean brw_miptree_layout(struct intel_context *intel, GLuint align_w = 4; mt->total_height = 0; - intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h); + intel_get_texture_alignment_unit(mt->format, &align_w, &align_h); if (mt->compressed) { mt->total_width = ALIGN(width, align_w); diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c index d6a53995531..a9ad5311fe3 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.c +++ b/src/mesa/drivers/dri/i965/brw_vs.c @@ -105,12 +105,11 @@ static void do_vs_prog( struct brw_context *brw, /* constant_map */ aux_size += c.vp->program.Base.Parameters->NumParameters; - drm_intel_bo_unreference(brw->vs.prog_bo); - brw->vs.prog_bo = brw_upload_cache(&brw->cache, BRW_VS_PROG, - &c.key, sizeof(c.key), - program, program_size, - &c.prog_data, aux_size, - &brw->vs.prog_data); + brw_upload_cache(&brw->cache, BRW_VS_PROG, + &c.key, sizeof(c.key), + program, program_size, + &c.prog_data, aux_size, + &brw->vs.prog_offset, &brw->vs.prog_data); ralloc_free(mem_ctx); } @@ -145,14 +144,19 @@ static void brw_upload_vs_prog(struct brw_context *brw) } } - /* Make an early check for the key. - */ - drm_intel_bo_unreference(brw->vs.prog_bo); - brw->vs.prog_bo = brw_search_cache(&brw->cache, BRW_VS_PROG, - &key, sizeof(key), - &brw->vs.prog_data); - if (brw->vs.prog_bo == NULL) + /* BRW_NEW_VERTICES */ + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + if (vp->program.Base.InputsRead & (1 << i) && + brw->vb.inputs[i].glarray->Type == GL_FIXED) { + key.gl_fixed_input_size[i] = brw->vb.inputs[i].glarray->Size; + } + } + + if (!brw_search_cache(&brw->cache, BRW_VS_PROG, + &key, sizeof(key), + &brw->vs.prog_offset, &brw->vs.prog_data)) { do_vs_prog(brw, vp, &key); + } brw->vs.constant_map = ((int8_t *)brw->vs.prog_data + sizeof(*brw->vs.prog_data)); } @@ -164,7 +168,8 @@ const struct brw_tracked_state brw_vs_prog = { .dirty = { .mesa = (_NEW_TRANSFORM | _NEW_POLYGON | _NEW_POINT | _NEW_LIGHT | _NEW_BUFFERS), - .brw = BRW_NEW_VERTEX_PROGRAM, + .brw = (BRW_NEW_VERTEX_PROGRAM | + BRW_NEW_VERTICES), .cache = 0 }, .prepare = brw_upload_vs_prog diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h index 7ca84a54b01..432994a8534 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.h +++ b/src/mesa/drivers/dri/i965/brw_vs.h @@ -41,6 +41,10 @@ struct brw_vs_prog_key { GLuint program_string_id; + /** + * Number of channels of the vertex attribute that need GL_FIXED rescaling + */ + uint8_t gl_fixed_input_size[VERT_ATTRIB_MAX]; GLuint nr_userclip:4; GLuint copy_edgeflag:1; GLuint point_coord_replace:8; diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 7d5eb353eee..9d733344a26 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -1635,7 +1635,7 @@ static void emit_vertex_write( struct brw_vs_compile *c) else m = brw_message_reg(4); - brw_DP4(p, brw_writemask(m, (1 << (i & 7))),pos, c->userplane[i]); + brw_DP4(p, brw_writemask(m, (1 << (i & 3))),pos, c->userplane[i]); } } } else if ((c->prog_data.outputs_written & @@ -1878,6 +1878,26 @@ get_predicate(const struct prog_instruction *inst) } } +static void +brw_vs_rescale_gl_fixed(struct brw_vs_compile *c) +{ + struct brw_compile *p = &c->func; + int i; + + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + if (!(c->prog_data.inputs_read & (1 << i))) + continue; + + if (c->key.gl_fixed_input_size[i] != 0) { + struct brw_reg reg = c->regs[PROGRAM_INPUT][i]; + + brw_MUL(p, + brw_writemask(reg, (1 << c->key.gl_fixed_input_size[i]) - 1), + reg, brw_imm_f(1.0 / 65536.0)); + } + } +} + /* Emit the vertex program instructions here. */ void brw_vs_emit(struct brw_vs_compile *c ) @@ -1937,6 +1957,8 @@ void brw_vs_emit(struct brw_vs_compile *c ) */ brw_vs_alloc_regs(c); + brw_vs_rescale_gl_fixed(c); + if (c->needs_stack) brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack)); diff --git a/src/mesa/drivers/dri/i965/brw_vs_state.c b/src/mesa/drivers/dri/i965/brw_vs_state.c index 1eee5b7e5de..d5010a21e80 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_state.c +++ b/src/mesa/drivers/dri/i965/brw_vs_state.c @@ -36,18 +36,6 @@ #include "brw_defines.h" #include "main/macros.h" -struct brw_vs_unit_key { - unsigned int total_grf; - unsigned int urb_entry_read_length; - unsigned int curb_entry_read_length; - - unsigned int curbe_offset; - - unsigned int nr_urb_entries, urb_size; - - unsigned int nr_surfaces; -}; - static void brw_prepare_vs_unit(struct brw_context *brw) { @@ -58,8 +46,14 @@ brw_prepare_vs_unit(struct brw_context *brw) vs = brw_state_batch(brw, sizeof(*vs), 32, &brw->vs.state_offset); memset(vs, 0, sizeof(*vs)); - /* CACHE_NEW_VS_PROG */ - vs->thread0.kernel_start_pointer = brw->vs.prog_bo->offset >> 6; /* reloc */ + /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_VS_PROG */ + vs->thread0.kernel_start_pointer = + brw_program_reloc(brw, + brw->vs.state_offset + + offsetof(struct brw_vs_unit_state, thread0), + brw->vs.prog_offset + + (vs->thread0.grf_reg_count << 1)) >> 6; + vs->thread0.grf_reg_count = ALIGN(brw->vs.prog_data->total_grf, 16) / 16 - 1; vs->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; /* Choosing multiple program flow means that we may get 2-vertex threads, @@ -152,13 +146,6 @@ brw_prepare_vs_unit(struct brw_context *brw) */ vs->vs6.vs_enable = 1; - /* Emit VS program relocation */ - drm_intel_bo_emit_reloc(intel->batch.bo, (brw->vs.state_offset + - offsetof(struct brw_vs_unit_state, - thread0)), - brw->vs.prog_bo, vs->thread0.grf_reg_count << 1, - I915_GEM_DOMAIN_INSTRUCTION, 0); - brw->state.dirty.cache |= CACHE_NEW_VS_UNIT; } @@ -166,6 +153,7 @@ const struct brw_tracked_state brw_vs_unit = { .dirty = { .mesa = _NEW_TRANSFORM, .brw = (BRW_NEW_BATCH | + BRW_NEW_PROGRAM_CACHE | BRW_NEW_CURBE_OFFSETS | BRW_NEW_NR_VS_SURFACES | BRW_NEW_URB_FENCE), diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index 69650e1df77..8612e743265 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -69,14 +69,8 @@ static void brw_destroy_context( struct intel_context *intel ) ralloc_free(brw->wm.compile_data); dri_bo_release(&brw->curbe.curbe_bo); - dri_bo_release(&brw->vs.prog_bo); dri_bo_release(&brw->vs.const_bo); - dri_bo_release(&brw->gs.prog_bo); - dri_bo_release(&brw->clip.prog_bo); - dri_bo_release(&brw->sf.prog_bo); - dri_bo_release(&brw->wm.prog_bo); dri_bo_release(&brw->wm.const_bo); - dri_bo_release(&brw->cc.prog_bo); free(brw->curbe.last_buf); free(brw->curbe.next_buf); @@ -122,13 +116,20 @@ static void brw_new_batch( struct intel_context *intel ) * This is probably not as severe as on 915, since almost all of our state * is just in referenced buffers. */ - brw->state.dirty.brw |= BRW_NEW_CONTEXT; + brw->state.dirty.brw |= BRW_NEW_CONTEXT | BRW_NEW_BATCH; - brw->state.dirty.mesa |= ~0; - brw->state.dirty.brw |= ~0; - brw->state.dirty.cache |= ~0; + /* Assume that the last command before the start of our batch was a + * primitive, for safety. + */ + intel->batch.need_workaround_flush = true; brw->vb.nr_current_buffers = 0; + + /* Mark that the current program cache BO has been used by the GPU. + * It will be reallocated if we need to put new programs in for the + * next batch. + */ + brw->cache.bo_used_by_gpu = true; } static void brw_invalidate_state( struct intel_context *intel, GLuint new_state ) diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 1aebd12df49..b0dfdd536aa 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -273,12 +273,11 @@ bool do_wm_prog(struct brw_context *brw, */ program = brw_get_program(&c->func, &program_size); - drm_intel_bo_unreference(brw->wm.prog_bo); - brw->wm.prog_bo = brw_upload_cache(&brw->cache, BRW_WM_PROG, - &c->key, sizeof(c->key), - program, program_size, - &c->prog_data, sizeof(c->prog_data), - &brw->wm.prog_data); + brw_upload_cache(&brw->cache, BRW_WM_PROG, + &c->key, sizeof(c->key), + program, program_size, + &c->prog_data, sizeof(c->prog_data), + &brw->wm.prog_offset, &brw->wm.prog_data); return true; } @@ -389,6 +388,8 @@ static void brw_wm_populate_key( struct brw_context *brw, * all 4 channels. */ if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) { + key->compare_funcs[i] = sampler->CompareFunc; + if (sampler->DepthMode == GL_ALPHA) { swizzles[0] = SWIZZLE_ZERO; swizzles[1] = SWIZZLE_ZERO; @@ -477,13 +478,9 @@ static void brw_prepare_wm_prog(struct brw_context *brw) brw_wm_populate_key(brw, &key); - /* Make an early check for the key. - */ - drm_intel_bo_unreference(brw->wm.prog_bo); - brw->wm.prog_bo = brw_search_cache(&brw->cache, BRW_WM_PROG, - &key, sizeof(key), - &brw->wm.prog_data); - if (brw->wm.prog_bo == NULL) { + if (!brw_search_cache(&brw->cache, BRW_WM_PROG, + &key, sizeof(key), + &brw->wm.prog_offset, &brw->wm.prog_data)) { bool success = do_wm_prog(brw, ctx->Shader.CurrentFragmentProgram, fp, &key); assert(success); diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index e244b55a083..29082c19088 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -68,6 +68,18 @@ struct brw_wm_prog_key { GLuint clamp_fragment_color:1; GLuint line_aa:2; + /** + * Per-sampler comparison functions: + * + * If comparison mode is GL_COMPARE_R_TO_TEXTURE, then this is set to one + * of GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, + * GL_GEQUAL, or GL_ALWAYS. Otherwise (comparison mode is GL_NONE), this + * field is irrelevant so it's left as GL_NONE (0). + * + * While this is a GLenum, all possible values fit in 16-bits. + */ + uint16_t compare_funcs[BRW_MAX_TEX_UNIT]; + GLbitfield proj_attrib_mask; /**< one bit per fragment program attribute */ GLuint yuvtex_mask:16; GLuint yuvtex_swap_mask:16; /* UV swaped */ diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index ef98f8126dc..506e2bdff5b 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -90,13 +90,25 @@ brw_prepare_wm_unit(struct brw_context *brw) brw->wm.prog_data->first_curbe_grf_16); } - /* CACHE_NEW_WM_PROG */ + /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_WM_PROG */ wm->thread0.grf_reg_count = brw->wm.prog_data->reg_blocks; wm->wm9.grf_reg_count_2 = brw->wm.prog_data->reg_blocks_16; - wm->thread0.kernel_start_pointer = brw->wm.prog_bo->offset >> 6; /* reloc */ - /* reloc */ - wm->wm9.kernel_start_pointer_2 = (brw->wm.prog_bo->offset + - brw->wm.prog_data->prog_offset_16) >> 6; + + wm->thread0.kernel_start_pointer = + brw_program_reloc(brw, + brw->wm.state_offset + + offsetof(struct brw_wm_unit_state, thread0), + brw->wm.prog_offset + + (wm->thread0.grf_reg_count << 1)) >> 6; + + wm->wm9.kernel_start_pointer_2 = + brw_program_reloc(brw, + brw->wm.state_offset + + offsetof(struct brw_wm_unit_state, wm9), + brw->wm.prog_offset + + brw->wm.prog_data->prog_offset_16 + + (wm->wm9.grf_reg_count_2 << 1)) >> 6; + wm->thread1.depth_coef_urb_read_offset = 1; wm->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; @@ -214,23 +226,6 @@ brw_prepare_wm_unit(struct brw_context *brw) if (unlikely(INTEL_DEBUG & DEBUG_STATS) || intel->stats_wm) wm->wm4.stats_enable = 1; - /* Emit WM program relocation */ - drm_intel_bo_emit_reloc(intel->batch.bo, - brw->wm.state_offset + - offsetof(struct brw_wm_unit_state, thread0), - brw->wm.prog_bo, wm->thread0.grf_reg_count << 1, - I915_GEM_DOMAIN_INSTRUCTION, 0); - - if (brw->wm.prog_data->prog_offset_16) { - drm_intel_bo_emit_reloc(intel->batch.bo, - brw->wm.state_offset + - offsetof(struct brw_wm_unit_state, wm9), - brw->wm.prog_bo, - ((wm->wm9.grf_reg_count_2 << 1) + - brw->wm.prog_data->prog_offset_16), - I915_GEM_DOMAIN_INSTRUCTION, 0); - } - /* Emit scratch space relocation */ if (brw->wm.prog_data->total_scratch != 0) { drm_intel_bo_emit_reloc(intel->batch.bo, @@ -265,6 +260,7 @@ const struct brw_tracked_state brw_wm_unit = { _NEW_BUFFERS), .brw = (BRW_NEW_BATCH | + BRW_NEW_PROGRAM_CACHE | BRW_NEW_FRAGMENT_PROGRAM | BRW_NEW_CURBE_OFFSETS | BRW_NEW_NR_WM_SURFACES), 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 f560bc3fa66..89fea9cc952 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -73,7 +73,7 @@ translate_tex_target(GLenum target) uint32_t brw_format_for_mesa_format(gl_format mesa_format) { - uint32_t table[MESA_FORMAT_COUNT] = + static const uint32_t table[MESA_FORMAT_COUNT] = { [MESA_FORMAT_L8] = BRW_SURFACEFORMAT_L8_UNORM, [MESA_FORMAT_I8] = BRW_SURFACEFORMAT_I8_UNORM, @@ -477,7 +477,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw, format << BRW_SURFACE_FORMAT_SHIFT); /* reloc */ - surf[1] = (intel_region_tile_offsets(region, &tile_x, &tile_y) + + surf[1] = (intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y) + region->buffer->offset); surf[2] = ((rb->Width - 1) << BRW_SURFACE_WIDTH_SHIFT | diff --git a/src/mesa/drivers/dri/i965/gen6_cc.c b/src/mesa/drivers/dri/i965/gen6_cc.c index 2b16d6cdc01..294d5a5e644 100644 --- a/src/mesa/drivers/dri/i965/gen6_cc.c +++ b/src/mesa/drivers/dri/i965/gen6_cc.c @@ -183,7 +183,8 @@ static void upload_cc_state_pointers(struct brw_context *brw) const struct brw_tracked_state gen6_cc_state_pointers = { .dirty = { .mesa = 0, - .brw = BRW_NEW_BATCH, + .brw = (BRW_NEW_BATCH | + BRW_NEW_STATE_BASE_ADDRESS), .cache = (CACHE_NEW_BLEND_STATE | CACHE_NEW_COLOR_CALC_STATE | CACHE_NEW_DEPTH_STENCIL_STATE) diff --git a/src/mesa/drivers/dri/i965/gen6_gs_state.c b/src/mesa/drivers/dri/i965/gen6_gs_state.c index c1d0a739394..d29f0290727 100644 --- a/src/mesa/drivers/dri/i965/gen6_gs_state.c +++ b/src/mesa/drivers/dri/i965/gen6_gs_state.c @@ -45,7 +45,7 @@ upload_gs_state(struct brw_context *brw) ADVANCE_BATCH(); // GS should never be used on Gen6. Disable it. - assert(brw->gs.prog_bo == NULL); + assert(!brw->gs.prog_active); BEGIN_BATCH(7); OUT_BATCH(_3DSTATE_GS << 16 | (7 - 2)); OUT_BATCH(0); /* prog_bo */ @@ -65,8 +65,7 @@ upload_gs_state(struct brw_context *brw) const struct brw_tracked_state gen6_gs_state = { .dirty = { .mesa = _NEW_TRANSFORM, - .brw = (BRW_NEW_CURBE_OFFSETS | - BRW_NEW_URB_FENCE | + .brw = (BRW_NEW_URB_FENCE | BRW_NEW_CONTEXT), .cache = CACHE_NEW_GS_PROG }, diff --git a/src/mesa/drivers/dri/i965/gen6_sampler_state.c b/src/mesa/drivers/dri/i965/gen6_sampler_state.c index 4cdec699df6..89326872faa 100644 --- a/src/mesa/drivers/dri/i965/gen6_sampler_state.c +++ b/src/mesa/drivers/dri/i965/gen6_sampler_state.c @@ -50,7 +50,8 @@ upload_sampler_state_pointers(struct brw_context *brw) const struct brw_tracked_state gen6_sampler_state = { .dirty = { .mesa = 0, - .brw = BRW_NEW_BATCH, + .brw = (BRW_NEW_BATCH | + BRW_NEW_STATE_BASE_ADDRESS), .cache = CACHE_NEW_SAMPLER }, .emit = upload_sampler_state_pointers, diff --git a/src/mesa/drivers/dri/i965/gen6_scissor_state.c b/src/mesa/drivers/dri/i965/gen6_scissor_state.c index fad3ca0dd04..7492e508864 100644 --- a/src/mesa/drivers/dri/i965/gen6_scissor_state.c +++ b/src/mesa/drivers/dri/i965/gen6_scissor_state.c @@ -31,7 +31,7 @@ #include "intel_batchbuffer.h" static void -gen6_prepare_scissor_state(struct brw_context *brw) +gen6_upload_scissor_state(struct brw_context *brw) { struct intel_context *intel = &brw->intel; struct gl_context *ctx = &intel->ctx; @@ -89,5 +89,5 @@ const struct brw_tracked_state gen6_scissor_state = { .brw = BRW_NEW_BATCH, .cache = 0, }, - .prepare = gen6_prepare_scissor_state, + .emit = gen6_upload_scissor_state, }; diff --git a/src/mesa/drivers/dri/i965/gen6_sf_state.c b/src/mesa/drivers/dri/i965/gen6_sf_state.c index 84028e4e758..5bb731dc8fd 100644 --- a/src/mesa/drivers/dri/i965/gen6_sf_state.c +++ b/src/mesa/drivers/dri/i965/gen6_sf_state.c @@ -100,10 +100,11 @@ upload_sf_state(struct brw_context *brw) int i; /* _NEW_BUFFER */ GLboolean render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0; - int attr = 0; + int attr = 0, input_index = 0; int urb_start; int two_side_color = (ctx->Light.Enabled && ctx->Light.Model.TwoSide); float point_size; + uint16_t attr_overrides[FRAG_ATTRIB_MAX]; /* _NEW_TRANSFORM */ if (ctx->Transform.ClipPlanesEnabled) @@ -230,19 +231,43 @@ upload_sf_state(struct brw_context *brw) (1 << GEN6_SF_TRIFAN_PROVOKE_SHIFT); } - if (ctx->Point.PointSprite) { - for (i = 0; i < 8; i++) { - if (ctx->Point.CoordReplace[i]) - dw16 |= (1 << i); - } - } - /* flat shading */ if (ctx->Light.ShadeModel == GL_FLAT) { dw17 |= ((brw->fragment_program->Base.InputsRead & (FRAG_BIT_COL0 | FRAG_BIT_COL1)) >> ((brw->fragment_program->Base.InputsRead & FRAG_BIT_WPOS) ? 0 : 1)); } + /* Create the mapping from the FS inputs we produce to the VS outputs + * they source from. + */ + for (; attr < FRAG_ATTRIB_MAX; attr++) { + if (!(brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr))) + continue; + + /* _NEW_POINT */ + if (ctx->Point.PointSprite && + (attr >= FRAG_ATTRIB_TEX0 && attr <= FRAG_ATTRIB_TEX7) && + ctx->Point.CoordReplace[attr - FRAG_ATTRIB_TEX0]) { + dw16 |= (1 << input_index); + } + + if (attr == FRAG_ATTRIB_PNTC) + dw16 |= (1 << input_index); + + /* The hardware can only do the overrides on 16 overrides at a + * time, and the other up to 16 have to be lined up so that the + * input index = the output index. We'll need to do some + * tweaking to make sure that's the case. + */ + assert(input_index < 16 || attr == input_index); + + attr_overrides[input_index++] = get_attr_override(brw, attr, + two_side_color); + } + + for (; input_index < FRAG_ATTRIB_MAX; input_index++) + attr_overrides[input_index] = 0; + BEGIN_BATCH(20); OUT_BATCH(_3DSTATE_SF << 16 | (20 - 2)); OUT_BATCH(dw1); @@ -253,24 +278,7 @@ upload_sf_state(struct brw_context *brw) OUT_BATCH_F(ctx->Polygon.OffsetFactor); /* scale */ OUT_BATCH_F(0.0); /* XXX: global depth offset clamp */ for (i = 0; i < 8; i++) { - uint32_t attr_overrides = 0; - - for (; attr < 64; attr++) { - if (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr)) { - attr_overrides |= get_attr_override(brw, attr, two_side_color); - attr++; - break; - } - } - - for (; attr < 64; attr++) { - if (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr)) { - attr_overrides |= get_attr_override(brw, attr, two_side_color) << 16; - attr++; - break; - } - } - OUT_BATCH(attr_overrides); + OUT_BATCH(attr_overrides[i * 2] | attr_overrides[i * 2 + 1] << 16); } OUT_BATCH(dw16); /* point sprite texcoord bitmask */ OUT_BATCH(dw17); /* constant interp bitmask */ diff --git a/src/mesa/drivers/dri/i965/gen6_urb.c b/src/mesa/drivers/dri/i965/gen6_urb.c index 62645a6a30f..b4105111c8c 100644 --- a/src/mesa/drivers/dri/i965/gen6_urb.c +++ b/src/mesa/drivers/dri/i965/gen6_urb.c @@ -64,7 +64,7 @@ upload_urb(struct brw_context *brw) assert(brw->urb.nr_vs_entries % 4 == 0); assert(brw->urb.nr_gs_entries % 4 == 0); /* GS requirement */ - assert(!brw->gs.prog_bo || brw->urb.vs_size < 5); + assert(!brw->gs.prog_active || brw->urb.vs_size < 5); BEGIN_BATCH(3); OUT_BATCH(_3DSTATE_URB << 16 | (3 - 2)); diff --git a/src/mesa/drivers/dri/i965/gen6_viewport_state.c b/src/mesa/drivers/dri/i965/gen6_viewport_state.c index 4116bdb96de..c6c55c926c7 100644 --- a/src/mesa/drivers/dri/i965/gen6_viewport_state.c +++ b/src/mesa/drivers/dri/i965/gen6_viewport_state.c @@ -122,7 +122,8 @@ static void upload_viewport_state_pointers(struct brw_context *brw) const struct brw_tracked_state gen6_viewport_state = { .dirty = { .mesa = 0, - .brw = BRW_NEW_BATCH, + .brw = (BRW_NEW_BATCH | + BRW_NEW_STATE_BASE_ADDRESS), .cache = (CACHE_NEW_CLIP_VP | CACHE_NEW_SF_VP | CACHE_NEW_CC_VP) diff --git a/src/mesa/drivers/dri/i965/gen6_vs_state.c b/src/mesa/drivers/dri/i965/gen6_vs_state.c index b46368e36e2..022e23e12b0 100644 --- a/src/mesa/drivers/dri/i965/gen6_vs_state.c +++ b/src/mesa/drivers/dri/i965/gen6_vs_state.c @@ -110,7 +110,7 @@ const struct brw_tracked_state gen6_vs_constants = { .mesa = _NEW_TRANSFORM | _NEW_PROGRAM_CONSTANTS, .brw = (BRW_NEW_BATCH | BRW_NEW_VERTEX_PROGRAM), - .cache = 0, + .cache = CACHE_NEW_VS_PROG, }, .prepare = gen6_prepare_vs_push_constants, }; @@ -147,7 +147,7 @@ upload_vs_state(struct brw_context *brw) BEGIN_BATCH(6); OUT_BATCH(_3DSTATE_VS << 16 | (6 - 2)); - OUT_RELOC(brw->vs.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); + OUT_BATCH(brw->vs.prog_offset); OUT_BATCH((0 << GEN6_VS_SAMPLER_COUNT_SHIFT) | GEN6_VS_FLOATING_POINT_MODE_ALT | (brw->vs.nr_surfaces << GEN6_VS_BINDING_TABLE_ENTRY_COUNT_SHIFT)); @@ -165,8 +165,7 @@ upload_vs_state(struct brw_context *brw) const struct brw_tracked_state gen6_vs_state = { .dirty = { .mesa = _NEW_TRANSFORM | _NEW_PROGRAM_CONSTANTS, - .brw = (BRW_NEW_CURBE_OFFSETS | - BRW_NEW_NR_VS_SURFACES | + .brw = (BRW_NEW_NR_VS_SURFACES | BRW_NEW_URB_FENCE | BRW_NEW_CONTEXT | BRW_NEW_VERTEX_PROGRAM | diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c index 43e651db3ef..9ef6133e2b9 100644 --- a/src/mesa/drivers/dri/i965/gen6_wm_state.c +++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c @@ -39,6 +39,7 @@ gen6_prepare_wm_push_constants(struct brw_context *brw) { struct intel_context *intel = &brw->intel; struct gl_context *ctx = &intel->ctx; + /* BRW_NEW_FRAGMENT_PROGRAM */ const struct brw_fragment_program *fp = brw_fragment_program_const(brw->fragment_program); @@ -48,6 +49,7 @@ gen6_prepare_wm_push_constants(struct brw_context *brw) /* XXX: Should this happen somewhere before to get our state flag set? */ _mesa_load_state_parameters(ctx, fp->program.Base.Parameters); + /* CACHE_NEW_VS_PROG */ if (brw->wm.prog_data->nr_params != 0) { float *constants; unsigned int i; @@ -83,7 +85,7 @@ const struct brw_tracked_state gen6_wm_constants = { .mesa = _NEW_PROGRAM_CONSTANTS, .brw = (BRW_NEW_BATCH | BRW_NEW_FRAGMENT_PROGRAM), - .cache = 0, + .cache = CACHE_NEW_VS_PROG, }, .prepare = gen6_prepare_wm_push_constants, }; @@ -97,7 +99,7 @@ upload_wm_state(struct brw_context *brw) brw_fragment_program_const(brw->fragment_program); uint32_t dw2, dw4, dw5, dw6; - /* CACHE_NEW_WM_PROG */ + /* CACHE_NEW_WM_PROG */ if (brw->wm.prog_data->nr_params == 0) { /* Disable the push constant buffers. */ BEGIN_BATCH(5); @@ -157,7 +159,7 @@ upload_wm_state(struct brw_context *brw) if (ctx->Line.StippleFlag) dw5 |= GEN6_WM_LINE_STIPPLE_ENABLE; - /* _NEW_POLYGONSTIPPLE */ + /* _NEW_POLYGON */ if (ctx->Polygon.StippleFlag) dw5 |= GEN6_WM_POLYGON_STIPPLE_ENABLE; @@ -183,7 +185,7 @@ upload_wm_state(struct brw_context *brw) BEGIN_BATCH(9); OUT_BATCH(_3DSTATE_WM << 16 | (9 - 2)); - OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); + OUT_BATCH(brw->wm.prog_offset); OUT_BATCH(dw2); if (brw->wm.prog_data->total_scratch) { OUT_RELOC(brw->wm.scratch_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, @@ -195,21 +197,19 @@ upload_wm_state(struct brw_context *brw) OUT_BATCH(dw5); OUT_BATCH(dw6); OUT_BATCH(0); /* kernel 1 pointer */ - if (brw->wm.prog_data->prog_offset_16) { - OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, - brw->wm.prog_data->prog_offset_16); - } else { - OUT_BATCH(0); /* kernel 2 pointer */ - } + /* kernel 2 pointer */ + OUT_BATCH(brw->wm.prog_offset + brw->wm.prog_data->prog_offset_16); ADVANCE_BATCH(); } const struct brw_tracked_state gen6_wm_state = { .dirty = { - .mesa = (_NEW_LINE | _NEW_POLYGONSTIPPLE | _NEW_COLOR | _NEW_BUFFERS | - _NEW_PROGRAM_CONSTANTS | _NEW_POLYGON), - .brw = (BRW_NEW_CURBE_OFFSETS | - BRW_NEW_FRAGMENT_PROGRAM | + .mesa = (_NEW_LINE | + _NEW_COLOR | + _NEW_BUFFERS | + _NEW_PROGRAM_CONSTANTS | + _NEW_POLYGON), + .brw = (BRW_NEW_FRAGMENT_PROGRAM | BRW_NEW_NR_WM_SURFACES | BRW_NEW_URB_FENCE | BRW_NEW_BATCH), diff --git a/src/mesa/drivers/dri/i965/gen7_disable.c b/src/mesa/drivers/dri/i965/gen7_disable.c index 4e9461739d0..a44d31596b9 100644 --- a/src/mesa/drivers/dri/i965/gen7_disable.c +++ b/src/mesa/drivers/dri/i965/gen7_disable.c @@ -31,7 +31,7 @@ disable_stages(struct brw_context *brw) { struct intel_context *intel = &brw->intel; - assert(brw->gs.prog_bo == NULL); + assert(!brw->gs.prog_active); /* Disable the Geometry Shader (GS) Unit */ BEGIN_BATCH(7); diff --git a/src/mesa/drivers/dri/i965/gen7_misc_state.c b/src/mesa/drivers/dri/i965/gen7_misc_state.c index dd0ccd27193..7544f961da9 100644 --- a/src/mesa/drivers/dri/i965/gen7_misc_state.c +++ b/src/mesa/drivers/dri/i965/gen7_misc_state.c @@ -113,7 +113,7 @@ static void emit_depthbuffer(struct brw_context *brw) struct intel_region *region = drb->region; uint32_t tile_x, tile_y, offset; - offset = intel_region_tile_offsets(region, &tile_x, &tile_y); + offset = intel_renderbuffer_tile_offsets(drb, &tile_x, &tile_y); assert(region->tiling == I915_TILING_Y); diff --git a/src/mesa/drivers/dri/i965/gen7_urb.c b/src/mesa/drivers/dri/i965/gen7_urb.c index 3a614693dfc..2b650e9bc45 100644 --- a/src/mesa/drivers/dri/i965/gen7_urb.c +++ b/src/mesa/drivers/dri/i965/gen7_urb.c @@ -78,7 +78,7 @@ upload_urb(struct brw_context *brw) assert(brw->urb.nr_vs_entries % 8 == 0); assert(brw->urb.nr_gs_entries % 8 == 0); /* GS requirement */ - assert(!brw->gs.prog_bo); + assert(!brw->gs.prog_active); BEGIN_BATCH(2); OUT_BATCH(_3DSTATE_PUSH_CONSTANT_ALLOC_VS << 16 | (2 - 2)); diff --git a/src/mesa/drivers/dri/i965/gen7_vs_state.c b/src/mesa/drivers/dri/i965/gen7_vs_state.c index ae7a1d6c35c..0fad3d2fb68 100644 --- a/src/mesa/drivers/dri/i965/gen7_vs_state.c +++ b/src/mesa/drivers/dri/i965/gen7_vs_state.c @@ -67,7 +67,7 @@ upload_vs_state(struct brw_context *brw) BEGIN_BATCH(6); OUT_BATCH(_3DSTATE_VS << 16 | (6 - 2)); - OUT_RELOC(brw->vs.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); + OUT_BATCH(brw->vs.prog_offset); OUT_BATCH((0 << GEN6_VS_SAMPLER_COUNT_SHIFT) | GEN6_VS_FLOATING_POINT_MODE_ALT | (brw->vs.nr_surfaces << GEN6_VS_BINDING_TABLE_ENTRY_COUNT_SHIFT)); diff --git a/src/mesa/drivers/dri/i965/gen7_wm_state.c b/src/mesa/drivers/dri/i965/gen7_wm_state.c index 6a64eb8a2d3..17f75354f1d 100644 --- a/src/mesa/drivers/dri/i965/gen7_wm_state.c +++ b/src/mesa/drivers/dri/i965/gen7_wm_state.c @@ -36,6 +36,7 @@ gen7_prepare_wm_constants(struct brw_context *brw) { struct intel_context *intel = &brw->intel; struct gl_context *ctx = &intel->ctx; + /* BRW_NEW_FRAGMENT_PROGRAM */ const struct brw_fragment_program *fp = brw_fragment_program_const(brw->fragment_program); @@ -45,7 +46,7 @@ gen7_prepare_wm_constants(struct brw_context *brw) /* XXX: Should this happen somewhere before to get our state flag set? */ _mesa_load_state_parameters(ctx, fp->program.Base.Parameters); - /* BRW_NEW_FRAGMENT_PROGRAM */ + /* CACHE_NEW_WM_PROG */ if (brw->wm.prog_data->nr_params != 0) { float *constants; unsigned int i; @@ -80,7 +81,7 @@ const struct brw_tracked_state gen7_wm_constants = { .dirty = { .mesa = _NEW_PROGRAM_CONSTANTS, .brw = (BRW_NEW_BATCH | BRW_NEW_FRAGMENT_PROGRAM), - .cache = 0, + .cache = CACHE_NEW_WM_PROG, }, .prepare = gen7_prepare_wm_constants, }; @@ -104,7 +105,7 @@ upload_wm_state(struct brw_context *brw) if (ctx->Line.StippleFlag) dw1 |= GEN7_WM_LINE_STIPPLE_ENABLE; - /* _NEW_POLYGONSTIPPLE */ + /* _NEW_POLYGON */ if (ctx->Polygon.StippleFlag) dw1 |= GEN7_WM_POLYGON_STIPPLE_ENABLE; @@ -227,24 +228,21 @@ upload_ps_state(struct brw_context *brw) BEGIN_BATCH(8); OUT_BATCH(_3DSTATE_PS << 16 | (8 - 2)); - OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); + OUT_BATCH(brw->wm.prog_offset); OUT_BATCH(dw2); OUT_BATCH(0); /* scratch space base offset */ OUT_BATCH(dw4); OUT_BATCH(dw5); OUT_BATCH(0); /* kernel 1 pointer */ - if (brw->wm.prog_data->prog_offset_16) { - OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, - brw->wm.prog_data->prog_offset_16); - } else { - OUT_BATCH(0); /* kernel 2 pointer */ - } + OUT_BATCH(brw->wm.prog_offset + brw->wm.prog_data->prog_offset_16); ADVANCE_BATCH(); } const struct brw_tracked_state gen7_ps_state = { .dirty = { - .mesa = (_NEW_LINE | _NEW_POLYGON | _NEW_POLYGONSTIPPLE | + .mesa = (_NEW_LINE | + _NEW_POLYGON | + _NEW_POLYGONSTIPPLE | _NEW_PROGRAM_CONSTANTS), .brw = (BRW_NEW_CURBE_OFFSETS | BRW_NEW_FRAGMENT_PROGRAM | diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c index 00b562f2176..9994b67bfc5 100644 --- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c @@ -273,7 +273,7 @@ gen7_update_renderbuffer_surface(struct brw_context *brw, surf->ss0.surface_type = BRW_SURFACE_2D; /* reloc */ - surf->ss1.base_addr = intel_region_tile_offsets(region, &tile_x, &tile_y); + surf->ss1.base_addr = intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y); surf->ss1.base_addr += region->buffer->offset; /* reloc */ assert(brw->has_surface_tile_offset); diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c index 77edc3a6bfe..735382902d1 100644 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c @@ -53,6 +53,22 @@ static void clear_cache( struct intel_context *intel ) } void +intel_batchbuffer_init(struct intel_context *intel) +{ + intel_batchbuffer_reset(intel); + + if (intel->gen == 6) { + /* We can't just use brw_state_batch to get a chunk of space for + * the gen6 workaround because it involves actually writing to + * the buffer, and the kernel doesn't let us write to the batch. + */ + intel->batch.workaround_bo = drm_intel_bo_alloc(intel->bufmgr, + "gen6 workaround", + 4096, 4096); + } +} + +void intel_batchbuffer_reset(struct intel_context *intel) { if (intel->batch.last_bo != NULL) { @@ -76,6 +92,7 @@ intel_batchbuffer_free(struct intel_context *intel) { drm_intel_bo_unreference(intel->batch.last_bo); drm_intel_bo_unreference(intel->batch.bo); + drm_intel_bo_unreference(intel->batch.workaround_bo); clear_cache(intel); } @@ -276,6 +293,43 @@ emit: item->header = intel->batch.emit; } +/** + * Emits a PIPE_CONTROL with a non-zero post-sync operation, for + * implementing two workarounds on gen6. From section 1.4.7.1 + * "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1: + * + * [DevSNB-C+{W/A}] Before any depth stall flush (including those + * produced by non-pipelined state commands), software needs to first + * send a PIPE_CONTROL with no bits set except Post-Sync Operation != + * 0. + * + * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache Flush Enable + * =1, a PIPE_CONTROL with any non-zero post-sync-op is required. + * + * XXX: There is also a workaround that would appear to apply to this + * workaround, but it doesn't appear to be necessary so far: + * + * Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent + * BEFORE the pipe-control with a post-sync op and no write-cache + * flushes. + */ +void +intel_emit_post_sync_nonzero_flush(struct intel_context *intel) +{ + if (!intel->batch.need_workaround_flush) + return; + + BEGIN_BATCH(4); + OUT_BATCH(_3DSTATE_PIPE_CONTROL); + OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE); + OUT_RELOC(intel->batch.workaround_bo, + I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT, 0); + OUT_BATCH(0); /* write data */ + ADVANCE_BATCH(); + + intel->batch.need_workaround_flush = false; +} + /* Emit a pipelined flush to either flush render and texture cache for * reading from a FBO-drawn texture, or flush so that frontbuffer * render appears on the screen in DRI1. @@ -294,15 +348,17 @@ intel_batchbuffer_emit_mi_flush(struct intel_context *intel) OUT_BATCH(0); ADVANCE_BATCH(); } else { - BEGIN_BATCH(8); - /* XXX workaround: issue any post sync != 0 before write - * cache flush = 1 - */ - OUT_BATCH(_3DSTATE_PIPE_CONTROL); - OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE); - OUT_BATCH(0); /* write address */ - OUT_BATCH(0); /* write data */ + if (intel->gen == 6) { + /* Hardware workaround: SNB B-Spec says: + * + * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache + * Flush Enable =1, a PIPE_CONTROL with any non-zero + * post-sync-op is required. + */ + intel_emit_post_sync_nonzero_flush(intel); + } + BEGIN_BATCH(4); OUT_BATCH(_3DSTATE_PIPE_CONTROL); OUT_BATCH(PIPE_CONTROL_INSTRUCTION_FLUSH | PIPE_CONTROL_WRITE_FLUSH | diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h index a0a5c9841c6..fb4134d889e 100644 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.h @@ -9,6 +9,7 @@ #define BATCH_RESERVED 16 +void intel_batchbuffer_init(struct intel_context *intel); void intel_batchbuffer_reset(struct intel_context *intel); void intel_batchbuffer_free(struct intel_context *intel); @@ -38,6 +39,7 @@ GLboolean intel_batchbuffer_emit_reloc_fenced(struct intel_context *intel, uint32_t write_domain, uint32_t offset); void intel_batchbuffer_emit_mi_flush(struct intel_context *intel); +void intel_emit_post_sync_nonzero_flush(struct intel_context *intel); static INLINE uint32_t float_as_int(float f) { diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index 5aac1f6fa24..30be1b9382f 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -280,10 +280,10 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask) write_buffer = intel_region_buffer(intel, irb->region, all ? INTEL_WRITE_FULL : INTEL_WRITE_PART); - x1 = cx + irb->region->draw_x; - y1 = cy + irb->region->draw_y; - x2 = cx + cw + irb->region->draw_x; - y2 = cy + ch + irb->region->draw_y; + x1 = cx + irb->draw_x; + y1 = cy + irb->draw_y; + x2 = cx + cw + irb->draw_x; + y2 = cy + ch + irb->draw_y; pitch = irb->region->pitch; cpp = irb->region->cpp; diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index 7eb50edc6b4..a52a07cd93a 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -28,7 +28,9 @@ #include "intel_context.h" #include "intel_buffers.h" #include "intel_fbo.h" + #include "main/framebuffer.h" +#include "main/renderbuffer.h" /** * Return pointer to current color drawing region, or NULL. @@ -100,6 +102,28 @@ intel_draw_buffer(struct gl_context * ctx, struct gl_framebuffer *fb) return; } + /* + * If intel_context is using separate stencil, but the depth attachment + * (gl_framebuffer.Attachment[BUFFER_DEPTH]) has a packed depth/stencil + * format, then we must install the real depth buffer at fb->_DepthBuffer + * and set fb->_DepthBuffer->Wrapped before calling _mesa_update_framebuffer. + * Otherwise, _mesa_update_framebuffer will create and install a swras + * depth wrapper instead. + * + * Ditto for stencil. + */ + irbDepth = intel_get_renderbuffer(fb, BUFFER_DEPTH); + if (irbDepth && irbDepth->Base.Format == MESA_FORMAT_X8_Z24) { + _mesa_reference_renderbuffer(&fb->_DepthBuffer, &irbDepth->Base); + irbDepth->Base.Wrapped = fb->Attachment[BUFFER_DEPTH].Renderbuffer; + } + + irbStencil = intel_get_renderbuffer(fb, BUFFER_STENCIL); + if (irbStencil && irbStencil->Base.Format == MESA_FORMAT_S8) { + _mesa_reference_renderbuffer(&fb->_StencilBuffer, &irbStencil->Base); + irbStencil->Base.Wrapped = fb->Attachment[BUFFER_STENCIL].Renderbuffer; + } + /* Do this here, not core Mesa, since this function is called from * many places within the driver. */ @@ -165,47 +189,33 @@ intel_draw_buffer(struct gl_context * ctx, struct gl_framebuffer *fb) FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); } - /*** - *** Get depth buffer region and check if we need a software fallback. - ***/ - if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) { - irbDepth = intel_renderbuffer(fb->_DepthBuffer->Wrapped); - if (irbDepth && irbDepth->region) { - assert(!fb_has_hiz || irbDepth->Base.Format != MESA_FORMAT_S8_Z24); - FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE); - depthRegion = irbDepth->region; - } - else { - FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE); - depthRegion = NULL; - } - } - else { - /* not using depth buffer */ + /* Check for depth fallback. */ + if (irbDepth && irbDepth->region) { + assert(!fb_has_hiz || irbDepth->Base.Format != MESA_FORMAT_S8_Z24); + FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE); + depthRegion = irbDepth->region; + } else if (irbDepth && !irbDepth->region) { + FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE); + depthRegion = NULL; + } else { /* !irbDepth */ + /* No fallback is needed because there is no depth buffer. */ FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE); depthRegion = NULL; } - /*** - *** Stencil buffer - ***/ - if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { - irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped); - if (irbStencil && irbStencil->region) { - if (!intel->has_separate_stencil) - assert(irbStencil->Base.Format == MESA_FORMAT_S8_Z24); - if (fb_has_hiz || intel->must_use_separate_stencil) - assert(irbStencil->Base.Format == MESA_FORMAT_S8); - if (irbStencil->Base.Format == MESA_FORMAT_S8) - assert(intel->has_separate_stencil); - FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); - } - else { - FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE); - } - } - else { - /* XXX FBO: instead of FALSE, pass ctx->Stencil._Enabled ??? */ + /* Check for stencil fallback. */ + if (irbStencil && irbStencil->region) { + if (!intel->has_separate_stencil) + assert(irbStencil->Base.Format == MESA_FORMAT_S8_Z24); + if (fb_has_hiz || intel->must_use_separate_stencil) + assert(irbStencil->Base.Format == MESA_FORMAT_S8); + if (irbStencil->Base.Format == MESA_FORMAT_S8) + assert(intel->has_separate_stencil); + FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); + } else if (irbStencil && !irbStencil->region) { + FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE); + } else { /* !irbStencil */ + /* No fallback is needed because there is no stencil buffer. */ FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); } diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 0c2ba413ad7..70aee52bd14 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -504,10 +504,7 @@ intelInvalidateState(struct gl_context * ctx, GLuint new_state) struct intel_context *intel = intel_context(ctx); _swrast_InvalidateState(ctx, new_state); - _swsetup_InvalidateState(ctx, new_state); _vbo_InvalidateState(ctx, new_state); - _tnl_InvalidateState(ctx, new_state); - _tnl_invalidate_vertex_state(ctx, new_state); intel->NewGLState |= new_state; @@ -663,7 +660,7 @@ intelInitContext(struct intel_context *intel, ctx->TextureFormatSupported[MESA_FORMAT_AL1616] = GL_TRUE; /* Depth and stencil */ - ctx->TextureFormatSupported[MESA_FORMAT_S8_Z24] = !intel->must_use_separate_stencil; + ctx->TextureFormatSupported[MESA_FORMAT_S8_Z24] = GL_TRUE; ctx->TextureFormatSupported[MESA_FORMAT_X8_Z24] = intel->has_separate_stencil; ctx->TextureFormatSupported[MESA_FORMAT_S8] = intel->has_separate_stencil; @@ -854,7 +851,7 @@ intelInitContext(struct intel_context *intel, if (INTEL_DEBUG & DEBUG_BUFMGR) dri_bufmgr_set_debug(intel->bufmgr, GL_TRUE); - intel_batchbuffer_reset(intel); + intel_batchbuffer_init(intel); intel_fbo_init(intel); diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index 80dee4ef38e..148fb0c2c9a 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -181,6 +181,9 @@ struct intel_context drm_intel_bo *bo; /** Last BO submitted to the hardware. Used for glFinish(). */ drm_intel_bo *last_bo; + /** BO for post-sync nonzero writes for gen6 workaround. */ + drm_intel_bo *workaround_bo; + bool need_workaround_flush; struct cached_batch_item *cached_items; diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c index 3fd987abd8c..64c996ca5cd 100644 --- a/src/mesa/drivers/dri/intel/intel_extensions.c +++ b/src/mesa/drivers/dri/intel/intel_extensions.c @@ -172,6 +172,7 @@ static const struct dri_extension brw_extensions[] = { { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions }, { "GL_ARB_point_sprite", NULL }, { "GL_ARB_seamless_cube_map", NULL }, + { "GL_ARB_shader_texture_lod", NULL }, { "GL_ARB_shadow", NULL }, #ifdef TEXTURE_FLOAT_ENABLED { "GL_ARB_texture_float", NULL }, diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index 83f622d437e..90c3909d1d8 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -35,7 +35,7 @@ #include "main/renderbuffer.h" #include "main/context.h" #include "main/teximage.h" -#include "main/texrender.h" +#include "swrast/swrast.h" #include "drivers/common/meta.h" #include "intel_context.h" @@ -82,6 +82,12 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb) if (intel && irb->hiz_region) { intel_region_release(&irb->hiz_region); } + if (intel && irb->wrapped_depth) { + _mesa_reference_renderbuffer(&irb->wrapped_depth, NULL); + } + if (intel && irb->wrapped_stencil) { + _mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL); + } free(irb); } @@ -105,7 +111,7 @@ intel_get_pointer(struct gl_context * ctx, struct gl_renderbuffer *rb, * Called via glRenderbufferStorageEXT() to set the format and allocate * storage for a user-created renderbuffer. */ -static GLboolean +GLboolean intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) @@ -141,6 +147,8 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer break; } + rb->Width = width; + rb->Height = height; rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); rb->DataType = intel_mesa_format_to_rb_datatype(rb->Format); cpp = _mesa_get_format_bytes(rb->Format); @@ -190,32 +198,63 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer width, height / 2, GL_TRUE); + if (!irb->region) + return false; + + } else if (irb->Base.Format == MESA_FORMAT_S8_Z24 + && intel->must_use_separate_stencil) { + + bool ok = true; + struct gl_renderbuffer *depth_rb; + struct gl_renderbuffer *stencil_rb; + + depth_rb = intel_create_wrapped_renderbuffer(ctx, width, height, + MESA_FORMAT_X8_Z24); + stencil_rb = intel_create_wrapped_renderbuffer(ctx, width, height, + MESA_FORMAT_S8); + ok = depth_rb && stencil_rb; + ok = ok && intel_alloc_renderbuffer_storage(ctx, depth_rb, + depth_rb->InternalFormat, + width, height); + ok = ok && intel_alloc_renderbuffer_storage(ctx, stencil_rb, + stencil_rb->InternalFormat, + width, height); + + if (!ok) { + if (depth_rb) { + intel_delete_renderbuffer(depth_rb); + } + if (stencil_rb) { + intel_delete_renderbuffer(stencil_rb); + } + return false; + } + + depth_rb->Wrapped = rb; + stencil_rb->Wrapped = rb; + _mesa_reference_renderbuffer(&irb->wrapped_depth, depth_rb); + _mesa_reference_renderbuffer(&irb->wrapped_stencil, stencil_rb); + } else { irb->region = intel_region_alloc(intel->intelScreen, tiling, cpp, width, height, GL_TRUE); - } - - if (!irb->region) - return GL_FALSE; /* out of memory? */ - - ASSERT(irb->region->buffer); - - if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)) { - irb->hiz_region = intel_region_alloc(intel->intelScreen, - I915_TILING_Y, - irb->region->cpp, - irb->region->width, - irb->region->height, - GL_TRUE); - if (!irb->hiz_region) { - intel_region_release(&irb->region); - return GL_FALSE; + if (!irb->region) + return false; + + if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)) { + irb->hiz_region = intel_region_alloc(intel->intelScreen, + I915_TILING_Y, + irb->region->cpp, + irb->region->width, + irb->region->height, + GL_TRUE); + if (!irb->hiz_region) { + intel_region_release(&irb->region); + return false; + } } } - rb->Width = width; - rb->Height = height; - return GL_TRUE; } @@ -366,6 +405,37 @@ intel_create_renderbuffer(gl_format format) } +struct gl_renderbuffer* +intel_create_wrapped_renderbuffer(struct gl_context * ctx, + int width, int height, + gl_format format) +{ + /* + * The name here is irrelevant, as long as its nonzero, because the + * renderbuffer never gets entered into Mesa's renderbuffer hash table. + */ + GLuint name = ~0; + + struct intel_renderbuffer *irb = CALLOC_STRUCT(intel_renderbuffer); + if (!irb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); + return NULL; + } + + struct gl_renderbuffer *rb = &irb->Base; + _mesa_init_renderbuffer(rb, name); + rb->ClassID = INTEL_RB_CLASS; + rb->_BaseFormat = _mesa_get_format_base_format(format); + rb->Format = format; + rb->InternalFormat = rb->_BaseFormat; + rb->DataType = intel_mesa_format_to_rb_datatype(format); + rb->Width = width; + rb->Height = height; + + return rb; +} + + /** * Create a new renderbuffer object. * Typically called via glBindRenderbufferEXT(). @@ -427,6 +497,10 @@ intel_framebuffer_renderbuffer(struct gl_context * ctx, intel_draw_buffer(ctx, fb); } +static bool +intel_update_tex_wrapper_regions(struct intel_context *intel, + struct intel_renderbuffer *irb, + struct intel_texture_image *intel_image); static GLboolean intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb, @@ -453,6 +527,49 @@ intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb, irb->Base.Delete = intel_delete_renderbuffer; irb->Base.AllocStorage = intel_nop_alloc_storage; + if (intel_image->stencil_rb) { + /* The tex image has packed depth/stencil format, but is using separate + * stencil. */ + + bool ok; + struct intel_renderbuffer *depth_irb = + intel_renderbuffer(intel_image->depth_rb); + + /* Update the hiz region if necessary. */ + ok = intel_update_tex_wrapper_regions(intel, depth_irb, intel_image); + if (!ok) { + return false; + } + + /* The tex image shares its embedded depth and stencil renderbuffers with + * the renderbuffer wrapper. */ + if (irb->wrapped_depth != intel_image->depth_rb) { + _mesa_reference_renderbuffer(&irb->wrapped_depth, + intel_image->depth_rb); + } + if (irb->wrapped_stencil != intel_image->stencil_rb) { + _mesa_reference_renderbuffer(&irb->wrapped_stencil, + intel_image->stencil_rb); + } + + return true; + + } else { + return intel_update_tex_wrapper_regions(intel, irb, intel_image); + } +} + +/** + * FIXME: The handling of the hiz region is broken for mipmapped depth textures + * FIXME: because intel_finalize_mipmap_tree is unaware of it. + */ +static bool +intel_update_tex_wrapper_regions(struct intel_context *intel, + struct intel_renderbuffer *irb, + struct intel_texture_image *intel_image) +{ + struct gl_renderbuffer *rb = &irb->Base; + /* Point the renderbuffer's region to the texture's region. */ if (irb->region != intel_image->mt->region) { intel_region_release(&irb->region); @@ -460,14 +577,14 @@ intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb, } /* Allocate the texture's hiz region if necessary. */ - if (intel->vtbl.is_hiz_depth_format(intel, texImage->TexFormat) + if (intel->vtbl.is_hiz_depth_format(intel, rb->Format) && !intel_image->mt->hiz_region) { intel_image->mt->hiz_region = intel_region_alloc(intel->intelScreen, I915_TILING_Y, - _mesa_get_format_bytes(texImage->TexFormat), - texImage->Width, - texImage->Height, + _mesa_get_format_bytes(rb->Format), + rb->Width, + rb->Height, GL_TRUE); if (!intel_image->mt->hiz_region) return GL_FALSE; @@ -512,9 +629,10 @@ intel_wrap_texture(struct gl_context * ctx, struct gl_texture_image *texImage) return irb; } -static void -intel_set_draw_offset_for_image(struct intel_texture_image *intel_image, - int zoffset) +void +intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb, + struct intel_texture_image *intel_image, + int zoffset) { struct intel_mipmap_tree *mt = intel_image->mt; unsigned int dst_x, dst_y; @@ -526,9 +644,45 @@ intel_set_draw_offset_for_image(struct intel_texture_image *intel_image, zoffset, &dst_x, &dst_y); - mt->region->draw_offset = (dst_y * mt->region->pitch + dst_x) * mt->cpp; - mt->region->draw_x = dst_x; - mt->region->draw_y = dst_y; + irb->draw_offset = (dst_y * mt->region->pitch + dst_x) * mt->cpp; + irb->draw_x = dst_x; + irb->draw_y = dst_y; +} + +/** + * Rendering to tiled buffers requires that the base address of the + * buffer be aligned to a page boundary. We generally render to + * textures by pointing the surface at the mipmap image level, which + * may not be aligned to a tile boundary. + * + * This function returns an appropriately-aligned base offset + * according to the tiling restrictions, plus any required x/y offset + * from there. + */ +uint32_t +intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb, + uint32_t *tile_x, + uint32_t *tile_y) +{ + int cpp = irb->region->cpp; + uint32_t pitch = irb->region->pitch * cpp; + + if (irb->region->tiling == I915_TILING_NONE) { + *tile_x = 0; + *tile_y = 0; + return irb->draw_x * cpp + irb->draw_y * pitch; + } else if (irb->region->tiling == I915_TILING_X) { + *tile_x = irb->draw_x % (512 / cpp); + *tile_y = irb->draw_y % 8; + return ((irb->draw_y / 8) * (8 * pitch) + + (irb->draw_x - *tile_x) / (512 / cpp) * 4096); + } else { + assert(irb->region->tiling == I915_TILING_Y); + *tile_x = irb->draw_x % (128 / cpp); + *tile_y = irb->draw_y % 32; + return ((irb->draw_y / 32) * (32 * pitch) + + (irb->draw_x - *tile_x) / (128 / cpp) * 4096); + } } /** @@ -542,54 +696,50 @@ intel_render_texture(struct gl_context * ctx, struct gl_framebuffer *fb, struct gl_renderbuffer_attachment *att) { - struct gl_texture_image *newImage - = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; + struct gl_texture_image *image = _mesa_get_attachment_teximage(att); struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); - struct intel_texture_image *intel_image; + struct intel_texture_image *intel_image = intel_texture_image(image); (void) fb; - ASSERT(newImage); - - intel_image = intel_texture_image(newImage); if (!intel_image->mt) { /* Fallback on drawing to a texture that doesn't have a miptree * (has a border, width/height 0, etc.) */ _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); - _mesa_render_texture(ctx, fb, att); + _swrast_render_texture(ctx, fb, att); return; } else if (!irb) { - irb = intel_wrap_texture(ctx, newImage); + irb = intel_wrap_texture(ctx, image); if (irb) { /* bind the wrapper to the attachment point */ _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base); } else { /* fallback to software rendering */ - _mesa_render_texture(ctx, fb, att); + _swrast_render_texture(ctx, fb, att); return; } } - if (!intel_update_wrapper(ctx, irb, newImage)) { + if (!intel_update_wrapper(ctx, irb, image)) { _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); - _mesa_render_texture(ctx, fb, att); + _swrast_render_texture(ctx, fb, att); return; } DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n", _glthread_GetID(), - att->Texture->Name, newImage->Width, newImage->Height, + att->Texture->Name, image->Width, image->Height, irb->Base.RefCount); - intel_set_draw_offset_for_image(intel_image, att->Zoffset); + intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset); intel_image->used_as_render_target = GL_TRUE; #ifndef I915 if (!brw_context(ctx)->has_surface_tile_offset && - (intel_image->mt->region->draw_offset & 4095) != 0) { + (irb->draw_offset & 4095) != 0) { /* Original gen4 hardware couldn't draw to a non-tile-aligned * destination in a miptree unless you actually setup your * renderbuffer as a miptree and used the fragile @@ -600,22 +750,15 @@ intel_render_texture(struct gl_context * ctx, struct intel_context *intel = intel_context(ctx); struct intel_mipmap_tree *old_mt = intel_image->mt; struct intel_mipmap_tree *new_mt; - int comp_byte = 0, texel_bytes; - - if (_mesa_is_format_compressed(intel_image->base.TexFormat)) - comp_byte = intel_compressed_num_bytes(intel_image->base.TexFormat); - texel_bytes = _mesa_get_format_bytes(intel_image->base.TexFormat); - - new_mt = intel_miptree_create(intel, newImage->TexObject->Target, - intel_image->base._BaseFormat, - intel_image->base.InternalFormat, + new_mt = intel_miptree_create(intel, image->TexObject->Target, + intel_image->base.TexFormat, intel_image->level, intel_image->level, intel_image->base.Width, intel_image->base.Height, intel_image->base.Depth, - texel_bytes, comp_byte, GL_TRUE); + GL_TRUE); intel_miptree_image_copy(intel, new_mt, @@ -625,7 +768,7 @@ intel_render_texture(struct gl_context * ctx, intel_miptree_release(intel, &intel_image->mt); intel_image->mt = new_mt; - intel_set_draw_offset_for_image(intel_image, att->Zoffset); + intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset); intel_region_release(&irb->region); intel_region_reference(&irb->region, intel_image->mt->region); @@ -693,16 +836,9 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) else depth_stencil_are_same = false; - bool fb_has_combined_depth_stencil_format = - (depthRb && depthRb->Base.Format == MESA_FORMAT_S8_Z24) || - (stencilRb && stencilRb->Base.Format == MESA_FORMAT_S8_Z24); - - bool fb_has_hiz = intel_framebuffer_has_hiz(fb); - - if ((intel->must_use_separate_stencil || fb_has_hiz) - && (depth_stencil_are_same || fb_has_combined_depth_stencil_format)) { - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; - } else if (!intel->has_separate_stencil && depthRb && stencilRb && !depth_stencil_are_same) { + if (!intel->has_separate_stencil + && depthRb && stencilRb + && !depth_stencil_are_same) { fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; } diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h index e9929b095ff..cbf29c86257 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.h +++ b/src/mesa/drivers/dri/intel/intel_fbo.h @@ -33,6 +33,7 @@ #include "intel_screen.h" struct intel_context; +struct intel_texture_image; /** * Intel renderbuffer, derived from gl_renderbuffer. @@ -44,6 +45,21 @@ struct intel_renderbuffer /** Only used by depth renderbuffers for which HiZ is enabled. */ struct intel_region *hiz_region; + + /** + * \name Packed depth/stencil unwrappers + * + * If the intel_context is using separate stencil and this renderbuffer has + * a a packed depth/stencil format, then wrapped_depth and wrapped_stencil + * are the real renderbuffers. + */ + struct gl_renderbuffer *wrapped_depth; + struct gl_renderbuffer *wrapped_stencil; + + /** \} */ + + GLuint draw_offset; /**< Offset of drawing address within the region */ + GLuint draw_x, draw_y; /**< Offset of drawing within the region */ }; @@ -73,15 +89,47 @@ intel_renderbuffer(struct gl_renderbuffer *rb) /** - * Return a framebuffer's renderbuffer, named by a BUFFER_x index. + * \brief Return the framebuffer attachment specified by attIndex. + * + * If the framebuffer lacks the specified attachment, then return null. + * + * If the attached renderbuffer is a wrapper, then return wrapped + * renderbuffer. */ static INLINE struct intel_renderbuffer * -intel_get_renderbuffer(struct gl_framebuffer *fb, int attIndex) +intel_get_renderbuffer(struct gl_framebuffer *fb, gl_buffer_index attIndex) { - if (attIndex >= 0) - return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer); - else + struct gl_renderbuffer *rb; + struct intel_renderbuffer *irb; + + /* XXX: Who passes -1 to intel_get_renderbuffer? */ + if (attIndex < 0) + return NULL; + + rb = fb->Attachment[attIndex].Renderbuffer; + if (!rb) return NULL; + + irb = intel_renderbuffer(rb); + if (!irb) + return NULL; + + switch (attIndex) { + case BUFFER_DEPTH: + if (irb->wrapped_depth) { + irb = intel_renderbuffer(irb->wrapped_depth); + } + break; + case BUFFER_STENCIL: + if (irb->wrapped_stencil) { + irb = intel_renderbuffer(irb->wrapped_stencil); + } + break; + default: + break; + } + + return irb; } /** @@ -122,6 +170,16 @@ intel_renderbuffer_set_hiz_region(struct intel_context *intel, extern struct intel_renderbuffer * intel_create_renderbuffer(gl_format format); +struct gl_renderbuffer* +intel_create_wrapped_renderbuffer(struct gl_context * ctx, + int width, int height, + gl_format format); + +GLboolean +intel_alloc_renderbuffer_storage(struct gl_context * ctx, + struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height); extern void intel_fbo_init(struct intel_context *intel); @@ -130,6 +188,15 @@ intel_fbo_init(struct intel_context *intel); extern void intel_flip_renderbuffers(struct gl_framebuffer *fb); +void +intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb, + struct intel_texture_image *intel_image, + int zoffset); + +uint32_t +intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb, + uint32_t *tile_x, + uint32_t *tile_y); static INLINE struct intel_region * intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) @@ -141,5 +208,4 @@ intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) return NULL; } - #endif /* INTEL_FBO_H */ diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index e62905de7c3..4e711de1ce1 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -29,6 +29,7 @@ #include "intel_mipmap_tree.h" #include "intel_regions.h" #include "intel_tex_layout.h" +#include "intel_tex.h" #include "main/enums.h" #include "main/formats.h" @@ -55,30 +56,34 @@ target_to_target(GLenum target) static struct intel_mipmap_tree * intel_miptree_create_internal(struct intel_context *intel, GLenum target, - GLenum internal_format, + gl_format format, GLuint first_level, GLuint last_level, GLuint width0, GLuint height0, - GLuint depth0, GLuint cpp, GLuint compress_byte, + GLuint depth0, uint32_t tiling) { GLboolean ok; struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); + int compress_byte = 0; DBG("%s target %s format %s level %d..%d <-- %p\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), - _mesa_lookup_enum_by_nr(internal_format), + _mesa_get_format_name(format), first_level, last_level, mt); + if (_mesa_is_format_compressed(format)) + compress_byte = intel_compressed_num_bytes(format); + mt->target = target_to_target(target); - mt->internal_format = internal_format; + mt->format = format; mt->first_level = first_level; mt->last_level = last_level; mt->width0 = width0; mt->height0 = height0; mt->depth0 = depth0; - mt->cpp = compress_byte ? compress_byte : cpp; + mt->cpp = compress_byte ? compress_byte : _mesa_get_format_bytes(mt->format); mt->compressed = compress_byte ? 1 : 0; mt->refcount = 1; @@ -104,19 +109,19 @@ intel_miptree_create_internal(struct intel_context *intel, struct intel_mipmap_tree * intel_miptree_create(struct intel_context *intel, GLenum target, - GLenum base_format, - GLenum internal_format, + gl_format format, GLuint first_level, GLuint last_level, GLuint width0, GLuint height0, - GLuint depth0, GLuint cpp, GLuint compress_byte, + GLuint depth0, GLboolean expect_accelerated_upload) { struct intel_mipmap_tree *mt; uint32_t tiling = I915_TILING_NONE; + GLenum base_format = _mesa_get_format_base_format(format); - if (intel->use_texture_tiling && compress_byte == 0) { + if (intel->use_texture_tiling && !_mesa_is_format_compressed(format)) { if (intel->gen >= 4 && (base_format == GL_DEPTH_COMPONENT || base_format == GL_DEPTH_STENCIL_EXT)) @@ -125,9 +130,9 @@ intel_miptree_create(struct intel_context *intel, tiling = I915_TILING_X; } - mt = intel_miptree_create_internal(intel, target, internal_format, + mt = intel_miptree_create_internal(intel, target, format, first_level, last_level, width0, - height0, depth0, cpp, compress_byte, + height0, depth0, tiling); /* * pitch == 0 || height == 0 indicates the null texture @@ -156,17 +161,15 @@ intel_miptree_create(struct intel_context *intel, struct intel_mipmap_tree * intel_miptree_create_for_region(struct intel_context *intel, GLenum target, - GLenum internal_format, + gl_format format, struct intel_region *region, - GLuint depth0, - GLuint compress_byte) + GLuint depth0) { struct intel_mipmap_tree *mt; - mt = intel_miptree_create_internal(intel, target, internal_format, + mt = intel_miptree_create_internal(intel, target, format, 0, 0, region->width, region->height, 1, - region->cpp, compress_byte, I915_TILING_NONE); if (!mt) return mt; @@ -223,7 +226,6 @@ GLboolean intel_miptree_match_image(struct intel_mipmap_tree *mt, struct gl_texture_image *image) { - GLboolean isCompressed = _mesa_is_format_compressed(image->TexFormat); struct intel_texture_image *intelImage = intel_texture_image(image); GLuint level = intelImage->level; @@ -231,13 +233,7 @@ intel_miptree_match_image(struct intel_mipmap_tree *mt, if (image->Border) return GL_FALSE; - if (image->InternalFormat != mt->internal_format || - isCompressed != mt->compressed) - return GL_FALSE; - - if (!isCompressed && - !mt->compressed && - _mesa_get_format_bytes(image->TexFormat) != mt->cpp) + if (image->TexFormat != mt->format) return GL_FALSE; /* Test image dimensions against the base level image adjusted for @@ -389,26 +385,32 @@ intel_miptree_image_data(struct intel_context *intel, GLuint i; for (i = 0; i < depth; i++) { - GLuint dst_x, dst_y, height; + GLuint dst_x, dst_y, height, width; intel_miptree_get_image_offset(dst, level, face, i, &dst_x, &dst_y); height = dst->level[level].height; - if(dst->compressed) - height = (height + 3) / 4; + width = dst->level[level].width; + if (dst->compressed) { + unsigned int align_w, align_h; + + intel_get_texture_alignment_unit(dst->format, &align_w, &align_h); + height = (height + align_h - 1) / align_h; + width = ALIGN(width, align_w); + } DBG("%s: %d/%d %p/%d -> (%d, %d)/%d (%d, %d)\n", __FUNCTION__, face, level, src, src_row_pitch * dst->cpp, dst_x, dst_y, dst->region->pitch * dst->cpp, - dst->level[level].width, height); + width, height); intel_region_data(intel, dst->region, 0, dst_x, dst_y, src, src_row_pitch, 0, 0, /* source x, y */ - dst->level[level].width, height); /* width, height */ + width, height); src = (char *)src + src_image_pitch * dst->cpp; } @@ -434,8 +436,7 @@ intel_miptree_image_copy(struct intel_context *intel, if (dst->compressed) { GLuint align_w, align_h; - intel_get_texture_alignment_unit(dst->internal_format, - &align_w, &align_h); + intel_get_texture_alignment_unit(dst->format, &align_w, &align_h); height = (height + 3) / 4; width = ALIGN(width, align_w); } diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index 325e3916981..ea865904f68 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -91,7 +91,7 @@ struct intel_mipmap_tree /* Effectively the key: */ GLenum target; - GLenum internal_format; + gl_format format; GLuint first_level; GLuint last_level; @@ -136,24 +136,20 @@ struct intel_mipmap_tree struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel, GLenum target, - GLenum base_format, - GLenum internal_format, + gl_format format, GLuint first_level, GLuint last_level, GLuint width0, GLuint height0, GLuint depth0, - GLuint cpp, - GLuint compress_byte, GLboolean expect_accelerated_upload); struct intel_mipmap_tree * intel_miptree_create_for_region(struct intel_context *intel, GLenum target, - GLenum internal_format, + gl_format format, struct intel_region *region, - GLuint depth0, - GLuint compress_byte); + GLuint depth0); int intel_miptree_pitch_align (struct intel_context *intel, struct intel_mipmap_tree *mt, diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c index e83f1bfab94..88258d5b42d 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c @@ -40,37 +40,6 @@ #define FILE_DEBUG_FLAG DEBUG_PIXEL -static struct intel_region * -copypix_src_region(struct intel_context *intel, GLenum type) -{ - struct intel_renderbuffer *depth; - - depth = (struct intel_renderbuffer *) - &intel->ctx.DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; - - switch (type) { - case GL_COLOR: - return intel_readbuf_region(intel); - case GL_DEPTH: - /* Don't think this is really possible execpt at 16bpp, when we - * have no stencil. */ - if (depth && depth->region->cpp == 2) - return depth->region; - case GL_STENCIL: - /* Don't think this is really possible. */ - break; - case GL_DEPTH_STENCIL_EXT: - /* Does it matter whether it is stencil/depth or depth/stencil? - */ - return depth->region; - default: - break; - } - - return NULL; -} - - /** * Check if any fragment operations are in effect which might effect * glCopyPixels. Differs from intel_check_blit_fragment_ops in that @@ -109,8 +78,6 @@ do_blit_copypixels(struct gl_context * ctx, GLint dstx, GLint dsty, GLenum type) { struct intel_context *intel = intel_context(ctx); - struct intel_region *dst; - struct intel_region *src; struct gl_framebuffer *fb = ctx->DrawBuffer; struct gl_framebuffer *read_fb = ctx->ReadBuffer; GLint orig_dstx; @@ -118,14 +85,56 @@ do_blit_copypixels(struct gl_context * ctx, GLint orig_srcx; GLint orig_srcy; GLboolean flip = GL_FALSE; + struct intel_renderbuffer *draw_irb = NULL; + struct intel_renderbuffer *read_irb = NULL; + + /* Update draw buffer bounds */ + _mesa_update_state(ctx); + + switch (type) { + case GL_COLOR: + if (fb->_NumColorDrawBuffers != 1) { + fallback_debug("glCopyPixels() fallback: MRT\n"); + return GL_FALSE; + } - if (type == GL_DEPTH || type == GL_STENCIL) { - fallback_debug("glCopyPixels() fallback: GL_DEPTH || GL_STENCIL\n"); + draw_irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]); + read_irb = intel_renderbuffer(read_fb->_ColorReadBuffer); + break; + case GL_DEPTH_STENCIL_EXT: + draw_irb = intel_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer); + read_irb = + intel_renderbuffer(read_fb->Attachment[BUFFER_DEPTH].Renderbuffer); + break; + case GL_DEPTH: + fallback_debug("glCopyPixels() fallback: GL_DEPTH\n"); + return GL_FALSE; + case GL_STENCIL: + fallback_debug("glCopyPixels() fallback: GL_STENCIL\n"); + return GL_FALSE; + default: + fallback_debug("glCopyPixels(): Unknown type\n"); return GL_FALSE; } - /* Update draw buffer bounds */ - _mesa_update_state(ctx); + if (!draw_irb) { + fallback_debug("glCopyPixels() fallback: missing draw buffer\n"); + return GL_FALSE; + } + + if (!read_irb) { + fallback_debug("glCopyPixels() fallback: missing read buffer\n"); + return GL_FALSE; + } + + if (draw_irb->Base.Format != read_irb->Base.Format && + !(draw_irb->Base.Format == MESA_FORMAT_XRGB8888 && + read_irb->Base.Format == MESA_FORMAT_ARGB8888)) { + fallback_debug("glCopyPixels() fallback: mismatched formats (%s -> %s\n", + _mesa_get_format_name(read_irb->Base.Format), + _mesa_get_format_name(draw_irb->Base.Format)); + return GL_FALSE; + } /* Copypixels can be more than a straight copy. Ensure all the * extra operations are disabled: @@ -136,12 +145,6 @@ do_blit_copypixels(struct gl_context * ctx, intel_prepare_render(intel); - dst = intel_drawbuf_region(intel); - src = copypix_src_region(intel, type); - - if (!src || !dst) - return GL_FALSE; - intel_flush(&intel->ctx); /* Clip to destination buffer. */ @@ -179,9 +182,14 @@ do_blit_copypixels(struct gl_context * ctx, flip = !flip; } + srcx += read_irb->draw_x; + srcy += read_irb->draw_y; + dstx += draw_irb->draw_x; + dsty += draw_irb->draw_y; + if (!intel_region_copy(intel, - dst, 0, dstx, dsty, - src, 0, srcx, srcy, + draw_irb->region, 0, dstx, dsty, + read_irb->region, 0, srcx, srcy, width, height, flip, ctx->Color.ColorLogicOpEnabled ? ctx->Color.LogicOp : GL_COPY)) { diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c index 0253bbc2aa0..a4da1ce4fa5 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -524,38 +524,3 @@ intel_region_buffer(struct intel_context *intel, return region->buffer; } - -/** - * Rendering to tiled buffers requires that the base address of the - * buffer be aligned to a page boundary. We generally render to - * textures by pointing the surface at the mipmap image level, which - * may not be aligned to a tile boundary. - * - * This function returns an appropriately-aligned base offset - * according to the tiling restrictions, plus any required x/y offset - * from there. - */ -uint32_t -intel_region_tile_offsets(struct intel_region *region, - uint32_t *tile_x, - uint32_t *tile_y) -{ - uint32_t pitch = region->pitch * region->cpp; - - if (region->tiling == I915_TILING_NONE) { - *tile_x = 0; - *tile_y = 0; - return region->draw_x * region->cpp + region->draw_y * pitch; - } else if (region->tiling == I915_TILING_X) { - *tile_x = region->draw_x % (512 / region->cpp); - *tile_y = region->draw_y % 8; - return ((region->draw_y / 8) * (8 * pitch) + - (region->draw_x - *tile_x) / (512 / region->cpp) * 4096); - } else { - assert(region->tiling == I915_TILING_Y); - *tile_x = region->draw_x % (128 / region->cpp); - *tile_y = region->draw_y % 32; - return ((region->draw_y / 32) * (32 * pitch) + - (region->draw_x - *tile_x) / (128 / region->cpp) * 4096); - } -} diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h index a8a300d863c..91f7121436e 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.h +++ b/src/mesa/drivers/dri/intel/intel_regions.h @@ -62,9 +62,6 @@ struct intel_region GLubyte *map; /**< only non-NULL when region is actually mapped */ GLuint map_refcount; /**< Reference count for mapping */ - GLuint draw_offset; /**< Offset of drawing address within the region */ - GLuint draw_x, draw_y; /**< Offset of drawing within the region */ - uint32_t tiling; /**< Which tiling mode the region is in */ struct intel_buffer_object *pbo; /* zero-copy uploads */ @@ -142,10 +139,6 @@ drm_intel_bo *intel_region_buffer(struct intel_context *intel, struct intel_region *region, GLuint flag); -uint32_t intel_region_tile_offsets(struct intel_region *region, - uint32_t *tile_x, - uint32_t *tile_y); - void _mesa_copy_rect(GLubyte * dst, GLuint cpp, GLuint dst_pitch, diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index e915ca04fe0..2a3a601ddba 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -282,13 +282,38 @@ intel_query_image(__DRIimage *image, int attrib, int *value) } } +static __DRIimage * +intel_dup_image(__DRIimage *orig_image, void *loaderPrivate) +{ + __DRIimage *image; + + image = CALLOC(sizeof *image); + if (image == NULL) + return NULL; + + image->region = NULL; + intel_region_reference(&image->region, orig_image->region); + if (image->region == NULL) { + FREE(image); + return NULL; + } + + image->internal_format = orig_image->internal_format; + image->format = orig_image->format; + image->data_type = orig_image->data_type; + image->data = loaderPrivate; + + return image; +} + static struct __DRIimageExtensionRec intelImageExtension = { { __DRI_IMAGE, __DRI_IMAGE_VERSION }, intel_create_image_from_name, intel_create_image_from_renderbuffer, intel_destroy_image, intel_create_image, - intel_query_image + intel_query_image, + intel_dup_image }; static const __DRIextension *intelScreenExtensions[] = { diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c index a4a1d6bd6eb..153803fba09 100644 --- a/src/mesa/drivers/dri/intel/intel_span.c +++ b/src/mesa/drivers/dri/intel/intel_span.c @@ -55,21 +55,18 @@ intel_set_span_functions(struct intel_context *intel, #define LOCAL_VARS \ struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ - const GLint yScale = rb->Name ? 1 : -1; \ - const GLint yBias = rb->Name ? 0 : rb->Height - 1; \ int minx = 0, miny = 0; \ int maxx = rb->Width; \ int maxy = rb->Height; \ - int pitch = irb->region->pitch * irb->region->cpp; \ - void *buf = irb->region->buffer->virtual; \ + int pitch = rb->RowStride * irb->region->cpp; \ + void *buf = rb->Data; \ GLuint p; \ - (void) p; \ - (void)buf; (void)pitch; /* unused for non-gttmap. */ \ + (void) p; #define HW_CLIPLOOP() #define HW_ENDCLIPLOOP() -#define Y_FLIP(_y) ((_y) * yScale + yBias) +#define Y_FLIP(_y) (_y) #define HW_LOCK() @@ -151,7 +148,7 @@ intel_set_span_functions(struct intel_context *intel, * x | y | byte offset * -------------------------- * 0 | 0 | 0 - * 0 | 0 | 1 + * 0 | 1 | 1 * 1 | 0 | 2 * 1 | 1 | 3 * ... | ... | ... @@ -180,7 +177,15 @@ intel_renderbuffer_map(struct intel_context *intel, struct gl_renderbuffer *rb) { struct intel_renderbuffer *irb = intel_renderbuffer(rb); - if (irb == NULL || irb->region == NULL) + if (!irb) + return; + + if (irb->wrapped_depth) + intel_renderbuffer_map(intel, irb->wrapped_depth); + if (irb->wrapped_stencil) + intel_renderbuffer_map(intel, irb->wrapped_stencil); + + if (!irb->region) return; drm_intel_gem_bo_map_gtt(irb->region->buffer); @@ -188,10 +193,16 @@ intel_renderbuffer_map(struct intel_context *intel, struct gl_renderbuffer *rb) rb->Data = irb->region->buffer->virtual; rb->RowStride = irb->region->pitch; - /* Flip orientation if it's the window system buffer */ if (!rb->Name) { + /* Flip orientation of the window system buffer */ rb->Data += rb->RowStride * (irb->region->height - 1) * irb->region->cpp; rb->RowStride = -rb->RowStride; + } else { + /* Adjust the base pointer of a texture image drawbuffer to the image + * within the miptree region (all else has draw_x/y = 0). + */ + rb->Data += irb->draw_x * irb->region->cpp; + rb->Data += irb->draw_y * rb->RowStride * irb->region->cpp; } intel_set_span_functions(intel, rb); @@ -203,7 +214,15 @@ intel_renderbuffer_unmap(struct intel_context *intel, { struct intel_renderbuffer *irb = intel_renderbuffer(rb); - if (irb == NULL || irb->region == NULL) + if (!irb) + return; + + if (irb->wrapped_depth) + intel_renderbuffer_unmap(intel, irb->wrapped_depth); + if (irb->wrapped_stencil) + intel_renderbuffer_unmap(intel, irb->wrapped_stencil); + + if (!irb->region) return; drm_intel_gem_bo_unmap_gtt(irb->region->buffer); @@ -214,71 +233,26 @@ intel_renderbuffer_unmap(struct intel_context *intel, rb->RowStride = 0; } -/** - * Map or unmap all the renderbuffers which we may need during - * software rendering. - * XXX in the future, we could probably convey extra information to - * reduce the number of mappings needed. I.e. if doing a glReadPixels - * from the depth buffer, we really only need one mapping. - * - * XXX Rewrite this function someday. - * We can probably just loop over all the renderbuffer attachments, - * map/unmap all of them, and not worry about the _ColorDrawBuffers - * _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields. - */ static void -intel_map_unmap_framebuffer(struct intel_context *intel, - struct gl_framebuffer *fb, - GLboolean map) +intel_framebuffer_map(struct intel_context *intel, struct gl_framebuffer *fb) { - GLuint i; - - /* color draw buffers */ - for (i = 0; i < fb->_NumColorDrawBuffers; i++) { - if (map) - intel_renderbuffer_map(intel, fb->_ColorDrawBuffers[i]); - else - intel_renderbuffer_unmap(intel, fb->_ColorDrawBuffers[i]); - } - - /* color read buffer */ - if (map) - intel_renderbuffer_map(intel, fb->_ColorReadBuffer); - else - intel_renderbuffer_unmap(intel, fb->_ColorReadBuffer); + int i; - /* check for render to textures */ for (i = 0; i < BUFFER_COUNT; i++) { - struct gl_renderbuffer_attachment *att = - fb->Attachment + i; - struct gl_texture_object *tex = att->Texture; - if (tex) { - /* render to texture */ - ASSERT(att->Renderbuffer); - if (map) - intel_tex_map_images(intel, intel_texture_object(tex)); - else - intel_tex_unmap_images(intel, intel_texture_object(tex)); - } + intel_renderbuffer_map(intel, fb->Attachment[i].Renderbuffer); } - /* depth buffer (Note wrapper!) */ - if (fb->_DepthBuffer) { - if (map) - intel_renderbuffer_map(intel, fb->_DepthBuffer->Wrapped); - else - intel_renderbuffer_unmap(intel, fb->_DepthBuffer->Wrapped); - } + intel_check_front_buffer_rendering(intel); +} - /* stencil buffer (Note wrapper!) */ - if (fb->_StencilBuffer) { - if (map) - intel_renderbuffer_map(intel, fb->_StencilBuffer->Wrapped); - else - intel_renderbuffer_unmap(intel, fb->_StencilBuffer->Wrapped); - } +static void +intel_framebuffer_unmap(struct intel_context *intel, struct gl_framebuffer *fb) +{ + int i; - intel_check_front_buffer_rendering(intel); + for (i = 0; i < BUFFER_COUNT; i++) { + intel_renderbuffer_unmap(intel, fb->Attachment[i].Renderbuffer); + } } /** @@ -305,9 +279,10 @@ intelSpanRenderStart(struct gl_context * ctx) } } - intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_TRUE); - if (ctx->ReadBuffer != ctx->DrawBuffer) - intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_TRUE); + intel_framebuffer_map(intel, ctx->DrawBuffer); + if (ctx->ReadBuffer != ctx->DrawBuffer) { + intel_framebuffer_map(intel, ctx->ReadBuffer); + } } /** @@ -329,9 +304,10 @@ intelSpanRenderFinish(struct gl_context * ctx) } } - intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_FALSE); - if (ctx->ReadBuffer != ctx->DrawBuffer) - intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_FALSE); + intel_framebuffer_unmap(intel, ctx->DrawBuffer); + if (ctx->ReadBuffer != ctx->DrawBuffer) { + intel_framebuffer_unmap(intel, ctx->ReadBuffer); + } } diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c index 2c3eab20fda..21c4a1dddba 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.c +++ b/src/mesa/drivers/dri/intel/intel_tex.c @@ -1,4 +1,5 @@ #include "swrast/swrast.h" +#include "main/renderbuffer.h" #include "main/texobj.h" #include "main/teximage.h" #include "main/mipmap.h" @@ -59,6 +60,14 @@ intelFreeTextureImageData(struct gl_context * ctx, struct gl_texture_image *texI _mesa_free_texmemory(texImage->Data); texImage->Data = NULL; } + + if (intelImage->depth_rb) { + _mesa_reference_renderbuffer(&intelImage->depth_rb, NULL); + } + + if (intelImage->stencil_rb) { + _mesa_reference_renderbuffer(&intelImage->stencil_rb, NULL); + } } /** @@ -75,6 +84,7 @@ intelGenerateMipmap(struct gl_context *ctx, GLenum target, /* sw path: need to map texture images */ struct intel_context *intel = intel_context(ctx); struct intel_texture_object *intelObj = intel_texture_object(texObj); + struct gl_texture_image *first_image = texObj->Image[0][texObj->BaseLevel]; fallback_debug("%s - fallback to swrast\n", __FUNCTION__); @@ -82,7 +92,7 @@ intelGenerateMipmap(struct gl_context *ctx, GLenum target, _mesa_generate_mipmap(ctx, target, texObj); intel_tex_unmap_level_images(intel, intelObj, texObj->BaseLevel); - { + if (!_mesa_is_format_compressed(first_image->TexFormat)) { GLuint nr_faces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; GLuint face, i; /* Update the level information in our private data in the new images, diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index 62d4169acd1..eda07a43dee 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -152,7 +152,7 @@ intel_copy_texsubimage(struct intel_context *intel, dst_bo, 0, intelImage->mt->region->tiling, - irb->region->draw_x + x, irb->region->draw_y + y, + irb->draw_x + x, irb->draw_y + y, image_x + dstx, image_y + dsty, width, height, GL_COPY)) { diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index bc39f4ad83f..269faefa1c0 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -8,6 +8,7 @@ #include "main/context.h" #include "main/formats.h" #include "main/pbo.h" +#include "main/renderbuffer.h" #include "main/texcompress.h" #include "main/texstore.h" #include "main/texgetimage.h" @@ -21,6 +22,7 @@ #include "intel_tex.h" #include "intel_blit.h" #include "intel_fbo.h" +#include "intel_span.h" #define FILE_DEBUG_FLAG DEBUG_TEXTURE @@ -54,8 +56,7 @@ intel_miptree_create_for_teximage(struct intel_context *intel, GLuint width = intelImage->base.Width; GLuint height = intelImage->base.Height; GLuint depth = intelImage->base.Depth; - GLuint i, comp_byte = 0; - GLuint texelBytes; + GLuint i; DBG("%s\n", __FUNCTION__); @@ -108,22 +109,14 @@ intel_miptree_create_for_teximage(struct intel_context *intel, } } - if (_mesa_is_format_compressed(intelImage->base.TexFormat)) - comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat); - - texelBytes = _mesa_get_format_bytes(intelImage->base.TexFormat); - return intel_miptree_create(intel, intelObj->base.Target, - intelImage->base._BaseFormat, - intelImage->base.InternalFormat, + intelImage->base.TexFormat, firstLevel, lastLevel, width, height, depth, - texelBytes, - comp_byte, expect_accelerated_upload); } @@ -286,6 +279,130 @@ try_pbo_zcopy(struct intel_context *intel, return GL_TRUE; } +/** + * \param scatter Scatter if true. Gather if false. + * + * \see intel_tex_image_x8z24_scatter + * \see intel_tex_image_x8z24_gather + */ +static void +intel_tex_image_s8z24_scattergather(struct intel_context *intel, + struct intel_texture_image *intel_image, + bool scatter) +{ + struct gl_context *ctx = &intel->ctx; + struct gl_renderbuffer *depth_rb = intel_image->depth_rb; + struct gl_renderbuffer *stencil_rb = intel_image->stencil_rb; + + int w = intel_image->base.Width; + int h = intel_image->base.Height; + + uint32_t depth_row[w]; + uint8_t stencil_row[w]; + + intel_renderbuffer_map(intel, depth_rb); + intel_renderbuffer_map(intel, stencil_rb); + + if (scatter) { + for (int y = 0; y < h; ++y) { + depth_rb->GetRow(ctx, depth_rb, w, 0, y, depth_row); + for (int x = 0; x < w; ++x) { + stencil_row[x] = depth_row[x] >> 24; + } + stencil_rb->PutRow(ctx, stencil_rb, w, 0, y, stencil_row, NULL); + } + } else { /* gather */ + for (int y = 0; y < h; ++y) { + depth_rb->GetRow(ctx, depth_rb, w, 0, y, depth_row); + stencil_rb->GetRow(ctx, stencil_rb, w, 0, y, stencil_row); + for (int x = 0; x < w; ++x) { + uint32_t s8_x24 = stencil_row[x] << 24; + uint32_t x8_z24 = depth_row[x] & 0x00ffffff; + depth_row[x] = s8_x24 | x8_z24; + } + depth_rb->PutRow(ctx, depth_rb, w, 0, y, depth_row, NULL); + } + } + + intel_renderbuffer_unmap(intel, depth_rb); + intel_renderbuffer_unmap(intel, stencil_rb); +} + +/** + * Copy the x8 bits from intel_image->depth_rb to intel_image->stencil_rb. + */ +static void +intel_tex_image_s8z24_scatter(struct intel_context *intel, + struct intel_texture_image *intel_image) +{ + intel_tex_image_s8z24_scattergather(intel, intel_image, true); +} + +/** + * Copy the data in intel_image->stencil_rb to the x8 bits in + * intel_image->depth_rb. + */ +static void +intel_tex_image_s8z24_gather(struct intel_context *intel, + struct intel_texture_image *intel_image) +{ + intel_tex_image_s8z24_scattergather(intel, intel_image, false); +} + +static bool +intel_tex_image_s8z24_create_renderbuffers(struct intel_context *intel, + struct intel_texture_image *image) +{ + struct gl_context *ctx = &intel->ctx; + + bool ok = true; + int width = image->base.Width; + int height = image->base.Height; + struct gl_renderbuffer *drb; + struct gl_renderbuffer *srb; + struct intel_renderbuffer *idrb; + struct intel_renderbuffer *isrb; + + assert(intel->has_separate_stencil); + assert(image->base.TexFormat == MESA_FORMAT_S8_Z24); + assert(image->mt != NULL); + + drb = intel_create_wrapped_renderbuffer(ctx, width, height, + MESA_FORMAT_X8_Z24); + srb = intel_create_wrapped_renderbuffer(ctx, width, height, + MESA_FORMAT_S8); + + if (!drb || !srb) { + if (drb) { + drb->Delete(drb); + } + if (srb) { + srb->Delete(srb); + } + return false; + } + + idrb = intel_renderbuffer(drb); + isrb = intel_renderbuffer(srb); + + intel_region_reference(&idrb->region, image->mt->region); + ok = intel_alloc_renderbuffer_storage(ctx, srb, GL_STENCIL_INDEX8, + width, height); + + if (!ok) { + drb->Delete(drb); + srb->Delete(srb); + return false; + } + + intel_renderbuffer_set_draw_offset(idrb, image, 0); + intel_renderbuffer_set_draw_offset(isrb, image, 0); + + _mesa_reference_renderbuffer(&image->depth_rb, drb); + _mesa_reference_renderbuffer(&image->stencil_rb, srb); + + return true; +} static void intelTexImage(struct gl_context * ctx, @@ -323,18 +440,7 @@ intelTexImage(struct gl_context * ctx, } } - /* Release the reference to a potentially orphaned buffer. - * Release any old malloced memory. - */ - if (intelImage->mt) { - intel_miptree_release(intel, &intelImage->mt); - assert(!texImage->Data); - } - else if (texImage->Data) { - _mesa_free_texmemory(texImage->Data); - texImage->Data = NULL; - } - + ctx->Driver.FreeTexImageData(ctx, texImage); assert(!intelImage->mt); if (intelObj->mt && @@ -493,6 +599,12 @@ intelTexImage(struct gl_context * ctx, _mesa_unmap_teximage_pbo(ctx, unpack); + if (intel->must_use_separate_stencil + && texImage->TexFormat == MESA_FORMAT_S8_Z24) { + intel_tex_image_s8z24_create_renderbuffers(intel, intelImage); + intel_tex_image_s8z24_scatter(intel, intelImage); + } + if (intelImage->mt) { if (pixels != NULL) intel_miptree_image_unmap(intel, intelImage->mt); @@ -609,6 +721,14 @@ intel_get_tex_image(struct gl_context * ctx, GLenum target, GLint level, assert(intelImage->base.Data); } + if (intelImage->stencil_rb) { + /* + * The texture has packed depth/stencil format, but uses separate + * stencil. The texture's embedded stencil buffer contains the real + * stencil data, so copy that into the miptree. + */ + intel_tex_image_s8z24_gather(intel, intelImage); + } if (compressed) { _mesa_get_compressed_teximage(ctx, target, level, pixels, @@ -692,8 +812,8 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, texFormat = MESA_FORMAT_ARGB8888; } - mt = intel_miptree_create_for_region(intel, target, - internalFormat, rb->region, 1, 0); + mt = intel_miptree_create_for_region(intel, target, texFormat, + rb->region, 1); if (mt == NULL) return; @@ -756,9 +876,8 @@ intel_image_target_texture_2d(struct gl_context *ctx, GLenum target, if (image == NULL) return; - mt = intel_miptree_create_for_region(intel, target, - image->internal_format, - image->region, 1, 0); + mt = intel_miptree_create_for_region(intel, target, image->format, + image->region, 1); if (mt == NULL) return; diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c index d39733b6c5a..9d8152375d8 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.c +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -35,39 +35,26 @@ #include "intel_context.h" #include "main/macros.h" -void intel_get_texture_alignment_unit(GLenum internalFormat, GLuint *w, GLuint *h) +void +intel_get_texture_alignment_unit(gl_format format, + unsigned int *w, unsigned int *h) { - switch (internalFormat) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: - *w = 8; - *h = 4; - break; - - case GL_RGB_S3TC: - case GL_RGB4_S3TC: - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - *w = 4; - *h = 4; - break; - - default: - *w = 4; - *h = 2; - break; - } + if (_mesa_is_format_compressed(format)) { + /* The hardware alignment requirements for compressed textures + * happen to match the block boundaries. + */ + _mesa_get_format_block_size(format, w, h); + } else { + *w = 4; + *h = 2; + } } void i945_miptree_layout_2d(struct intel_context *intel, struct intel_mipmap_tree *mt, uint32_t tiling, int nr_images) { - GLuint align_h = 2, align_w = 4; + GLuint align_h, align_w; GLuint level; GLuint x = 0; GLuint y = 0; @@ -75,7 +62,7 @@ void i945_miptree_layout_2d(struct intel_context *intel, GLuint height = mt->height0; mt->total_width = mt->width0; - intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h); + intel_get_texture_alignment_unit(mt->format, &align_w, &align_h); if (mt->compressed) { mt->total_width = ALIGN(mt->width0, align_w); @@ -110,11 +97,9 @@ void i945_miptree_layout_2d(struct intel_context *intel, intel_miptree_set_level_info(mt, level, nr_images, x, y, width, height, 1); + img_height = ALIGN(height, align_h); if (mt->compressed) - img_height = MAX2(1, height/4); - else - img_height = ALIGN(height, align_h); - + img_height /= align_h; /* Because the images are packed better, the final offset * might not be the maximal one: diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h index 1c8c53e5459..b52e5a48855 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.h +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h @@ -41,4 +41,5 @@ static INLINE GLuint minify( GLuint d ) extern void i945_miptree_layout_2d(struct intel_context *intel, struct intel_mipmap_tree *mt, uint32_t tiling, int nr_images); -extern void intel_get_texture_alignment_unit(GLenum, GLuint *, GLuint *); +void intel_get_texture_alignment_unit(gl_format format, + unsigned int *w, unsigned int *h); diff --git a/src/mesa/drivers/dri/intel/intel_tex_obj.h b/src/mesa/drivers/dri/intel/intel_tex_obj.h index e93ef4a4727..a9ae2ec5429 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_obj.h +++ b/src/mesa/drivers/dri/intel/intel_tex_obj.h @@ -63,6 +63,36 @@ struct intel_texture_image */ struct intel_mipmap_tree *mt; GLboolean used_as_render_target; + + /** + * \name Renderbuffers for faking packed depth/stencil + * + * These renderbuffers are non-null only if the intel_context is using + * separate stencil and this texture has a packed depth/stencil format. When + * glFramebufferTexture is called on this image, the resultant renderbuffer + * wrapper reuses these renderbuffers as its own. + * + * \see intel_wrap_texture + * \see intel_tex_image_s8z24_create_renderbuffers + * \see intel_tex_image_s8z24_scatter + * \see intel_tex_image_s8z24_gather + * + * \{ + */ + + /** + * The depth buffer has format X8_Z24. The x8 bits are undefined unless + * intel_tex_image_s8z24_gather has been immediately called. The depth buffer + * resuses the image miptree's region and hiz_region as its own. + */ + struct gl_renderbuffer *depth_rb; + + /** + * The stencil buffer has format S8 and keeps its data in its own region. + */ + struct gl_renderbuffer *stencil_rb; + + /** \} */ }; static INLINE struct intel_texture_object * diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c index 27f2646ebf5..7135a6276fe 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_validate.c +++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c @@ -77,8 +77,6 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current; struct intel_texture_object *intelObj = intel_texture_object(tObj); struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit); - int comp_byte = 0; - int cpp; GLuint face, i; GLuint nr_faces = 0; struct intel_texture_image *firstImage; @@ -101,13 +99,6 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) return GL_FALSE; } - if (_mesa_is_format_compressed(firstImage->base.TexFormat)) { - comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat); - cpp = comp_byte; - } - else - cpp = _mesa_get_format_bytes(firstImage->base.TexFormat); - /* Check tree can hold all active levels. Check tree matches * target, imageFormat, etc. * @@ -118,14 +109,12 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) */ if (intelObj->mt && (intelObj->mt->target != intelObj->base.Target || - intelObj->mt->internal_format != firstImage->base.InternalFormat || + intelObj->mt->format != firstImage->base.TexFormat || intelObj->mt->first_level != tObj->BaseLevel || intelObj->mt->last_level < intelObj->_MaxLevel || intelObj->mt->width0 != firstImage->base.Width || intelObj->mt->height0 != firstImage->base.Height || - intelObj->mt->depth0 != firstImage->base.Depth || - intelObj->mt->cpp != cpp || - intelObj->mt->compressed != _mesa_is_format_compressed(firstImage->base.TexFormat))) { + intelObj->mt->depth0 != firstImage->base.Depth)) { intel_miptree_release(intel, &intelObj->mt); } @@ -135,15 +124,12 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) if (!intelObj->mt) { intelObj->mt = intel_miptree_create(intel, intelObj->base.Target, - firstImage->base._BaseFormat, - firstImage->base.InternalFormat, + firstImage->base.TexFormat, tObj->BaseLevel, intelObj->_MaxLevel, firstImage->base.Width, firstImage->base.Height, firstImage->base.Depth, - cpp, - comp_byte, GL_TRUE); if (!intelObj->mt) return GL_FALSE; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c index 36e68c99181..dcfd316c49f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_texture.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.c @@ -688,8 +688,10 @@ nouveau_generate_mipmap(struct gl_context *ctx, GLenum target, _mesa_generate_mipmap(ctx, target, t); nouveau_teximage_unmap(ctx, base); - store_mipmap(ctx, target, t->BaseLevel + 1, - get_last_level(t), t); + if (!_mesa_is_format_compressed(base->TexFormat)) { + store_mipmap(ctx, target, t->BaseLevel + 1, + get_last_level(t), t); + } } else { _mesa_meta_GenerateMipmap(ctx, target, t); diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c index 931a9ecf8fe..a512c9d112a 100644 --- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c +++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c @@ -47,9 +47,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define insert_at_tail_if(atom_list, atom) \ do { \ - struct radeon_state_atom* __atom = (atom); \ - if (__atom->check) \ - insert_at_tail((atom_list), __atom); \ + struct radeon_state_atom* current_atom = (atom); \ + if (current_atom->check) \ + insert_at_tail((atom_list), current_atom); \ } while(0) void r200SetUpAtomList( r200ContextPtr rmesa ) diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c index 2bd3b62bfdb..0f7a7a46b71 100644 --- a/src/mesa/drivers/dri/r600/r700_render.c +++ b/src/mesa/drivers/dri/r600/r700_render.c @@ -329,7 +329,7 @@ static void r700RunRenderPrimitiveImmediate(struct gl_context * ctx, int start, { context_t *context = R700_CONTEXT(ctx); BATCH_LOCALS(&context->radeon); - int type, i; + int type; uint32_t num_indices, total_emit = 0; uint32_t vgt_draw_initiator = 0; uint32_t vgt_index_type = 0; @@ -370,22 +370,7 @@ static void r700RunRenderPrimitiveImmediate(struct gl_context * ctx, int start, vgt_num_indices = num_indices; SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift, MAJOR_MODE_mask); - if (start == 0) - { - SETfield(vgt_draw_initiator, DI_SRC_SEL_AUTO_INDEX, SOURCE_SELECT_shift, SOURCE_SELECT_mask); - } - else - { - if (num_indices > 0xffff) - { - total_emit += num_indices; - } - else - { - total_emit += (num_indices + 1) / 2; - } - SETfield(vgt_draw_initiator, DI_SRC_SEL_IMMEDIATE, SOURCE_SELECT_shift, SOURCE_SELECT_mask); - } + SETfield(vgt_draw_initiator, DI_SRC_SEL_AUTO_INDEX, SOURCE_SELECT_shift, SOURCE_SELECT_mask); total_emit += 3 /* VGT_PRIMITIVE_TYPE */ + 2 /* VGT_INDEX_TYPE */ @@ -406,45 +391,13 @@ static void r700RunRenderPrimitiveImmediate(struct gl_context * ctx, int start, /* offset */ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 2)); R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX); - R600_OUT_BATCH(0); //VTX_BASE_VTX_LOC + R600_OUT_BATCH(start); //VTX_BASE_VTX_LOC R600_OUT_BATCH(0); //VTX_START_INST_LOC // draw packet - if(start == 0) - { - R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1)); - R600_OUT_BATCH(vgt_num_indices); - R600_OUT_BATCH(vgt_draw_initiator); - } - else - { - if (num_indices > 0xffff) - { - R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (num_indices + 1))); - R600_OUT_BATCH(vgt_num_indices); - R600_OUT_BATCH(vgt_draw_initiator); - for (i = start; i < (start + num_indices); i++) - { - R600_OUT_BATCH(i); - } - } - else - { - R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (((num_indices + 1) / 2) + 1))); - R600_OUT_BATCH(vgt_num_indices); - R600_OUT_BATCH(vgt_draw_initiator); - for (i = start; i < (start + num_indices); i += 2) - { - if ((i + 1) == (start + num_indices)) - { - R600_OUT_BATCH(i); - } - else - { - R600_OUT_BATCH(((i + 1) << 16) | (i)); - } - } - } - } + + R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1)); + R600_OUT_BATCH(vgt_num_indices); + R600_OUT_BATCH(vgt_draw_initiator); END_BATCH(); COMMIT_BATCH(); @@ -469,12 +422,7 @@ static GLuint r700PredictRenderSize(struct gl_context* ctx, else { for (i = 0; i < nr_prims; ++i) { - if (prim[i].start == 0) - dwords += 14; - else if (prim[i].count > 0xffff) - dwords += prim[i].count + 14; - else - dwords += ((prim[i].count + 1) / 2) + 14; + dwords += 14; } } diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c index d3c9257fb66..92c1854f098 100644 --- a/src/mesa/drivers/dri/radeon/radeon_fbo.c +++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c @@ -35,7 +35,7 @@ #include "main/framebuffer.h" #include "main/renderbuffer.h" #include "main/context.h" -#include "main/texrender.h" +#include "swrast/swrast.h" #include "drivers/common/meta.h" #include "radeon_common.h" @@ -557,7 +557,7 @@ radeon_render_texture(struct gl_context * ctx, /* Fallback on drawing to a texture without a miptree. */ _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); - _mesa_render_texture(ctx, fb, att); + _swrast_render_texture(ctx, fb, att); return; } else if (!rrb) { @@ -568,14 +568,14 @@ radeon_render_texture(struct gl_context * ctx, } else { /* fallback to software rendering */ - _mesa_render_texture(ctx, fb, att); + _swrast_render_texture(ctx, fb, att); return; } } if (!radeon_update_wrapper(ctx, rrb, newImage)) { _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); - _mesa_render_texture(ctx, fb, att); + _swrast_render_texture(ctx, fb, att); return; } diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 6cf843406f9..676fafd4560 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -1658,52 +1658,105 @@ radeonCreateScreen2(__DRIscreen *sPriv) screen->group_bytes = 512; else screen->group_bytes = 256; - if (IS_R600_CLASS(screen) && (sPriv->drm_version.minor >= 6) && - (screen->chip_family < CHIP_FAMILY_CEDAR)) { - ret = radeonGetParam(sPriv, RADEON_INFO_TILE_CONFIG, &temp); - if (ret) - fprintf(stderr, "failed to get tiling info\n"); - else { - screen->tile_config = temp; - screen->r7xx_bank_op = 0; - switch((screen->tile_config & 0xe) >> 1) { - case 0: - screen->num_channels = 1; - break; - case 1: - screen->num_channels = 2; - break; - case 2: - screen->num_channels = 4; - break; - case 3: - screen->num_channels = 8; - break; - default: - fprintf(stderr, "bad channels\n"); - break; + if (IS_R600_CLASS(screen)) { + if ((sPriv->drm_version.minor >= 6) && + (screen->chip_family < CHIP_FAMILY_CEDAR)) { + ret = radeonGetParam(sPriv, RADEON_INFO_TILE_CONFIG, &temp); + if (ret) + fprintf(stderr, "failed to get tiling info\n"); + else { + screen->tile_config = temp; + screen->r7xx_bank_op = 0; + switch ((screen->tile_config & 0xe) >> 1) { + case 0: + screen->num_channels = 1; + break; + case 1: + screen->num_channels = 2; + break; + case 2: + screen->num_channels = 4; + break; + case 3: + screen->num_channels = 8; + break; + default: + fprintf(stderr, "bad channels\n"); + break; + } + switch ((screen->tile_config & 0x30) >> 4) { + case 0: + screen->num_banks = 4; + break; + case 1: + screen->num_banks = 8; + break; + default: + fprintf(stderr, "bad banks\n"); + break; + } + switch ((screen->tile_config & 0xc0) >> 6) { + case 0: + screen->group_bytes = 256; + break; + case 1: + screen->group_bytes = 512; + break; + default: + fprintf(stderr, "bad group_bytes\n"); + break; + } } - switch((screen->tile_config & 0x30) >> 4) { - case 0: - screen->num_banks = 4; - break; - case 1: - screen->num_banks = 8; - break; - default: - fprintf(stderr, "bad banks\n"); - break; - } - switch((screen->tile_config & 0xc0) >> 6) { - case 0: - screen->group_bytes = 256; - break; - case 1: - screen->group_bytes = 512; - break; - default: - fprintf(stderr, "bad group_bytes\n"); - break; + } else if ((sPriv->drm_version.minor >= 7) && + (screen->chip_family >= CHIP_FAMILY_CEDAR)) { + ret = radeonGetParam(sPriv, RADEON_INFO_TILE_CONFIG, &temp); + if (ret) + fprintf(stderr, "failed to get tiling info\n"); + else { + screen->tile_config = temp; + screen->r7xx_bank_op = 0; + switch (screen->tile_config & 0xf) { + case 0: + screen->num_channels = 1; + break; + case 1: + screen->num_channels = 2; + break; + case 2: + screen->num_channels = 4; + break; + case 3: + screen->num_channels = 8; + break; + default: + fprintf(stderr, "bad channels\n"); + break; + } + switch ((screen->tile_config & 0xf0) >> 4) { + case 0: + screen->num_banks = 4; + break; + case 1: + screen->num_banks = 8; + break; + case 2: + screen->num_banks = 16; + break; + default: + fprintf(stderr, "bad banks\n"); + break; + } + switch ((screen->tile_config & 0xf00) >> 8) { + case 0: + screen->group_bytes = 256; + break; + case 1: + screen->group_bytes = 512; + break; + default: + fprintf(stderr, "bad group_bytes\n"); + break; + } } } } diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index 9ec53881bb2..ce0df32bfe4 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -249,6 +249,7 @@ static void radeon_generate_mipmap(struct gl_context *ctx, GLenum target, radeonTexObj* t = radeon_tex_obj(texObj); GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; int i, face; + struct gl_texture_image *first_image; radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, "%s(%p, tex %p) Target type %s.\n", @@ -257,6 +258,13 @@ static void radeon_generate_mipmap(struct gl_context *ctx, GLenum target, _mesa_generate_mipmap(ctx, target, texObj); + /* For the compressed case, we don't need to do the + * non-TexImage recovery path below. + */ + first_image = texObj->Image[0][texObj->BaseLevel]; + if (_mesa_is_format_compressed(first_image->TexFormat)) + return; + for (face = 0; face < nr_faces; face++) { for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { radeon_texture_image *image; diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index 63f53e2b080..a75c9c2e782 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -462,6 +462,27 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers, /** + * Update the current drawbuffer's _ColorDrawBufferIndex[] list, etc. + * from the context's Color.DrawBuffer[] state. + * Use when changing contexts. + */ +void +_mesa_update_draw_buffers(struct gl_context *ctx) +{ + GLenum buffers[MAX_DRAW_BUFFERS]; + GLuint i; + + /* should be a window system FBO */ + assert(ctx->DrawBuffer->Name == 0); + + for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) + buffers[i] = ctx->Color.DrawBuffer[i]; + + _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, buffers, NULL); +} + + +/** * Like \sa _mesa_drawbuffers(), this is a helper function for setting * GL_READ_BUFFER state in the context and current FBO. * \param ctx the rendering context diff --git a/src/mesa/main/buffers.h b/src/mesa/main/buffers.h index 1404112c411..8083bc3d353 100644 --- a/src/mesa/main/buffers.h +++ b/src/mesa/main/buffers.h @@ -50,6 +50,10 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers, extern void _mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex); +extern void +_mesa_update_draw_buffers(struct gl_context *ctx); + + extern void GLAPIENTRY _mesa_ReadBuffer( GLenum mode ); diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index ea13bdd6835..b83a5d621fa 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1430,7 +1430,8 @@ _mesa_make_current( struct gl_context *newCtx, } if (curCtx && - (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) && /* make sure this context is valid for flushing */ + (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) && + /* make sure this context is valid for flushing */ curCtx != newCtx) _mesa_flush(curCtx); @@ -1445,8 +1446,6 @@ _mesa_make_current( struct gl_context *newCtx, _glapi_set_dispatch(newCtx->CurrentDispatch); if (drawBuffer && readBuffer) { - /* TODO: check if newCtx and buffer's visual match??? */ - ASSERT(drawBuffer->Name == 0); ASSERT(readBuffer->Name == 0); _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer); @@ -1457,23 +1456,12 @@ _mesa_make_current( struct gl_context *newCtx, * or not bound to a user-created FBO. */ if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) { - /* KW: merge conflict here, revisit. - */ - /* fix up the fb fields - these will end up wrong otherwise - * if the DRIdrawable changes, and everything relies on them. - * This is a bit messy (same as needed in _mesa_BindFramebufferEXT) - */ - unsigned int i; - GLenum buffers[MAX_DRAW_BUFFERS]; - _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer); - - for(i = 0; i < newCtx->Const.MaxDrawBuffers; i++) { - buffers[i] = newCtx->Color.DrawBuffer[i]; - } - - _mesa_drawbuffers(newCtx, newCtx->Const.MaxDrawBuffers, - buffers, NULL); + /* Update the FBO's list of drawbuffers/renderbuffers. + * For winsys FBOs this comes from the GL state (which may have + * changed since the last time this FBO was bound). + */ + _mesa_update_draw_buffers(newCtx); } if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) { _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 2230b262336..8cc3fd49a34 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -78,9 +78,32 @@ static struct gl_renderbuffer DummyRenderbuffer; static struct gl_framebuffer IncompleteFramebuffer; -#define IS_CUBE_FACE(TARGET) \ - ((TARGET) >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && \ - (TARGET) <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) +static INLINE GLboolean +is_cube_face(GLenum target) +{ + return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); +} + + +/** + * Is the given FBO a user-created FBO? + */ +static INLINE GLboolean +is_user_fbo(const struct gl_framebuffer *fb) +{ + return fb->Name != 0; +} + + +/** + * Is the given FBO a window system FBO (like an X window)? + */ +static INLINE GLboolean +is_winsys_fbo(const struct gl_framebuffer *fb) +{ + return fb->Name == 0; +} static void @@ -196,7 +219,7 @@ _mesa_get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, { GLuint i; - assert(fb->Name > 0); + assert(is_user_fbo(fb)); switch (attachment) { case GL_COLOR_ATTACHMENT0_EXT: @@ -244,7 +267,7 @@ static struct gl_renderbuffer_attachment * _mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, GLenum attachment) { - assert(fb->Name == 0); + assert(is_winsys_fbo(fb)); switch (attachment) { case GL_FRONT_LEFT: @@ -669,7 +692,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, GLint i; GLuint j; - assert(fb->Name != 0); + assert(is_user_fbo(fb)); numImages = 0; fb->Width = 0; @@ -968,10 +991,11 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers) _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); } - if (ctx->DrawBuffer->Name) { + if (is_user_fbo(ctx->DrawBuffer)) { detach_renderbuffer(ctx, ctx->DrawBuffer, rb); } - if (ctx->ReadBuffer->Name && ctx->ReadBuffer != ctx->DrawBuffer) { + if (is_user_fbo(ctx->ReadBuffer) + && ctx->ReadBuffer != ctx->DrawBuffer) { detach_renderbuffer(ctx, ctx->ReadBuffer, rb); } @@ -1203,7 +1227,7 @@ invalidate_rb(GLuint key, void *data, void *userData) struct gl_renderbuffer *rb = (struct gl_renderbuffer *) userData; /* If this is a user-created FBO */ - if (fb->Name) { + if (is_user_fbo(fb)) { GLuint i; for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = fb->Attachment + i; @@ -1532,7 +1556,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) GLuint i; ASSERT(ctx->Driver.RenderTexture); - if (fb->Name == 0) + if (is_winsys_fbo(fb)) return; /* can't render to texture with winsys framebuffers */ for (i = 0; i < BUFFER_COUNT; i++) { @@ -1552,7 +1576,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) static void check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) { - if (fb->Name == 0) + if (is_winsys_fbo(fb)) return; /* can't render to texture with winsys framebuffers */ if (ctx->Driver.FinishRenderTexture) { @@ -1805,7 +1829,7 @@ _mesa_CheckFramebufferStatusEXT(GLenum target) return 0; } - if (buffer->Name == 0) { + if (is_winsys_fbo(buffer)) { /* The window system / default framebuffer is always complete */ return GL_FRAMEBUFFER_COMPLETE_EXT; } @@ -1843,7 +1867,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, } /* check framebuffer binding */ - if (fb->Name == 0) { + if (is_winsys_fbo(fb)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferTexture%sEXT", caller); return; @@ -1866,7 +1890,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, } else { err = (texObj->Target == GL_TEXTURE_CUBE_MAP) - ? !IS_CUBE_FACE(textarget) + ? !is_cube_face(textarget) : (texObj->Target != textarget); } } @@ -1970,7 +1994,7 @@ _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment, if ((texture != 0) && (textarget != GL_TEXTURE_2D) && (textarget != GL_TEXTURE_RECTANGLE_ARB) && - (!IS_CUBE_FACE(textarget))) { + (!is_cube_face(textarget))) { _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferTexture2DEXT(textarget=0x%x)", textarget); return; @@ -2034,7 +2058,7 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment, return; } - if (fb->Name == 0) { + if (is_winsys_fbo(fb)) { /* Can't attach new renderbuffers to a window system framebuffer */ _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT"); return; @@ -2111,7 +2135,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, return; } - if (buffer->Name == 0) { + if (is_winsys_fbo(buffer)) { /* the default / window-system FBO */ att = _mesa_get_fb0_attachment(ctx, buffer, attachment); } @@ -2143,7 +2167,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, switch (pname) { case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT: - *params = buffer->Name == 0 ? GL_FRAMEBUFFER_DEFAULT : att->Type; + *params = is_winsys_fbo(buffer) ? GL_FRAMEBUFFER_DEFAULT : att->Type; return; case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT: if (att->Type == GL_RENDERBUFFER_EXT) { diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index e9fcb545a1e..f2724dbca7e 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -1885,107 +1885,19 @@ next_mipmap_level_size(GLenum target, GLint border, } } - - - -/** - * Automatic mipmap generation. - * This is the fallback/default function for ctx->Driver.GenerateMipmap(). - * Generate a complete set of mipmaps from texObj's BaseLevel image. - * Stop at texObj's MaxLevel or when we get to the 1x1 texture. - * For cube maps, target will be one of - * GL_TEXTURE_CUBE_MAP_POSITIVE/NEGATIVE_X/Y/Z; never GL_TEXTURE_CUBE_MAP. - */ -void -_mesa_generate_mipmap(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj) +static void +generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target, + struct gl_texture_object *texObj, + const struct gl_texture_image *srcImage, + GLuint maxLevel) { - const struct gl_texture_image *srcImage; - gl_format convertFormat; - const GLubyte *srcData = NULL; - GLubyte *dstData = NULL; - GLint level, maxLevels; + GLint level; GLenum datatype; GLuint comps; - ASSERT(texObj); - srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel); - ASSERT(srcImage); - - maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); - ASSERT(maxLevels > 0); /* bad target */ - - /* Find convertFormat - the format that do_row() will process */ - - if (_mesa_is_format_compressed(srcImage->TexFormat)) { - /* setup for compressed textures - need to allocate temporary - * image buffers to hold uncompressed images. - */ - GLuint row; - GLint components, size; - GLchan *dst; - - assert(texObj->Target == GL_TEXTURE_2D || - texObj->Target == GL_TEXTURE_CUBE_MAP_ARB); - - if (srcImage->_BaseFormat == GL_RGB) { - convertFormat = MESA_FORMAT_RGB888; - components = 3; - } else if (srcImage->_BaseFormat == GL_RED) { - convertFormat = MESA_FORMAT_R8; - components = 1; - } else if (srcImage->_BaseFormat == GL_RG) { - convertFormat = MESA_FORMAT_RG88; - components = 2; - } else if (srcImage->_BaseFormat == GL_RGBA) { - convertFormat = MESA_FORMAT_RGBA8888; - components = 4; - } else if (srcImage->_BaseFormat == GL_LUMINANCE) { - convertFormat = MESA_FORMAT_L8; - components = 1; - } else if (srcImage->_BaseFormat == GL_LUMINANCE_ALPHA) { - convertFormat = MESA_FORMAT_AL88; - components = 2; - } else { - _mesa_problem(ctx, "bad srcImage->_BaseFormat in _mesa_generate_mipmaps"); - return; - } - - /* allocate storage for uncompressed GL_RGB or GL_RGBA images */ - size = _mesa_bytes_per_pixel(srcImage->_BaseFormat, CHAN_TYPE) - * srcImage->Width * srcImage->Height * srcImage->Depth + 20; - /* 20 extra bytes, just be safe when calling last FetchTexel */ - srcData = (GLubyte *) malloc(size); - if (!srcData) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); - return; - } - dstData = (GLubyte *) malloc(size / 2); /* 1/4 would probably be OK */ - if (!dstData) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); - free((void *) srcData); - return; - } + _mesa_format_to_type_and_comps(srcImage->TexFormat, &datatype, &comps); - /* decompress base image here */ - dst = (GLchan *) srcData; - for (row = 0; row < srcImage->Height; row++) { - GLuint col; - for (col = 0; col < srcImage->Width; col++) { - srcImage->FetchTexelc(srcImage, col, row, 0, dst); - dst += components; - } - } - } - else { - /* uncompressed */ - convertFormat = srcImage->TexFormat; - } - - _mesa_format_to_type_and_comps(convertFormat, &datatype, &comps); - - for (level = texObj->BaseLevel; level < texObj->MaxLevel - && level < maxLevels - 1; level++) { + for (level = texObj->BaseLevel; level < maxLevel; level++) { /* generate image[level+1] from image[level] */ const struct gl_texture_image *srcImage; struct gl_texture_image *dstImage; @@ -2005,14 +1917,8 @@ _mesa_generate_mipmap(struct gl_context *ctx, GLenum target, nextLevel = next_mipmap_level_size(target, border, srcWidth, srcHeight, srcDepth, &dstWidth, &dstHeight, &dstDepth); - if (!nextLevel) { - /* all done */ - if (_mesa_is_format_compressed(srcImage->TexFormat)) { - free((void *) srcData); - free(dstData); - } + if (!nextLevel) return; - } /* get dest gl_texture_image */ dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1); @@ -2044,52 +1950,184 @@ _mesa_generate_mipmap(struct gl_context *ctx, GLenum target, } } - /* Setup src and dest data pointers */ - if (_mesa_is_format_compressed(dstImage->TexFormat)) { - /* srcData and dstData are already set */ - ASSERT(srcData); - ASSERT(dstData); - } - else { - srcData = (const GLubyte *) srcImage->Data; - dstData = (GLubyte *) dstImage->Data; - } - ASSERT(dstImage->TexFormat); ASSERT(dstImage->FetchTexelc); ASSERT(dstImage->FetchTexelf); _mesa_generate_mipmap_level(target, datatype, comps, border, - srcWidth, srcHeight, srcDepth, - srcData, srcImage->RowStride, - dstWidth, dstHeight, dstDepth, - dstData, dstImage->RowStride); - - - if (_mesa_is_format_compressed(dstImage->TexFormat)) { - GLubyte *temp; - /* compress image from dstData into dstImage->Data */ - const GLenum srcFormat = _mesa_get_format_base_format(convertFormat); - GLint dstRowStride - = _mesa_format_row_stride(dstImage->TexFormat, dstWidth); - - _mesa_texstore(ctx, 2, dstImage->_BaseFormat, - dstImage->TexFormat, - dstImage->Data, - 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, 0, /* strides */ - dstWidth, dstHeight, 1, /* size */ - srcFormat, CHAN_TYPE, - dstData, /* src data, actually */ - &ctx->DefaultPacking); - - /* swap src and dest pointers */ - temp = (GLubyte *) srcData; - srcData = dstData; - dstData = temp; + srcWidth, srcHeight, srcDepth, + srcImage->Data, srcImage->RowStride, + dstWidth, dstHeight, dstDepth, + dstImage->Data, dstImage->RowStride); + + } /* loop over mipmap levels */ +} + +static void +generate_mipmap_compressed(struct gl_context *ctx, GLenum target, + struct gl_texture_object *texObj, + const struct gl_texture_image *srcImage, + GLuint maxLevel) +{ + GLint level; + gl_format temp_format; + GLenum datatype; + GLuint comps; + GLuint row; + GLint components; + GLuint temp_src_stride, temp_dst_stride; /* in bytes */ + GLchan *temp_src = NULL, *temp_dst = NULL; + + /* Choose the format we will do _mesa_generate_mipmap_level() in, + * and uncompress the firstImage into a temporary of that format. + */ + assert(texObj->Target == GL_TEXTURE_2D || + texObj->Target == GL_TEXTURE_CUBE_MAP_ARB); + + if (srcImage->_BaseFormat == GL_RGB) { + temp_format = MESA_FORMAT_RGB888; + components = 3; + } else if (srcImage->_BaseFormat == GL_RED) { + temp_format = MESA_FORMAT_R8; + components = 1; + } else if (srcImage->_BaseFormat == GL_RG) { + temp_format = MESA_FORMAT_RG88; + components = 2; + } else if (srcImage->_BaseFormat == GL_RGBA) { + temp_format = MESA_FORMAT_RGBA8888; + components = 4; + } else if (srcImage->_BaseFormat == GL_LUMINANCE) { + temp_format = MESA_FORMAT_L8; + components = 1; + } else if (srcImage->_BaseFormat == GL_LUMINANCE_ALPHA) { + temp_format = MESA_FORMAT_AL88; + components = 2; + } else { + _mesa_problem(ctx, "bad srcImage->_BaseFormat in _mesa_generate_mipmaps"); + return; + } + + /* allocate storage for uncompressed GL_RGB or GL_RGBA images */ + temp_src_stride = _mesa_format_row_stride(temp_format, srcImage->Width); + /* 20 extra bytes, just be safe when calling last FetchTexel */ + temp_src = (GLubyte *) malloc(temp_src_stride * srcImage->Height + 20); + if (!temp_src) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); + return; + } + + /* decompress base image to the temporary */ + for (row = 0; row < srcImage->Height; row++) { + GLuint col; + GLchan *dst = (GLchan *) temp_src + temp_src_stride * row; + for (col = 0; col < srcImage->Width; col++) { + srcImage->FetchTexelc(srcImage, col, row, 0, dst); + dst += components; + } + } + + _mesa_format_to_type_and_comps(temp_format, &datatype, &comps); + + for (level = texObj->BaseLevel; level < maxLevel; level++) { + /* generate image[level+1] from image[level] */ + const struct gl_texture_image *srcImage; + struct gl_texture_image *dstImage; + GLint srcWidth, srcHeight, srcDepth; + GLint dstWidth, dstHeight, dstDepth; + GLint border; + GLboolean nextLevel; + + /* get src image parameters */ + srcImage = _mesa_select_tex_image(ctx, texObj, target, level); + ASSERT(srcImage); + srcWidth = srcImage->Width; + srcHeight = srcImage->Height; + srcDepth = srcImage->Depth; + border = srcImage->Border; + + nextLevel = next_mipmap_level_size(target, border, + srcWidth, srcHeight, srcDepth, + &dstWidth, &dstHeight, &dstDepth); + if (!nextLevel) + break; + + temp_dst_stride = _mesa_format_row_stride(temp_format, dstWidth); + if (!temp_dst) { + temp_dst = (GLubyte *) malloc(temp_dst_stride * dstHeight); + if (!temp_dst) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); + break; + } + } + + /* get dest gl_texture_image */ + dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1); + if (!dstImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); + return; } + _mesa_generate_mipmap_level(target, datatype, comps, border, + srcWidth, srcHeight, srcDepth, + temp_src, temp_src_stride / components, + dstWidth, dstHeight, dstDepth, + temp_dst, temp_dst_stride / components); + + /* initialize new image */ + _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight, + dstDepth, border, srcImage->InternalFormat, + srcImage->TexFormat); + + ctx->Driver.TexImage2D(ctx, target, level + 1, + srcImage->InternalFormat, + dstWidth, dstHeight, border, + _mesa_get_format_base_format(temp_format), + GL_UNSIGNED_BYTE, + temp_dst, &ctx->DefaultPacking, texObj, dstImage); + + /* swap src and dest pointers */ + { + GLchan *temp = temp_src; + temp_src = temp_dst; + temp_dst = temp; + + temp_src_stride = temp_dst_stride; + } } /* loop over mipmap levels */ + + free((void *) temp_src); + free(temp_dst); +} + +/** + * Automatic mipmap generation. + * This is the fallback/default function for ctx->Driver.GenerateMipmap(). + * Generate a complete set of mipmaps from texObj's BaseLevel image. + * Stop at texObj's MaxLevel or when we get to the 1x1 texture. + * For cube maps, target will be one of + * GL_TEXTURE_CUBE_MAP_POSITIVE/NEGATIVE_X/Y/Z; never GL_TEXTURE_CUBE_MAP. + */ +void +_mesa_generate_mipmap(struct gl_context *ctx, GLenum target, + struct gl_texture_object *texObj) +{ + const struct gl_texture_image *srcImage; + GLint maxLevel; + + ASSERT(texObj); + srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel); + ASSERT(srcImage); + + maxLevel = _mesa_max_texture_levels(ctx, texObj->Target) - 1; + ASSERT(maxLevel >= 0); /* bad target */ + + maxLevel = MIN2(maxLevel, texObj->MaxLevel); + + if (_mesa_is_format_compressed(srcImage->TexFormat)) { + generate_mipmap_compressed(ctx, target, texObj, srcImage, maxLevel); + } else { + generate_mipmap_uncompressed(ctx, target, texObj, srcImage, maxLevel); + } } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index eb2efc89aed..f018c75cc6a 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1435,8 +1435,7 @@ struct gl_texgen /** * Texture unit state. Contains enable flags, texture environment/function/ - * combiners, texgen state, pointers to current texture objects and - * post-filter color tables. + * combiners, texgen state, and pointers to current texture objects. */ struct gl_texture_unit { diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c index d6470e351b8..a232a51c355 100644 --- a/src/mesa/main/pack.c +++ b/src/mesa/main/pack.c @@ -4683,7 +4683,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n, GLenum srcType, const GLvoid *source, const struct gl_pixelstore_attrib *srcPacking ) { - GLfloat *depthTemp, *depthValues; + GLfloat *depthTemp = NULL, *depthValues; GLboolean needClamp = GL_FALSE; /* Look for special cases first. @@ -4729,16 +4729,16 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n, /* general case path follows */ - depthTemp = (GLfloat *) malloc(n * sizeof(GLfloat)); - if (!depthTemp) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); - return; - } - if (dstType == GL_FLOAT) { depthValues = (GLfloat *) dest; } else { + depthTemp = (GLfloat *) malloc(n * sizeof(GLfloat)); + if (!depthTemp) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + return; + } + depthValues = depthTemp; } @@ -4782,6 +4782,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n, } zValues[i] = value & 0xffffff00; } + free(depthTemp); return; } else { diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c index fa884c0de93..c36175c60e7 100644 --- a/src/mesa/main/renderbuffer.c +++ b/src/mesa/main/renderbuffer.c @@ -2567,26 +2567,3 @@ _mesa_reference_renderbuffer(struct gl_renderbuffer **ptr, *ptr = rb; } } - - -/** - * Create a new combined depth/stencil renderbuffer for implementing - * the GL_EXT_packed_depth_stencil extension. - * \return new depth/stencil renderbuffer - */ -struct gl_renderbuffer * -_mesa_new_depthstencil_renderbuffer(struct gl_context *ctx, GLuint name) -{ - struct gl_renderbuffer *dsrb; - - dsrb = _mesa_new_renderbuffer(ctx, name); - if (!dsrb) - return NULL; - - /* init fields not covered by _mesa_new_renderbuffer() */ - dsrb->InternalFormat = GL_DEPTH24_STENCIL8_EXT; - dsrb->Format = MESA_FORMAT_Z24_S8; - dsrb->AllocStorage = _mesa_soft_renderbuffer_storage; - - return dsrb; -} diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h index 39d9b3035e6..53da5b03385 100644 --- a/src/mesa/main/renderbuffer.h +++ b/src/mesa/main/renderbuffer.h @@ -108,8 +108,5 @@ extern void _mesa_reference_renderbuffer(struct gl_renderbuffer **ptr, struct gl_renderbuffer *rb); -extern struct gl_renderbuffer * -_mesa_new_depthstencil_renderbuffer(struct gl_context *ctx, GLuint name); - #endif /* RENDERBUFFER_H */ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 4696dbb526f..7ad50bcaddc 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -192,7 +192,10 @@ update_arrays( struct gl_context *ctx ) static void update_program_enables(struct gl_context *ctx) { - /* These _Enabled flags indicate if the program is enabled AND valid. */ + /* These _Enabled flags indicate if the user-defined ARB/NV vertex/fragment + * program is enabled AND valid. Similarly for ATI fragment shaders. + * GLSL shaders not relevant here. + */ ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled && ctx->VertexProgram.Current->Base.Instructions; ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled @@ -203,11 +206,12 @@ update_program_enables(struct gl_context *ctx) /** - * Update vertex/fragment program state. In particular, update these fields: - * ctx->VertexProgram._Current - * ctx->VertexProgram._TnlProgram, - * These point to the highest priority enabled vertex/fragment program or are - * NULL if fixed-function processing is to be done. + * Update the ctx->Vertex/Geometry/FragmentProgram._Current pointers to point + * to the current/active programs. Then call ctx->Driver.BindProgram() to + * tell the driver which programs to use. + * + * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment + * programs or programs derived from fixed-function state. * * This function needs to be called after texture state validation in case * we're generating a fragment program from fixed-function texture state. @@ -243,34 +247,33 @@ update_program(struct gl_context *ctx) */ if (fsProg && fsProg->LinkStatus && fsProg->FragmentProgram) { - /* Use shader programs */ + /* Use GLSL fragment shader */ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, fsProg->FragmentProgram); } else if (ctx->FragmentProgram._Enabled) { - /* use user-defined vertex program */ + /* Use user-defined fragment program */ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, ctx->FragmentProgram.Current); } else if (ctx->FragmentProgram._MaintainTexEnvProgram) { - /* Use fragment program generated from fixed-function state. - */ + /* Use fragment program generated from fixed-function state */ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, _mesa_get_fixed_func_fragment_program(ctx)); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, ctx->FragmentProgram._Current); } else { - /* no fragment program */ + /* No fragment program */ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); } if (gsProg && gsProg->LinkStatus && gsProg->GeometryProgram) { - /* Use shader programs */ + /* Use GLSL geometry shader */ _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, gsProg->GeometryProgram); } else { - /* no fragment program */ + /* No geometry program */ _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL); } @@ -279,18 +282,17 @@ update_program(struct gl_context *ctx) * fragprog inputs. */ if (vsProg && vsProg->LinkStatus && vsProg->VertexProgram) { - /* Use shader programs */ + /* Use GLSL vertex shader */ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, - vsProg->VertexProgram); + vsProg->VertexProgram); } else if (ctx->VertexProgram._Enabled) { - /* use user-defined vertex program */ + /* Use user-defined vertex program */ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, ctx->VertexProgram.Current); } else if (ctx->VertexProgram._MaintainTnlProgram) { - /* Use vertex program generated from fixed-function state. - */ + /* Use vertex program generated from fixed-function state */ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, _mesa_get_fixed_func_vertex_program(ctx)); _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, @@ -416,29 +418,44 @@ update_color(struct gl_context *ctx) ctx->Color._LogicOpEnabled = _mesa_rgba_logicop_enabled(ctx); } + +/** + * Update the ctx->Color._ClampFragmentColor field + */ static void update_clamp_fragment_color(struct gl_context *ctx) { - if(ctx->Color.ClampFragmentColor == GL_FIXED_ONLY_ARB) - ctx->Color._ClampFragmentColor = !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode; + if (ctx->Color.ClampFragmentColor == GL_FIXED_ONLY_ARB) + ctx->Color._ClampFragmentColor = + !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode; else ctx->Color._ClampFragmentColor = ctx->Color.ClampFragmentColor; } + +/** + * Update the ctx->Color._ClampVertexColor field + */ static void update_clamp_vertex_color(struct gl_context *ctx) { - if(ctx->Light.ClampVertexColor == GL_FIXED_ONLY_ARB) - ctx->Light._ClampVertexColor = !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode; + if (ctx->Light.ClampVertexColor == GL_FIXED_ONLY_ARB) + ctx->Light._ClampVertexColor = + !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode; else ctx->Light._ClampVertexColor = ctx->Light.ClampVertexColor; } + +/** + * Update the ctx->Color._ClampReadColor field + */ static void update_clamp_read_color(struct gl_context *ctx) { - if(ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB) - ctx->Color._ClampReadColor = !ctx->ReadBuffer || !ctx->ReadBuffer->Visual.floatMode; + if (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB) + ctx->Color._ClampReadColor = + !ctx->ReadBuffer || !ctx->ReadBuffer->Visual.floatMode; else ctx->Color._ClampReadColor = ctx->Color.ClampReadColor; } diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c index 97d10122541..26c2ff98ba1 100644 --- a/src/mesa/main/texgetimage.c +++ b/src/mesa/main/texgetimage.c @@ -233,6 +233,7 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions, const GLint width = texImage->Width; const GLint height = texImage->Height; const GLint depth = texImage->Depth; + const GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat); /* Normally, no pixel transfer ops are performed during glGetTexImage. * The only possible exception is component clamping to [0,1]. */ @@ -248,6 +249,19 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions, return; } + /* Clamping does not apply to GetTexImage (final conversion)? + * Looks like we need clamp though when going from format + * containing negative values to unsigned format. + */ + if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) { + transferOps |= IMAGE_CLAMP_BIT; + } + else if (!type_with_negative_values(type) && + (dataType == GL_FLOAT || + dataType == GL_SIGNED_NORMALIZED)) { + transferOps |= IMAGE_CLAMP_BIT; + } + /* glGetTexImage always returns sRGB data for sRGB textures. Make sure the * fetch functions return sRGB data without linearizing it. */ @@ -262,20 +276,6 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions, width, height, format, type, img, row, 0); GLint col; - GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat); - - /* clamp does not apply to GetTexImage (final conversion)? - * Looks like we need clamp though when going from format - * containing negative values to unsigned format. - */ - if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) { - transferOps |= IMAGE_CLAMP_BIT; - } - else if (!type_with_negative_values(type) && - (dataType == GL_FLOAT || - dataType == GL_SIGNED_NORMALIZED)) { - transferOps |= IMAGE_CLAMP_BIT; - } for (col = 0; col < width; col++) { texImage->FetchTexelf(texImage, col, row, img, rgba[col]); diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 0827cb883e8..6f53686e7ff 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1685,11 +1685,15 @@ texture_error_check( struct gl_context *ctx, /* additional checks for depth textures */ if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) { - /* Only 1D, 2D and rectangular textures supported, not 3D or cubes */ + /* Only 1D, 2D, rect and array textures supported, not 3D or cubes */ if (target != GL_TEXTURE_1D && target != GL_PROXY_TEXTURE_1D && target != GL_TEXTURE_2D && target != GL_PROXY_TEXTURE_2D && + target != GL_TEXTURE_1D_ARRAY && + target != GL_PROXY_TEXTURE_1D_ARRAY && + target != GL_TEXTURE_2D_ARRAY && + target != GL_PROXY_TEXTURE_2D_ARRAY && target != GL_TEXTURE_RECTANGLE_ARB && target != GL_PROXY_TEXTURE_RECTANGLE_ARB) { if (!isProxy) @@ -3270,7 +3274,7 @@ compressedteximage(struct gl_context *ctx, GLuint dims, border, imageSize, &reason); if (error) { - _mesa_error(ctx, error, "glTexImage2D(%s)", reason); + _mesa_error(ctx, error, "glCompressedTexImage%uD(%s)", dims, reason); return; } diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index fdf12817c9a..565a3a2d8df 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -879,6 +879,8 @@ unbind_texobj_from_fbo(struct gl_context *ctx, for (j = 0; j < BUFFER_COUNT; j++) { if (fb->Attachment[j].Type == GL_TEXTURE && fb->Attachment[j].Texture == texObj) { + /* Vertices are already flushed by _mesa_DeleteTextures */ + ctx->NewState |= _NEW_BUFFERS; _mesa_remove_attachment(ctx, fb->Attachment + j); } } diff --git a/src/mesa/main/texrender.h b/src/mesa/main/texrender.h deleted file mode 100644 index cacd091160e..00000000000 --- a/src/mesa/main/texrender.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef TEXRENDER_H -#define TEXRENDER_H - -struct gl_context; -struct gl_framebuffer; -struct gl_renderbuffer_attachment; - -extern void -_mesa_render_texture(struct gl_context *ctx, - struct gl_framebuffer *fb, - struct gl_renderbuffer_attachment *att); - -extern void -_mesa_finish_render_texture(struct gl_context *ctx, - struct gl_renderbuffer_attachment *att); - - -#endif /* TEXRENDER_H */ diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 6da3e4eb7b4..5c925a3d314 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -3308,10 +3308,12 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS) GLint img, row; ASSERT(dstFormat == MESA_FORMAT_Z24_S8); - ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT); + ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || + srcFormat == GL_DEPTH_COMPONENT || + srcFormat == GL_STENCIL_INDEX); ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT); - if (srcFormat != GL_DEPTH_COMPONENT && ctx->Pixel.DepthScale == 1.0f && + if (srcFormat == GL_DEPTH_STENCIL && ctx->Pixel.DepthScale == 1.0f && ctx->Pixel.DepthBias == 0.0f && !srcPacking->SwapBytes) { /* simple path */ @@ -3322,7 +3324,8 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS) srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, srcPacking); } - else if (srcFormat == GL_DEPTH_COMPONENT) { + else if (srcFormat == GL_DEPTH_COMPONENT || + srcFormat == GL_STENCIL_INDEX) { /* In case we only upload depth we need to preserve the stencil */ for (img = 0; img < srcDepth; img++) { GLuint *dstRow = (GLuint *) dstAddr diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h index 2e6335846e3..0a0512c339d 100644 --- a/src/mesa/main/version.h +++ b/src/mesa/main/version.h @@ -33,9 +33,9 @@ struct gl_context; /* Mesa version */ #define MESA_MAJOR 7 -#define MESA_MINOR 11 +#define MESA_MINOR 12 #define MESA_PATCH 0 -#define MESA_VERSION_STRING "7.11-devel" +#define MESA_VERSION_STRING "7.12-devel" /* To make version comparison easy */ #define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 00869979dd8..67adb8f3dcd 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -1296,8 +1296,11 @@ ir_to_mesa_visitor::visit(ir_expression *ir) emit_scalar(ir, OPCODE_RSQ, result_dst, op[0]); break; case ir_unop_i2f: + case ir_unop_u2f: case ir_unop_b2f: case ir_unop_b2i: + case ir_unop_i2u: + case ir_unop_u2i: /* Mesa IR lacks types, ints are stored as truncated floats. */ result_src = op[0]; break; @@ -1335,7 +1338,6 @@ ir_to_mesa_visitor::visit(ir_expression *ir) break; case ir_unop_bit_not: - case ir_unop_u2f: case ir_binop_lshift: case ir_binop_rshift: case ir_binop_bit_and: diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak index 9b2cb1a3c14..4b2ec08bbb0 100644 --- a/src/mesa/sources.mak +++ b/src/mesa/sources.mak @@ -92,7 +92,6 @@ MAIN_SOURCES = \ main/texobj.c \ main/texpal.c \ main/texparam.c \ - main/texrender.c \ main/texstate.c \ main/texstore.c \ main/texturebarrier.c \ @@ -145,6 +144,7 @@ SWRAST_SOURCES = \ swrast/s_stencil.c \ swrast/s_texcombine.c \ swrast/s_texfilter.c \ + swrast/s_texrender.c \ swrast/s_triangle.c \ swrast/s_zoom.c diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index d1844e1066f..4c9a2b95ac3 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -156,7 +156,7 @@ translate_logicop(GLenum logicop) * Figure out if colormasks are different per rt. */ static GLboolean -colormask_per_rt(struct gl_context *ctx) +colormask_per_rt(const struct gl_context *ctx) { /* a bit suboptimal have to compare lots of values */ unsigned i; @@ -172,7 +172,7 @@ colormask_per_rt(struct gl_context *ctx) * Figure out if blend enables/state are different per rt. */ static GLboolean -blend_per_rt(struct gl_context *ctx) +blend_per_rt(const struct gl_context *ctx) { if (ctx->Color.BlendEnabled && (ctx->Color.BlendEnabled != ((1 << ctx->Const.MaxDrawBuffers) - 1))) { @@ -190,13 +190,14 @@ static void update_blend( struct st_context *st ) { struct pipe_blend_state *blend = &st->state.blend; + const struct gl_context *ctx = st->ctx; unsigned num_state = 1; unsigned i, j; memset(blend, 0, sizeof(*blend)); - if (blend_per_rt(st->ctx) || colormask_per_rt(st->ctx)) { - num_state = st->ctx->Const.MaxDrawBuffers; + if (blend_per_rt(ctx) || colormask_per_rt(ctx)) { + num_state = ctx->Const.MaxDrawBuffers; blend->independent_blend_enable = 1; } /* Note it is impossible to correctly deal with EXT_blend_logic_op and @@ -205,52 +206,52 @@ update_blend( struct st_context *st ) and separate alpha/rgb logicop/blend support respectively. Neither possible in gallium nor most hardware. Assume these combinations don't happen. */ - if (st->ctx->Color.ColorLogicOpEnabled || - (st->ctx->Color.BlendEnabled && - st->ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) { + if (ctx->Color.ColorLogicOpEnabled || + (ctx->Color.BlendEnabled && + ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) { /* logicop enabled */ blend->logicop_enable = 1; - blend->logicop_func = translate_logicop(st->ctx->Color.LogicOp); + blend->logicop_func = translate_logicop(ctx->Color.LogicOp); } - else if (st->ctx->Color.BlendEnabled) { + else if (ctx->Color.BlendEnabled) { /* blending enabled */ for (i = 0, j = 0; i < num_state; i++) { - blend->rt[i].blend_enable = (st->ctx->Color.BlendEnabled >> i) & 0x1; + blend->rt[i].blend_enable = (ctx->Color.BlendEnabled >> i) & 0x1; - if (st->ctx->Extensions.ARB_draw_buffers_blend) + if (ctx->Extensions.ARB_draw_buffers_blend) j = i; blend->rt[i].rgb_func = - translate_blend(st->ctx->Color.Blend[j].EquationRGB); + translate_blend(ctx->Color.Blend[j].EquationRGB); - if (st->ctx->Color.Blend[i].EquationRGB == GL_MIN || - st->ctx->Color.Blend[i].EquationRGB == GL_MAX) { + if (ctx->Color.Blend[i].EquationRGB == GL_MIN || + ctx->Color.Blend[i].EquationRGB == GL_MAX) { /* Min/max are special */ blend->rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; } else { blend->rt[i].rgb_src_factor = - translate_blend(st->ctx->Color.Blend[j].SrcRGB); + translate_blend(ctx->Color.Blend[j].SrcRGB); blend->rt[i].rgb_dst_factor = - translate_blend(st->ctx->Color.Blend[j].DstRGB); + translate_blend(ctx->Color.Blend[j].DstRGB); } blend->rt[i].alpha_func = - translate_blend(st->ctx->Color.Blend[j].EquationA); + translate_blend(ctx->Color.Blend[j].EquationA); - if (st->ctx->Color.Blend[i].EquationA == GL_MIN || - st->ctx->Color.Blend[i].EquationA == GL_MAX) { + if (ctx->Color.Blend[i].EquationA == GL_MIN || + ctx->Color.Blend[i].EquationA == GL_MAX) { /* Min/max are special */ blend->rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE; blend->rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; } else { blend->rt[i].alpha_src_factor = - translate_blend(st->ctx->Color.Blend[j].SrcA); + translate_blend(ctx->Color.Blend[j].SrcA); blend->rt[i].alpha_dst_factor = - translate_blend(st->ctx->Color.Blend[j].DstA); + translate_blend(ctx->Color.Blend[j].DstA); } } } @@ -260,25 +261,25 @@ update_blend( struct st_context *st ) /* Colormask - maybe reverse these bits? */ for (i = 0; i < num_state; i++) { - if (st->ctx->Color.ColorMask[i][0]) + if (ctx->Color.ColorMask[i][0]) blend->rt[i].colormask |= PIPE_MASK_R; - if (st->ctx->Color.ColorMask[i][1]) + if (ctx->Color.ColorMask[i][1]) blend->rt[i].colormask |= PIPE_MASK_G; - if (st->ctx->Color.ColorMask[i][2]) + if (ctx->Color.ColorMask[i][2]) blend->rt[i].colormask |= PIPE_MASK_B; - if (st->ctx->Color.ColorMask[i][3]) + if (ctx->Color.ColorMask[i][3]) blend->rt[i].colormask |= PIPE_MASK_A; } - if (st->ctx->Color.DitherFlag) + if (ctx->Color.DitherFlag) blend->dither = 1; - if (st->ctx->Multisample.Enabled) { + if (ctx->Multisample.Enabled) { /* unlike in gallium/d3d10 these operations are only performed if msaa is enabled */ - if (st->ctx->Multisample.SampleAlphaToCoverage) + if (ctx->Multisample.SampleAlphaToCoverage) blend->alpha_to_coverage = 1; - if (st->ctx->Multisample.SampleAlphaToOne) + if (ctx->Multisample.SampleAlphaToOne) blend->alpha_to_one = 1; } @@ -286,7 +287,7 @@ update_blend( struct st_context *st ) { struct pipe_blend_color bc; - COPY_4FV(bc.color, st->ctx->Color.BlendColorUnclamped); + COPY_4FV(bc.color, ctx->Color.BlendColorUnclamped); cso_set_blend_color(st->cso_context, &bc); } } diff --git a/src/mesa/state_tracker/st_atom_clip.c b/src/mesa/state_tracker/st_atom_clip.c index 16f7aaae6f4..1330db843a6 100644 --- a/src/mesa/state_tracker/st_atom_clip.c +++ b/src/mesa/state_tracker/st_atom_clip.c @@ -43,20 +43,21 @@ static void update_clip( struct st_context *st ) { struct pipe_clip_state clip; + const struct gl_context *ctx = st->ctx; GLuint i; memset(&clip, 0, sizeof(clip)); for (i = 0; i < PIPE_MAX_CLIP_PLANES; i++) { - if (st->ctx->Transform.ClipPlanesEnabled & (1 << i)) { + if (ctx->Transform.ClipPlanesEnabled & (1 << i)) { memcpy(clip.ucp[clip.nr], - st->ctx->Transform._ClipUserPlane[i], + ctx->Transform._ClipUserPlane[i], sizeof(clip.ucp[0])); clip.nr++; } } - clip.depth_clamp = st->ctx->Transform.DepthClamp != GL_FALSE; + clip.depth_clamp = ctx->Transform.DepthClamp != GL_FALSE; if (memcmp(&clip, &st->state.clip, sizeof(clip)) != 0) { st->state.clip = clip; diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index 95b706cb96c..1f833d28212 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -94,7 +94,7 @@ create_color_map_texture(struct gl_context *ctx) const uint texSize = 256; /* simple, and usually perfect */ /* find an RGBA texture format */ - format = st_choose_format(pipe->screen, GL_RGBA, + format = st_choose_format(pipe->screen, GL_RGBA, GL_NONE, GL_NONE, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); /* create texture for color map/table */ diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 06024ad2657..731338f9beb 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -120,87 +120,91 @@ gl_filter_to_img_filter(GLenum filter) } } -static void convert_sampler(struct st_context *st, - struct pipe_sampler_state *sampler, - GLuint texUnit) + +static void +convert_sampler(struct st_context *st, + struct pipe_sampler_state *sampler, + GLuint texUnit) { - struct gl_texture_object *texobj; - struct gl_sampler_object *msamp; - - texobj = st->ctx->Texture.Unit[texUnit]._Current; - if (!texobj) { - texobj = st_get_default_texture(st); - } - - msamp = _mesa_get_samplerobj(st->ctx, texUnit); - - memset(sampler, 0, sizeof(*sampler)); - sampler->wrap_s = gl_wrap_xlate(msamp->WrapS); - sampler->wrap_t = gl_wrap_xlate(msamp->WrapT); - sampler->wrap_r = gl_wrap_xlate(msamp->WrapR); - - sampler->min_img_filter = gl_filter_to_img_filter(msamp->MinFilter); - sampler->min_mip_filter = gl_filter_to_mip_filter(msamp->MinFilter); - sampler->mag_img_filter = gl_filter_to_img_filter(msamp->MagFilter); - - if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB) - sampler->normalized_coords = 1; - - sampler->lod_bias = st->ctx->Texture.Unit[texUnit].LodBias + - msamp->LodBias; - - sampler->min_lod = CLAMP(msamp->MinLod, - 0.0f, - (GLfloat) texobj->MaxLevel - texobj->BaseLevel); - sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel - texobj->BaseLevel, - msamp->MaxLod); - if (sampler->max_lod < sampler->min_lod) { - /* The GL spec doesn't seem to specify what to do in this case. - * Swap the values. - */ - float tmp = sampler->max_lod; - sampler->max_lod = sampler->min_lod; - sampler->min_lod = tmp; - assert(sampler->min_lod <= sampler->max_lod); - } - - if (msamp->BorderColor.ui[0] || - msamp->BorderColor.ui[1] || - msamp->BorderColor.ui[2] || - msamp->BorderColor.ui[3]) { - struct gl_texture_image *teximg; - - teximg = texobj->Image[0][texobj->BaseLevel]; - - st_translate_color(msamp->BorderColor.f, - teximg ? teximg->_BaseFormat : GL_RGBA, - sampler->border_color); - } - - sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ? - 0 : (GLuint) msamp->MaxAnisotropy); - - /* only care about ARB_shadow, not SGI shadow */ - if (msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) { - sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE; - sampler->compare_func - = st_compare_func_to_pipe(msamp->CompareFunc); - } - - sampler->seamless_cube_map = - st->ctx->Texture.CubeMapSeamless || msamp->CubeMapSeamless; + struct gl_texture_object *texobj; + struct gl_context *ctx = st->ctx; + struct gl_sampler_object *msamp; + + texobj = ctx->Texture.Unit[texUnit]._Current; + if (!texobj) { + texobj = st_get_default_texture(st); + } + + msamp = _mesa_get_samplerobj(ctx, texUnit); + + memset(sampler, 0, sizeof(*sampler)); + sampler->wrap_s = gl_wrap_xlate(msamp->WrapS); + sampler->wrap_t = gl_wrap_xlate(msamp->WrapT); + sampler->wrap_r = gl_wrap_xlate(msamp->WrapR); + + sampler->min_img_filter = gl_filter_to_img_filter(msamp->MinFilter); + sampler->min_mip_filter = gl_filter_to_mip_filter(msamp->MinFilter); + sampler->mag_img_filter = gl_filter_to_img_filter(msamp->MagFilter); + + if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB) + sampler->normalized_coords = 1; + + sampler->lod_bias = ctx->Texture.Unit[texUnit].LodBias + msamp->LodBias; + + sampler->min_lod = CLAMP(msamp->MinLod, + 0.0f, + (GLfloat) texobj->MaxLevel - texobj->BaseLevel); + sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel - texobj->BaseLevel, + msamp->MaxLod); + if (sampler->max_lod < sampler->min_lod) { + /* The GL spec doesn't seem to specify what to do in this case. + * Swap the values. + */ + float tmp = sampler->max_lod; + sampler->max_lod = sampler->min_lod; + sampler->min_lod = tmp; + assert(sampler->min_lod <= sampler->max_lod); + } + + if (msamp->BorderColor.ui[0] || + msamp->BorderColor.ui[1] || + msamp->BorderColor.ui[2] || + msamp->BorderColor.ui[3]) { + struct gl_texture_image *teximg; + + teximg = texobj->Image[0][texobj->BaseLevel]; + + st_translate_color(msamp->BorderColor.f, + teximg ? teximg->_BaseFormat : GL_RGBA, + sampler->border_color); + } + + sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ? + 0 : (GLuint) msamp->MaxAnisotropy); + + /* only care about ARB_shadow, not SGI shadow */ + if (msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) { + sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE; + sampler->compare_func + = st_compare_func_to_pipe(msamp->CompareFunc); + } + + sampler->seamless_cube_map = + ctx->Texture.CubeMapSeamless || msamp->CubeMapSeamless; } + static void update_vertex_samplers(struct st_context *st) { - struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current; + const struct gl_context *ctx = st->ctx; + struct gl_vertex_program *vprog = ctx->VertexProgram._Current; GLuint su; st->state.num_vertex_samplers = 0; /* loop over sampler units (aka tex image units) */ - for (su = 0; su < st->ctx->Const.MaxVertexTextureImageUnits; su++) { + for (su = 0; su < ctx->Const.MaxVertexTextureImageUnits; su++) { struct pipe_sampler_state *sampler = st->state.vertex_samplers + su; if (vprog->Base.SamplersUsed & (1 << su)) { @@ -220,16 +224,18 @@ update_vertex_samplers(struct st_context *st) cso_single_vertex_sampler_done(st->cso_context); } + static void update_fragment_samplers(struct st_context *st) { - struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; + const struct gl_context *ctx = st->ctx; + struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; GLuint su; st->state.num_samplers = 0; /* loop over sampler units (aka tex image units) */ - for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) { + for (su = 0; su < ctx->Const.MaxTextureImageUnits; su++) { struct pipe_sampler_state *sampler = st->state.samplers + su; @@ -254,6 +260,7 @@ update_fragment_samplers(struct st_context *st) cso_single_sampler_done(st->cso_context); } + static void update_samplers(struct st_context *st) { @@ -261,6 +268,7 @@ update_samplers(struct st_context *st) update_vertex_samplers(st); } + const struct st_tracked_state st_update_sampler = { "st_update_sampler", /* name */ { /* dirty */ diff --git a/src/mesa/state_tracker/st_atom_scissor.c b/src/mesa/state_tracker/st_atom_scissor.c index 56b1383ae39..eb13877787b 100644 --- a/src/mesa/state_tracker/st_atom_scissor.c +++ b/src/mesa/state_tracker/st_atom_scissor.c @@ -44,7 +44,8 @@ static void update_scissor( struct st_context *st ) { struct pipe_scissor_state scissor; - const struct gl_framebuffer *fb = st->ctx->DrawBuffer; + const struct gl_context *ctx = st->ctx; + const struct gl_framebuffer *fb = ctx->DrawBuffer; GLint miny, maxy; scissor.minx = 0; @@ -52,15 +53,15 @@ update_scissor( struct st_context *st ) scissor.maxx = fb->Width; scissor.maxy = fb->Height; - if (st->ctx->Scissor.Enabled) { + if (ctx->Scissor.Enabled) { /* need to be careful here with xmax or ymax < 0 */ - GLint xmax = MAX2(0, st->ctx->Scissor.X + st->ctx->Scissor.Width); - GLint ymax = MAX2(0, st->ctx->Scissor.Y + st->ctx->Scissor.Height); + GLint xmax = MAX2(0, ctx->Scissor.X + ctx->Scissor.Width); + GLint ymax = MAX2(0, ctx->Scissor.Y + ctx->Scissor.Height); - if (st->ctx->Scissor.X > (GLint)scissor.minx) - scissor.minx = st->ctx->Scissor.X; - if (st->ctx->Scissor.Y > (GLint)scissor.miny) - scissor.miny = st->ctx->Scissor.Y; + if (ctx->Scissor.X > (GLint)scissor.minx) + scissor.minx = ctx->Scissor.X; + if (ctx->Scissor.Y > (GLint)scissor.miny) + scissor.miny = ctx->Scissor.Y; if (xmax < (GLint) scissor.maxx) scissor.maxx = xmax; diff --git a/src/mesa/state_tracker/st_atom_stipple.c b/src/mesa/state_tracker/st_atom_stipple.c index ecdd9f06f6a..b3e0dc7f1b0 100644 --- a/src/mesa/state_tracker/st_atom_stipple.c +++ b/src/mesa/state_tracker/st_atom_stipple.c @@ -64,17 +64,18 @@ invert_stipple(GLuint dest[32], const GLuint src[32], GLuint winHeight) static void update_stipple( struct st_context *st ) { + const struct gl_context *ctx = st->ctx; const GLuint sz = sizeof(st->state.poly_stipple); - assert(sz == sizeof(st->ctx->PolygonStipple)); + assert(sz == sizeof(ctx->PolygonStipple)); - if (memcmp(st->state.poly_stipple, st->ctx->PolygonStipple, sz)) { + if (memcmp(st->state.poly_stipple, ctx->PolygonStipple, sz)) { /* state has changed */ struct pipe_poly_stipple newStipple; - memcpy(st->state.poly_stipple, st->ctx->PolygonStipple, sz); + memcpy(st->state.poly_stipple, ctx->PolygonStipple, sz); - invert_stipple(newStipple.stipple, st->ctx->PolygonStipple, - st->ctx->DrawBuffer->Height); + invert_stipple(newStipple.stipple, ctx->PolygonStipple, + ctx->DrawBuffer->Height); st->pipe->set_polygon_stipple(st->pipe, &newStipple); } diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 072eb977ebb..800a9f1f0e0 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -187,15 +187,16 @@ update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_ GLuint texUnit) { struct pipe_context *pipe = st->pipe; + struct gl_context *ctx = st->ctx; const struct gl_sampler_object *samp; struct gl_texture_object *texObj; struct st_texture_object *stObj; enum pipe_format st_view_format; GLboolean retval; - samp = _mesa_get_samplerobj(st->ctx, texUnit); + samp = _mesa_get_samplerobj(ctx, texUnit); - texObj = st->ctx->Texture.Unit[texUnit]._Current; + texObj = ctx->Texture.Unit[texUnit]._Current; if (!texObj) { texObj = st_get_default_texture(st); @@ -203,7 +204,7 @@ update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_ } stObj = st_texture_object(texObj); - retval = st_finalize_texture(st->ctx, st->pipe, texObj); + retval = st_finalize_texture(ctx, st->pipe, texObj); if (!retval) { /* out of mem */ return GL_FALSE; @@ -253,13 +254,14 @@ update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_ static void update_vertex_textures(struct st_context *st) { - struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current; + const struct gl_context *ctx = st->ctx; + struct gl_vertex_program *vprog = ctx->VertexProgram._Current; GLuint su; st->state.num_vertex_textures = 0; /* loop over sampler units (aka tex image units) */ - for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) { + for (su = 0; su < ctx->Const.MaxTextureImageUnits; su++) { struct pipe_sampler_view *sampler_view = NULL; if (vprog->Base.SamplersUsed & (1 << su)) { GLboolean retval; @@ -277,9 +279,9 @@ update_vertex_textures(struct st_context *st) pipe_sampler_view_reference(&st->state.sampler_vertex_views[su], sampler_view); } - if (st->ctx->Const.MaxVertexTextureImageUnits > 0) { + if (ctx->Const.MaxVertexTextureImageUnits > 0) { GLuint numUnits = MIN2(st->state.num_vertex_textures, - st->ctx->Const.MaxVertexTextureImageUnits); + ctx->Const.MaxVertexTextureImageUnits); cso_set_vertex_sampler_views(st->cso_context, numUnits, st->state.sampler_vertex_views); @@ -289,13 +291,14 @@ update_vertex_textures(struct st_context *st) static void update_fragment_textures(struct st_context *st) { - struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; + const struct gl_context *ctx = st->ctx; + struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; GLuint su; st->state.num_textures = 0; /* loop over sampler units (aka tex image units) */ - for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) { + for (su = 0; su < ctx->Const.MaxTextureImageUnits; su++) { struct pipe_sampler_view *sampler_view = NULL; if (fprog->Base.SamplersUsed & (1 << su)) { GLboolean retval; @@ -338,22 +341,23 @@ const struct st_tracked_state st_update_vertex_texture = { static void finalize_textures(struct st_context *st) { - struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; + struct gl_context *ctx = st->ctx; + struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; const GLboolean prev_missing_textures = st->missing_textures; GLuint su; st->missing_textures = GL_FALSE; - for (su = 0; su < st->ctx->Const.MaxTextureCoordUnits; su++) { + for (su = 0; su < ctx->Const.MaxTextureCoordUnits; su++) { if (fprog->Base.SamplersUsed & (1 << su)) { const GLuint texUnit = fprog->Base.SamplerUnits[su]; struct gl_texture_object *texObj - = st->ctx->Texture.Unit[texUnit]._Current; + = ctx->Texture.Unit[texUnit]._Current; if (texObj) { GLboolean retval; - retval = st_finalize_texture(st->ctx, st->pipe, texObj); + retval = st_finalize_texture(ctx, st->pipe, texObj); if (!retval) { /* out of mem */ st->missing_textures = GL_TRUE; diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 965fbcd1d9e..d61d7ac22be 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -989,8 +989,9 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y, /* can we write to stencil if not fallback */ if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) goto stencil_fallback; - + tex_format = st_choose_format(st->pipe->screen, base_format(format), + GL_NONE, GL_NONE, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); if (tex_format == PIPE_FORMAT_Z24_UNORM_S8_USCALED) @@ -1399,13 +1400,14 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, /* srcFormat can't be used as a texture format */ if (type == GL_DEPTH) { texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT, - st->internal_target, sample_count, - PIPE_BIND_DEPTH_STENCIL); + GL_NONE, GL_NONE, st->internal_target, + sample_count, PIPE_BIND_DEPTH_STENCIL); assert(texFormat != PIPE_FORMAT_NONE); } else { /* default color format */ - texFormat = st_choose_format(screen, GL_RGBA, st->internal_target, + texFormat = st_choose_format(screen, GL_RGBA, + GL_NONE, GL_NONE, st->internal_target, sample_count, PIPE_BIND_SAMPLER_VIEW); assert(texFormat != PIPE_FORMAT_NONE); } diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 88f62902b25..6907cfc03cf 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -842,7 +842,7 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level, else { /* format translation via floats */ GLuint row; - enum pipe_format format = util_format_linear(dst_texture->format); + enum pipe_format pformat = util_format_linear(dst_texture->format); for (row = 0; row < height; row++) { const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ GLfloat rgba[4 * MAX_WIDTH]; @@ -854,7 +854,7 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level, /* get float[4] rgba row from surface */ pipe_get_tile_rgba_format(pipe, tex_xfer, 0, row, width, 1, - format, rgba); + pformat, rgba); _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, type, dest, &ctx->Pack, transferOps); @@ -1241,7 +1241,8 @@ fallback_copy_texsubimage(struct gl_context *ctx, GLenum target, GLint level, src_trans = pipe_get_transfer(pipe, strb->texture, - 0, 0, + strb->rtt_level, + strb->rtt_face + strb->rtt_slice, PIPE_TRANSFER_READ, srcX, srcY, width, height); diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/mesa/state_tracker/st_cb_viewport.c index 049755e45c0..d4742eb897d 100644 --- a/src/mesa/state_tracker/st_cb_viewport.c +++ b/src/mesa/state_tracker/st_cb_viewport.c @@ -56,13 +56,20 @@ static void st_viewport(struct gl_context * ctx, GLint x, GLint y, if (!st->invalidate_on_gl_viewport) return; + /* + * Normally we'd want the state tracker manager to mark the drawables + * invalid only when needed. This will force the state tracker manager + * to revalidate the drawable, rather than just update the context with + * the latest cached drawable info. + */ + stdraw = st_ws_framebuffer(st->ctx->DrawBuffer); stread = st_ws_framebuffer(st->ctx->ReadBuffer); - if (stdraw) - p_atomic_set(&stdraw->revalidate, TRUE); - if (stread && stread != stdraw) - p_atomic_set(&stread->revalidate, TRUE); + if (stdraw && stdraw->iface) + stdraw->iface_stamp = p_atomic_read(&stdraw->iface->stamp) - 1; + if (stread && stread != stdraw && stread->iface) + stread->iface_stamp = p_atomic_read(&stread->iface->stamp) - 1; } void st_init_viewport_functions(struct dd_function_table *functions) diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index ff207039d78..0a322022149 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -204,6 +204,9 @@ struct st_context /* Active render condition. */ struct pipe_query *render_condition; unsigned condition_mode; + + int32_t draw_stamp; + int32_t read_stamp; }; @@ -227,7 +230,8 @@ struct st_framebuffer struct st_framebuffer_iface *iface; enum st_attachment_type statts[ST_ATTACHMENT_COUNT]; unsigned num_statts; - int32_t revalidate; + int32_t stamp; + int32_t iface_stamp; }; diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 56955d357b1..5040c6fa5ab 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -33,7 +33,7 @@ * * We basically convert the VBO's vertex attribute/array information into * Gallium vertex state, bind the vertex buffer objects and call - * pipe->draw_elements(), pipe->draw_range_elements() or pipe->draw_arrays(). + * pipe->draw_vbo(). * * Authors: * Keith Whitwell <[email protected]> @@ -233,11 +233,26 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, } +/** + * This is very similar to vbo_all_varyings_in_vbos() but we test + * the stride. See bug 38626. + */ +static GLboolean +all_varyings_in_vbos(const struct gl_client_array *arrays[]) +{ + GLuint i; + + for (i = 0; i < VERT_ATTRIB_MAX; i++) + if (arrays[i]->StrideB && !_mesa_is_bufferobj(arrays[i]->BufferObj)) + return GL_FALSE; + + return GL_TRUE; +} + /** * Examine the active arrays to determine if we have interleaved * vertex arrays all living in one VBO, or all living in user space. - * \param userSpace returns whether the arrays are in user space. */ static GLboolean is_interleaved_arrays(const struct st_vertex_program *vp, @@ -247,8 +262,8 @@ is_interleaved_arrays(const struct st_vertex_program *vp, GLuint attr; const struct gl_buffer_object *firstBufObj = NULL; GLint firstStride = -1; - const GLubyte *client_addr = NULL; - GLboolean user_memory = GL_FALSE; + const GLubyte *firstPtr = NULL; + GLboolean userSpaceBuffer = GL_FALSE; for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; @@ -256,37 +271,26 @@ is_interleaved_arrays(const struct st_vertex_program *vp, const struct gl_buffer_object *bufObj = array->BufferObj; const GLsizei stride = array->StrideB; /* in bytes */ - if (firstStride < 0) { + if (attr == 0) { + /* save info about the first array */ firstStride = stride; - user_memory = !bufObj || !bufObj->Name; - } - else if (firstStride != stride) { - return GL_FALSE; - } - - if (!bufObj || !bufObj->Name) { - /* Try to detect if the client-space arrays are - * "close" to each other. - */ - if (!user_memory) { - return GL_FALSE; - } - if (!client_addr) { - client_addr = array->Ptr; - } - else if (abs(array->Ptr - client_addr) > firstStride) { - /* arrays start too far apart */ - return GL_FALSE; - } - } - else if (!firstBufObj) { - if (user_memory) { - return GL_FALSE; - } + firstPtr = array->Ptr; firstBufObj = bufObj; + userSpaceBuffer = !bufObj || !bufObj->Name; } - else if (bufObj != firstBufObj) { - return GL_FALSE; + else { + /* check if other arrays interleave with the first, in same buffer */ + if (stride != firstStride) + return GL_FALSE; /* strides don't match */ + + if (bufObj != firstBufObj) + return GL_FALSE; /* arrays in different VBOs */ + + if (abs(array->Ptr - firstPtr) > firstStride) + return GL_FALSE; /* arrays start too far apart */ + + if ((!bufObj || !_mesa_is_bufferobj(bufObj)) != userSpaceBuffer) + return GL_FALSE; /* mix of VBO and user-space arrays */ } } @@ -510,6 +514,7 @@ setup_index_buffer(struct gl_context *ctx, } } + /** * Prior to drawing, check that any uniforms referenced by the * current shader have been set. If a uniform has not been set, @@ -556,8 +561,8 @@ translate_prim(const struct gl_context *ctx, unsigned prim) assert(GL_TRIANGLE_STRIP_ADJACENCY == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY); /* Avoid quadstrips if it's easy to do so: - * Note: it's imporant to do the correct trimming if we change the prim type! - * We do that wherever this function is called. + * Note: it's important to do the correct trimming if we change the + * prim type! We do that wherever this function is called. */ if (prim == GL_QUAD_STRIP && ctx->Light.ShadeModel != GL_FLAT && @@ -650,7 +655,8 @@ st_draw_vbo(struct gl_context *ctx, struct pipe_draw_info info; unsigned i, num_instances = 1; GLboolean new_array = - st->dirty.st && (st->dirty.mesa & (_NEW_ARRAY | _NEW_PROGRAM)) != 0; + st->dirty.st && + (st->dirty.mesa & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0; /* Mesa core state should have been validated already */ assert(ctx->NewState == 0x0); @@ -658,7 +664,7 @@ st_draw_vbo(struct gl_context *ctx, if (ib) { /* Gallium probably doesn't want this in some cases. */ if (!index_bounds_valid) - if (!vbo_all_varyings_in_vbos(arrays)) + if (!all_varyings_in_vbos(arrays)) vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index); for (i = 0; i < nr_prims; i++) { @@ -738,8 +744,8 @@ st_draw_vbo(struct gl_context *ctx, } } - info.primitive_restart = st->ctx->Array.PrimitiveRestart; - info.restart_index = st->ctx->Array.RestartIndex; + info.primitive_restart = ctx->Array.PrimitiveRestart; + info.restart_index = ctx->Array.RestartIndex; /* do actual drawing */ for (i = 0; i < nr_prims; i++) { diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 35835712547..fa5d8f5050a 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -608,7 +608,7 @@ struct format_mapping * Multiple GL enums might map to multiple pipe_formats. * The first pipe format in the list that's supported is the one that's chosen. */ -static struct format_mapping format_map[] = { +static const struct format_mapping format_map[] = { /* Basic RGB, RGBA formats */ { { GL_RGB10, GL_RGB10_A2, 0 }, @@ -616,7 +616,7 @@ static struct format_mapping format_map[] = { }, { { 4, GL_RGBA, GL_RGBA8, 0 }, - { DEFAULT_RGBA_FORMATS, 0 } + { PIPE_FORMAT_R8G8B8A8_UNORM, DEFAULT_RGBA_FORMATS } }, { { GL_BGRA, 0 }, @@ -624,7 +624,7 @@ static struct format_mapping format_map[] = { }, { { 3, GL_RGB, GL_RGB8, 0 }, - { DEFAULT_RGB_FORMATS, 0 } + { DEFAULT_RGB_FORMATS } }, { { GL_RGB12, GL_RGB16, GL_RGBA12, GL_RGBA16, 0 }, @@ -1108,7 +1108,7 @@ static struct format_mapping format_map[] = { * Return first supported format from the given list. */ static enum pipe_format -find_supported_format(struct pipe_screen *screen, +find_supported_format(struct pipe_screen *screen, const enum pipe_format formats[], enum pipe_texture_target target, unsigned sample_count, @@ -1124,6 +1124,91 @@ find_supported_format(struct pipe_screen *screen, return PIPE_FORMAT_NONE; } +struct exact_format_mapping +{ + GLenum format; + GLenum type; + enum pipe_format pformat; +}; + +static const struct exact_format_mapping rgba8888_tbl[] = +{ + { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_A8B8G8R8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_A8B8G8R8_UNORM }, + { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_R8G8B8A8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_R8G8B8A8_UNORM }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_A8R8G8B8_UNORM }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_B8G8R8A8_UNORM }, + { GL_RGBA, GL_UNSIGNED_BYTE, PIPE_FORMAT_R8G8B8A8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_BYTE, PIPE_FORMAT_A8B8G8R8_UNORM }, + { GL_BGRA, GL_UNSIGNED_BYTE, PIPE_FORMAT_B8G8R8A8_UNORM }, + { 0, 0, 0 } +}; + +static const struct exact_format_mapping rgbx8888_tbl[] = +{ + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_X8R8G8B8_UNORM }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_B8G8R8X8_UNORM }, + { GL_BGRA, GL_UNSIGNED_BYTE, PIPE_FORMAT_B8G8R8X8_UNORM }, + /* No Mesa formats for these Gallium formats: + { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_X8B8G8R8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_X8B8G8R8_UNORM }, + { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_R8G8B8X8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_R8G8B8X8_UNORM }, + { GL_RGBA, GL_UNSIGNED_BYTE, PIPE_FORMAT_R8G8B8X8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_BYTE, PIPE_FORMAT_X8B8G8R8_UNORM }, + */ + { 0, 0, 0 } +}; + +static const struct exact_format_mapping rgba1010102_tbl[] = +{ + { GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, PIPE_FORMAT_B10G10R10A2_UNORM }, + /* No Mesa formats for these Gallium formats: + { GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, PIPE_FORMAT_R10G10B10A2_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_10_10_10_2, PIPE_FORMAT_R10G10B10A2_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT, PIPE_FORMAT_R10G10B10A2_UNORM }, + */ + { 0, 0, 0 } +}; + +/** + * If there is an exact pipe_format match for {internalFormat, format, type} + * return that, otherwise return PIPE_FORMAT_NONE so we can do fuzzy matching. + */ +static enum pipe_format +find_exact_format(GLint internalFormat, GLenum format, GLenum type) +{ + uint i; + const struct exact_format_mapping* tbl; + + if (format == GL_NONE || type == GL_NONE) + return PIPE_FORMAT_NONE; + + switch (internalFormat) { + case 4: + case GL_RGBA: + case GL_RGBA8: + tbl = rgba8888_tbl; + break; + case 3: + case GL_RGB: + case GL_RGB8: + tbl = rgbx8888_tbl; + break; + case GL_RGB10_A2: + tbl = rgba1010102_tbl; + break; + default: + return PIPE_FORMAT_NONE; + } + + for (i = 0; tbl[i].format; i++) + if (tbl[i].format == format && tbl[i].type == type) + return tbl[i].pformat; + + return PIPE_FORMAT_NONE; +} /** * Given an OpenGL internalFormat value for a texture or surface, return @@ -1140,11 +1225,13 @@ find_supported_format(struct pipe_screen *screen, */ enum pipe_format st_choose_format(struct pipe_screen *screen, GLenum internalFormat, + GLenum format, GLenum type, enum pipe_texture_target target, unsigned sample_count, unsigned bindings) { GET_CURRENT_CONTEXT(ctx); /* XXX this should be a function parameter */ int i, j; + enum pipe_format pf; /* can't render to compressed formats at this time */ if (_mesa_is_compressed_format(ctx, internalFormat) @@ -1152,6 +1239,13 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, return PIPE_FORMAT_NONE; } + /* search for exact matches */ + pf = find_exact_format(internalFormat, format, type); + if (pf != PIPE_FORMAT_NONE && + screen->is_format_supported(screen, pf, + target, sample_count, bindings)) + return pf; + /* search table for internalFormat */ for (i = 0; i < Elements(format_map); i++) { const struct format_mapping *mapping = &format_map[i]; @@ -1183,14 +1277,11 @@ st_choose_renderbuffer_format(struct pipe_screen *screen, usage = PIPE_BIND_DEPTH_STENCIL; else usage = PIPE_BIND_RENDER_TARGET; - return st_choose_format(screen, internalFormat, PIPE_TEXTURE_2D, + return st_choose_format(screen, internalFormat, GL_NONE, GL_NONE, PIPE_TEXTURE_2D, sample_count, usage); } -/** - * Called via ctx->Driver.chooseTextureFormat(). - */ gl_format st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat, GLenum format, GLenum type, GLboolean renderable) @@ -1206,20 +1297,19 @@ st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat, * that in advance. Specify potential render target flags now. */ bindings = PIPE_BIND_SAMPLER_VIEW; - if (renderable == GL_TRUE) { - if (_mesa_is_depth_format(internalFormat) || - _mesa_is_depth_or_stencil_format(internalFormat)) + if (renderable) { + if (_mesa_is_depth_or_stencil_format(internalFormat)) bindings |= PIPE_BIND_DEPTH_STENCIL; - else + else bindings |= PIPE_BIND_RENDER_TARGET; } - pFormat = st_choose_format(screen, internalFormat, + pFormat = st_choose_format(screen, internalFormat, format, type, PIPE_TEXTURE_2D, 0, bindings); if (pFormat == PIPE_FORMAT_NONE) { /* try choosing format again, this time without render target bindings */ - pFormat = st_choose_format(screen, internalFormat, + pFormat = st_choose_format(screen, internalFormat, format, type, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); } @@ -1231,6 +1321,10 @@ st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat, return st_pipe_format_to_mesa_format(pFormat); } + +/** + * Called via ctx->Driver.ChooseTextureFormat(). + */ gl_format st_ChooseTextureFormat(struct gl_context *ctx, GLint internalFormat, GLenum format, GLenum type) diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index 0fb570f6ee4..1c1f5965f66 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -52,8 +52,9 @@ st_pipe_format_to_mesa_format(enum pipe_format pipeFormat); extern enum pipe_format st_choose_format(struct pipe_screen *screen, GLenum internalFormat, + GLenum format, GLenum type, enum pipe_texture_target target, unsigned sample_count, - unsigned tex_usage); + unsigned bindings); extern enum pipe_format st_choose_renderbuffer_format(struct pipe_screen *screen, diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c index a68544ddac7..a8c4b5c3f49 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -139,23 +139,64 @@ buffer_index_to_attachment(gl_buffer_index index) } /** + * Make sure a context picks up the latest cached state of the + * drawables it binds to. + */ +static void +st_context_validate(struct st_context *st, + struct st_framebuffer *stdraw, + struct st_framebuffer *stread) +{ + if (stdraw && stdraw->stamp != st->draw_stamp) { + st->dirty.st |= ST_NEW_FRAMEBUFFER; + _mesa_resize_framebuffer(st->ctx, &stdraw->Base, + stdraw->Base.Width, + stdraw->Base.Height); + st->draw_stamp = stdraw->stamp; + } + + if (stread && stread->stamp != st->read_stamp) { + if (stread != stdraw) { + st->dirty.st |= ST_NEW_FRAMEBUFFER; + _mesa_resize_framebuffer(st->ctx, &stread->Base, + stread->Base.Width, + stread->Base.Height); + } + st->read_stamp = stread->stamp; + } +} + +/** * Validate a framebuffer to make sure up-to-date pipe_textures are used. + * The context we need to pass in is s dummy context needed only to be + * able to get a pipe context to create pipe surfaces, and to have a + * context to call _mesa_resize_framebuffer(): + * (That should probably be rethought, since those surfaces become + * drawable state, not context state, and can be freed by another pipe + * context). */ static void -st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st) +st_framebuffer_validate(struct st_framebuffer *stfb, + struct st_context *st) { - struct pipe_context *pipe = st->pipe; struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; uint width, height; unsigned i; boolean changed = FALSE; + int32_t new_stamp = p_atomic_read(&stfb->iface->stamp); - if (!p_atomic_read(&stfb->revalidate)) + if (stfb->iface_stamp == new_stamp) return; /* validate the fb */ - if (!stfb->iface->validate(stfb->iface, stfb->statts, stfb->num_statts, textures)) - return; + do { + if (!stfb->iface->validate(stfb->iface, stfb->statts, + stfb->num_statts, textures)) + return; + + stfb->iface_stamp = new_stamp; + new_stamp = p_atomic_read(&stfb->iface->stamp); + } while(stfb->iface_stamp != new_stamp); width = stfb->Base.Width; height = stfb->Base.Height; @@ -184,7 +225,7 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st) memset(&surf_tmpl, 0, sizeof(surf_tmpl)); u_surface_default_template(&surf_tmpl, textures[i], PIPE_BIND_RENDER_TARGET); - ps = pipe->create_surface(pipe, textures[i], &surf_tmpl); + ps = st->pipe->create_surface(st->pipe, textures[i], &surf_tmpl); if (ps) { pipe_surface_reference(&strb->surface, ps); pipe_resource_reference(&strb->texture, ps->texture); @@ -204,14 +245,9 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st) } if (changed) { - st->dirty.st |= ST_NEW_FRAMEBUFFER; + ++stfb->stamp; _mesa_resize_framebuffer(st->ctx, &stfb->Base, width, height); - - assert(stfb->Base.Width == width); - assert(stfb->Base.Height == height); } - - p_atomic_set(&stfb->revalidate, FALSE); } /** @@ -236,8 +272,7 @@ st_framebuffer_update_attachments(struct st_framebuffer *stfb) st_visual_have_buffers(stfb->iface->visual, 1 << statt)) stfb->statts[stfb->num_statts++] = statt; } - - p_atomic_set(&stfb->revalidate, TRUE); + stfb->stamp++; } /** @@ -443,6 +478,7 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi) &stfb->Base._ColorReadBufferIndex); stfb->iface = stfbi; + stfb->iface_stamp = p_atomic_read(&stfbi->stamp) - 1; /* add the color buffer */ idx = stfb->Base._ColorDrawBufferIndexes[0]; @@ -454,6 +490,7 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi) st_framebuffer_add_renderbuffer(stfb, BUFFER_DEPTH); st_framebuffer_add_renderbuffer(stfb, BUFFER_ACCUM); + stfb->stamp = 0; st_framebuffer_update_attachments(stfb); stfb->Base.Initialized = GL_TRUE; @@ -473,31 +510,6 @@ st_framebuffer_reference(struct st_framebuffer **ptr, } static void -st_context_notify_invalid_framebuffer(struct st_context_iface *stctxi, - struct st_framebuffer_iface *stfbi) -{ - struct st_context *st = (struct st_context *) stctxi; - struct st_framebuffer *stfb; - - /* either draw or read winsys fb */ - stfb = st_ws_framebuffer(st->ctx->WinSysDrawBuffer); - if (!stfb || stfb->iface != stfbi) - stfb = st_ws_framebuffer(st->ctx->WinSysReadBuffer); - - if (stfb && stfb->iface == stfbi) { - p_atomic_set(&stfb->revalidate, TRUE); - } - else { - /* This function is probably getting called when we've detected a - * change in a window's size but the currently bound context is - * not bound to that window. - * If the st_framebuffer_iface structure had a pointer to the - * corresponding st_framebuffer we'd be able to handle this. - */ - } -} - -static void st_context_flush(struct st_context_iface *stctxi, unsigned flags, struct pipe_fence_handle **fence) { @@ -696,8 +708,6 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, smapi->get_param(smapi, ST_MANAGER_BROKEN_INVALIDATE); st->iface.destroy = st_context_destroy; - st->iface.notify_invalid_framebuffer = - st_context_notify_invalid_framebuffer; st->iface.flush = st_context_flush; st->iface.teximage = st_context_teximage; st->iface.copy = st_context_copy; @@ -707,38 +717,58 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, return &st->iface; } +static struct st_context_iface * +st_api_get_current(struct st_api *stapi) +{ + GET_CURRENT_CONTEXT(ctx); + struct st_context *st = (ctx) ? ctx->st : NULL; + + return (st) ? &st->iface : NULL; +} + +static struct st_framebuffer * +st_framebuffer_reuse_or_create(struct gl_framebuffer *fb, + struct st_framebuffer_iface *stfbi) +{ + struct st_framebuffer *cur = st_ws_framebuffer(fb), *stfb = NULL; + + if (cur && cur->iface == stfbi) { + /* reuse the current stfb */ + st_framebuffer_reference(&stfb, cur); + } + else { + /* create a new one */ + stfb = st_framebuffer_create(stfbi); + } + + return stfb; +} + static boolean st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, struct st_framebuffer_iface *stdrawi, struct st_framebuffer_iface *streadi) { struct st_context *st = (struct st_context *) stctxi; - struct st_framebuffer *stdraw, *stread, *stfb; + struct st_framebuffer *stdraw, *stread; boolean ret; _glapi_check_multithread(); if (st) { - /* reuse/create the draw fb */ - stfb = st_ws_framebuffer(st->ctx->WinSysDrawBuffer); - if (stfb && stfb->iface == stdrawi) { - stdraw = NULL; - st_framebuffer_reference(&stdraw, stfb); + /* reuse or create the draw fb */ + stdraw = st_framebuffer_reuse_or_create(st->ctx->WinSysDrawBuffer, + stdrawi); + if (streadi != stdrawi) { + /* do the same for the read fb */ + stread = st_framebuffer_reuse_or_create(st->ctx->WinSysReadBuffer, + streadi); } else { - stdraw = st_framebuffer_create(stdrawi); - } - - /* reuse/create the read fb */ - stfb = st_ws_framebuffer(st->ctx->WinSysReadBuffer); - if (!stfb || stfb->iface != streadi) - stfb = stdraw; - if (stfb && stfb->iface == streadi) { stread = NULL; - st_framebuffer_reference(&stread, stfb); - } - else { - stread = st_framebuffer_create(streadi); + /* reuse the draw fb for the read fb */ + if (stdraw) + st_framebuffer_reference(&stread, stdraw); } if (stdraw && stread) { @@ -757,6 +787,10 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, } ret = _mesa_make_current(st->ctx, &stdraw->Base, &stread->Base); + + st->draw_stamp = stdraw->stamp - 1; + st->read_stamp = stread->stamp - 1; + st_context_validate(st, stdraw, stread); } else { struct gl_framebuffer *incomplete = _mesa_get_incomplete_framebuffer(); @@ -773,15 +807,6 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, return ret; } -static struct st_context_iface * -st_api_get_current(struct st_api *stapi) -{ - GET_CURRENT_CONTEXT(ctx); - struct st_context *st = (ctx) ? ctx->st : NULL; - - return (st) ? &st->iface : NULL; -} - static st_proc_t st_api_get_proc_address(struct st_api *stapi, const char *procname) { @@ -857,6 +882,8 @@ st_manager_validate_framebuffers(struct st_context *st) st_framebuffer_validate(stdraw, st); if (stread && stread != stdraw) st_framebuffer_validate(stread, st); + + st_context_validate(st, stdraw, stread); } /** diff --git a/src/mesa/main/texrender.c b/src/mesa/swrast/s_texrender.c index a7641a5f9a4..52d03c92ac7 100644 --- a/src/mesa/main/texrender.c +++ b/src/mesa/swrast/s_texrender.c @@ -1,12 +1,12 @@ -#include "context.h" -#include "colormac.h" -#include "fbobject.h" -#include "macros.h" -#include "texfetch.h" -#include "teximage.h" -#include "texrender.h" -#include "renderbuffer.h" +#include "main/context.h" +#include "main/colormac.h" +#include "main/fbobject.h" +#include "main/macros.h" +#include "main/texfetch.h" +#include "main/teximage.h" +#include "main/renderbuffer.h" +#include "swrast/swrast.h" /* @@ -628,9 +628,9 @@ update_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att) * \sa _mesa_framebuffer_renderbuffer */ void -_mesa_render_texture(struct gl_context *ctx, - struct gl_framebuffer *fb, - struct gl_renderbuffer_attachment *att) +_swrast_render_texture(struct gl_context *ctx, + struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) { (void) fb; @@ -642,8 +642,8 @@ _mesa_render_texture(struct gl_context *ctx, void -_mesa_finish_render_texture(struct gl_context *ctx, - struct gl_renderbuffer_attachment *att) +_swrast_finish_render_texture(struct gl_context *ctx, + struct gl_renderbuffer_attachment *att) { /* do nothing */ /* The renderbuffer texture wrapper will get deleted by the diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index 9b88c70220e..27b74c32486 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -206,6 +206,16 @@ extern void _swrast_eject_texture_images(struct gl_context *ctx); +extern void +_swrast_render_texture(struct gl_context *ctx, + struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att); + +extern void +_swrast_finish_render_texture(struct gl_context *ctx, + struct gl_renderbuffer_attachment *att); + + /** * The driver interface for the software rasterizer. diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 5e9b2798c43..7959337decb 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -337,7 +337,8 @@ print_draw_arrays(struct gl_context *ctx, mode, start, count); for (i = 0; i < 32; i++) { - GLuint bufName = exec->array.inputs[i]->BufferObj->Name; + struct gl_buffer_object *bufObj = exec->array.inputs[i]->BufferObj; + GLuint bufName = bufObj->Name; GLint stride = exec->array.inputs[i]->Stride; printf("attr %2d: size %d stride %d enabled %d " "ptr %p Bufobj %u\n", @@ -350,9 +351,8 @@ print_draw_arrays(struct gl_context *ctx, bufName); if (bufName) { - struct gl_buffer_object *buf = _mesa_lookup_bufferobj(ctx, bufName); GLubyte *p = ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER_ARB, - GL_READ_ONLY_ARB, buf); + GL_READ_ONLY_ARB, bufObj); int offset = (int) (GLintptr) exec->array.inputs[i]->Ptr; float *f = (float *) (p + offset); int *k = (int *) f; @@ -364,7 +364,7 @@ print_draw_arrays(struct gl_context *ctx, for (i = 0; i < n; i++) { printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]); } - ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, buf); + ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, bufObj); } } } diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c index 9068ae240a6..1de290ff602 100644 --- a/src/mesa/vbo/vbo_rebase.c +++ b/src/mesa/vbo/vbo_rebase.c @@ -78,8 +78,7 @@ GLboolean vbo_all_varyings_in_vbos( const struct gl_client_array *arrays[] ) GLuint i; for (i = 0; i < VERT_ATTRIB_MAX; i++) - if (arrays[i]->StrideB && - arrays[i]->BufferObj->Name == 0) + if (arrays[i]->BufferObj->Name == 0) return GL_FALSE; return GL_TRUE; @@ -90,8 +89,7 @@ GLboolean vbo_any_varyings_in_vbos( const struct gl_client_array *arrays[] ) GLuint i; for (i = 0; i < VERT_ATTRIB_MAX; i++) - if (arrays[i]->StrideB && - arrays[i]->BufferObj->Name != 0) + if (arrays[i]->BufferObj->Name != 0) return GL_TRUE; return GL_FALSE; |