From d95b2ad7bc95e4ba2f1af9737935878f1ff7d79a Mon Sep 17 00:00:00 2001 From: marha Date: Wed, 10 Apr 2013 22:50:07 +0200 Subject: Added xrdb app from git sources --- apps/xrdb/.gitignore | 79 +++ apps/xrdb/AUTHORS | 3 + apps/xrdb/COPYING | 51 ++ apps/xrdb/Makefile.am | 43 ++ apps/xrdb/README | 25 + apps/xrdb/autogen.sh | 13 + apps/xrdb/configure.ac | 91 +++ apps/xrdb/man/Makefile.am | 12 + apps/xrdb/man/xrdb.man | 302 ++++++++++ apps/xrdb/xrdb.c | 1408 +++++++++++++++++++++++++++++++++++++++++++++ packages.txt | 1 + 11 files changed, 2028 insertions(+) create mode 100644 apps/xrdb/.gitignore create mode 100644 apps/xrdb/AUTHORS create mode 100644 apps/xrdb/COPYING create mode 100644 apps/xrdb/Makefile.am create mode 100644 apps/xrdb/README create mode 100755 apps/xrdb/autogen.sh create mode 100644 apps/xrdb/configure.ac create mode 100644 apps/xrdb/man/Makefile.am create mode 100644 apps/xrdb/man/xrdb.man create mode 100644 apps/xrdb/xrdb.c diff --git a/apps/xrdb/.gitignore b/apps/xrdb/.gitignore new file mode 100644 index 000000000..0d6e60997 --- /dev/null +++ b/apps/xrdb/.gitignore @@ -0,0 +1,79 @@ +# +# X.Org module default exclusion patterns +# The next section if for module specific patterns +# +# Do not edit the following section +# GNU Build System (Autotools) +aclocal.m4 +autom4te.cache/ +autoscan.log +ChangeLog +compile +config.guess +config.h +config.h.in +config.log +config-ml.in +config.py +config.status +config.status.lineno +config.sub +configure +configure.scan +depcomp +.deps/ +INSTALL +install-sh +.libs/ +libtool +libtool.m4 +ltmain.sh +lt~obsolete.m4 +ltoptions.m4 +ltsugar.m4 +ltversion.m4 +Makefile +Makefile.in +mdate-sh +missing +mkinstalldirs +*.pc +py-compile +stamp-h? +symlink-tree +texinfo.tex +ylwrap + +# Do not edit the following section +# Edit Compile Debug Document Distribute +*~ +*.[0-9] +*.[0-9]x +*.bak +*.bin +core +*.dll +*.exe +*-ISO*.bdf +*-JIS*.bdf +*-KOI8*.bdf +*.kld +*.ko +*.ko.cmd +*.lai +*.l[oa] +*.[oa] +*.obj +*.patch +*.so +*.pcf.gz +*.pdb +*.tar.bz2 +*.tar.gz +# +# Add & Override patterns for xrdb +# +# Edit the following section as needed +# For example, !report.pc overrides *.pc. See 'man gitignore' +# +xrdb diff --git a/apps/xrdb/AUTHORS b/apps/xrdb/AUTHORS new file mode 100644 index 000000000..09c906f4f --- /dev/null +++ b/apps/xrdb/AUTHORS @@ -0,0 +1,3 @@ + * Original Author: Jim Gettys, August 28, 1987 + * Extensively Modified: Phil Karlton, January 5, 1987 + * Modified a Bunch More: Bob Scheifler, February, 1991 diff --git a/apps/xrdb/COPYING b/apps/xrdb/COPYING new file mode 100644 index 000000000..9783f04f7 --- /dev/null +++ b/apps/xrdb/COPYING @@ -0,0 +1,51 @@ + + COPYRIGHT 1987, 1991 + DIGITAL EQUIPMENT CORPORATION + MAYNARD, MASSACHUSETTS + MASSACHUSETTS INSTITUTE OF TECHNOLOGY + CAMBRIDGE, MASSACHUSETTS + ALL RIGHTS RESERVED. + +THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND +SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. +DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR +ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. + +IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS, +APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT +SET FORTH ABOVE. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided +that the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the name of Digital Equipment Corporation not be +used in advertising or publicity pertaining to distribution of the software +without specific, written prior permission. + + ---------------------------------------------------------------- + +Copyright 1991, Digital Equipment Corporation. +Copyright 1991, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +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 OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. diff --git a/apps/xrdb/Makefile.am b/apps/xrdb/Makefile.am new file mode 100644 index 000000000..251261b3f --- /dev/null +++ b/apps/xrdb/Makefile.am @@ -0,0 +1,43 @@ +# +# Copyright 2005 Red Hat, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of Red Hat not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +SUBDIRS = man +bin_PROGRAMS = xrdb + +AM_CFLAGS = $(CWARNFLAGS) $(XRDB_CFLAGS) +xrdb_LDADD = $(XRDB_LIBS) + +xrdb_SOURCES = \ + xrdb.c + +MAINTAINERCLEANFILES = ChangeLog INSTALL + +.PHONY: ChangeLog INSTALL + +INSTALL: + $(INSTALL_CMD) + +ChangeLog: + $(CHANGELOG_CMD) + +dist-hook: ChangeLog INSTALL + + diff --git a/apps/xrdb/README b/apps/xrdb/README new file mode 100644 index 000000000..48a9ed864 --- /dev/null +++ b/apps/xrdb/README @@ -0,0 +1,25 @@ +xrdb - X server resource database utility + +All questions regarding this software should be directed at the +Xorg mailing list: + + http://lists.freedesktop.org/mailman/listinfo/xorg + +Please submit bug reports to the Xorg bugzilla: + + https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +The master development code repository can be found at: + + git://anongit.freedesktop.org/git/xorg/app/xrdb + + http://cgit.freedesktop.org/xorg/app/xrdb + +For patch submission instructions, see: + + http://www.x.org/wiki/Development/Documentation/SubmittingPatches + +For more information on the git code manager, see: + + http://wiki.x.org/wiki/GitPage + diff --git a/apps/xrdb/autogen.sh b/apps/xrdb/autogen.sh new file mode 100755 index 000000000..e81f98910 --- /dev/null +++ b/apps/xrdb/autogen.sh @@ -0,0 +1,13 @@ +#! /bin/sh + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +ORIGDIR=`pwd` +cd $srcdir + +autoreconf -v --install || exit 1 +cd $ORIGDIR || exit $? + +$srcdir/configure --enable-maintainer-mode "$@" + diff --git a/apps/xrdb/configure.ac b/apps/xrdb/configure.ac new file mode 100644 index 000000000..04aa03400 --- /dev/null +++ b/apps/xrdb/configure.ac @@ -0,0 +1,91 @@ +dnl Copyright 2005 Red Hat, Inc. +dnl +dnl Permission to use, copy, modify, distribute, and sell this software and its +dnl documentation for any purpose is hereby granted without fee, provided that +dnl the above copyright notice appear in all copies and that both that +dnl copyright notice and this permission notice appear in supporting +dnl documentation, and that the name of Red Hat not be used in +dnl advertising or publicity pertaining to distribution of the software without +dnl specific, written prior permission. Red Hat makes no +dnl representations about the suitability of this software for any purpose. It +dnl is provided "as is" without express or implied warranty. +dnl +dnl RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +dnl INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +dnl EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR +dnl CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +dnl DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +dnl TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +dnl PERFORMANCE OF THIS SOFTWARE. +dnl +dnl Process this file with autoconf to create configure. + +# Initialize Autoconf +AC_PREREQ([2.60]) +AC_INIT([xrdb], [1.0.9], + [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xrdb]) +AC_CONFIG_SRCDIR([Makefile.am]) +AC_CONFIG_HEADERS([config.h]) +AC_USE_SYSTEM_EXTENSIONS + +# Initialize Automake +AM_INIT_AUTOMAKE([foreign dist-bzip2]) +AM_MAINTAINER_MODE + +# Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS +m4_ifndef([XORG_MACROS_VERSION], + [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])]) +XORG_MACROS_VERSION(1.8) +XORG_DEFAULT_OPTIONS + +AC_CHECK_FUNCS([mkstemp asprintf]) + +# Find MAXHOSTNAMELEN definition +# Common hidey holes: +# BSD & Linux - +# Solaris - + +AC_CHECK_DECL([MAXHOSTNAMELEN],[FOUND_MAXHOSTNAMELEN=yes]) + +if test x$FOUND_MAXHOSTNAMELEN != xyes ; then + AC_MSG_CHECKING([for header that defines MAXHOSTNAMELEN]) + + FOUND_MAXHOSTNAMELEN='not found' + + AC_COMPILE_IFELSE( + AC_LANG_PROGRAM([#include ], + [int h = MAXHOSTNAMELEN;]), + [FOUND_MAXHOSTNAMELEN='sys/param.h' + AC_DEFINE(NEED_SYS_PARAM_H,1, + [Define to 1 if you need to define MAXHOSTNAMELEN])]) + + AC_COMPILE_IFELSE( + AC_LANG_PROGRAM([#include ], + [int h = MAXHOSTNAMELEN;]), + [FOUND_MAXHOSTNAMELEN='netdb.h' + AC_DEFINE(NEED_NETDB_H,1, + [Define to 1 if you need to define MAXHOSTNAMELEN])]) + + AC_MSG_RESULT([$FOUND_MAXHOSTNAMELEN]) +fi + +# xrdb needs to know where to find cpp at runtime - previously set as CppCmd +# in Imake config files for each OS +AC_ARG_WITH([cpp], + AS_HELP_STRING([--with-cpp=path], + [comma-separated list of paths to cpp command for xrdb to use at runtime]), + [AC_MSG_CHECKING(for cpp) + CPP_PATH=$withval + AC_MSG_RESULT(--with-cpp specified $CPP_PATH)], + [AC_PATH_PROG([CPP_PATH],[cpp], [cpp], + [$PATH:/bin:/usr/bin:/usr/lib:/usr/libexec:/usr/ccs/lib:/usr/ccs/lbin:/lib])]) +CPP_PATH=`echo ${CPP_PATH} | sed 's/,/\\",\\"/g'` +AC_DEFINE_UNQUOTED([CPP], "$CPP_PATH", [Path to CPP program]) + +# Checks for pkg-config packages +PKG_CHECK_MODULES(XRDB, xmuu x11) + +AC_CONFIG_FILES([ + Makefile + man/Makefile]) +AC_OUTPUT diff --git a/apps/xrdb/man/Makefile.am b/apps/xrdb/man/Makefile.am new file mode 100644 index 000000000..95a4ed588 --- /dev/null +++ b/apps/xrdb/man/Makefile.am @@ -0,0 +1,12 @@ + +appmandir = $(APP_MAN_DIR) +appman_PRE = xrdb.man +appman_DATA = $(appman_PRE:man=$(APP_MAN_SUFFIX)) + +EXTRA_DIST = $(appman_PRE) +CLEANFILES = $(appman_DATA) +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure +.man.$(APP_MAN_SUFFIX): + $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ diff --git a/apps/xrdb/man/xrdb.man b/apps/xrdb/man/xrdb.man new file mode 100644 index 000000000..e30b0d553 --- /dev/null +++ b/apps/xrdb/man/xrdb.man @@ -0,0 +1,302 @@ +.\" Copyright 1991, Digital Equipment Corporation. +.\" Copyright 1991, 1994, 1998 The Open Group +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and its +.\" documentation for any purpose is hereby granted without fee, provided that +.\" the above copyright notice appear in all copies and that both that +.\" copyright notice and this permission notice appear in supporting +.\" documentation. +.\" +.\" 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 OPEN GROUP 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. +.\" +.\" Except as contained in this notice, the name of The Open Group shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from The Open Group. +.\" +.TH XRDB 1 __xorgversion__ +.SH NAME +xrdb - X server resource database utility +.SH SYNOPSIS +.B xrdb +[-option ...] [\fIfilename\fP] +.SH DESCRIPTION +.I Xrdb +is used to get or set the contents of the RESOURCE_MANAGER property +on the root window of screen 0, or the SCREEN_RESOURCES property on +the root window of any or all screens, or everything combined. +You would normally run this program from your X startup file. +.LP +Most X clients use the RESOURCE_MANAGER and SCREEN_RESOURCES properties to +get user preferences about +color, fonts, and so on for applications. Having this information in +the server (where it is available to all clients) instead of on disk, +solves the problem in previous versions of X that required you to +maintain \fIdefaults\fP files on every machine that you might use. +It also allows for dynamic changing of defaults without editing files. +.LP +The RESOURCE_MANAGER property is used for resources that apply to all +screens of the display. The SCREEN_RESOURCES property on each screen +specifies additional (or overriding) resources to be used for that screen. +(When there is only one screen, SCREEN_RESOURCES is normally not used, +all resources are just placed in the RESOURCE_MANAGER property.) +.LP +The file specified by +.I filename +(or the contents from standard input if - or no filename is given) +is optionally passed through the C preprocessor with the +following symbols defined, based on the capabilities of the server +being used: +.TP 8 +.B SERVERHOST=\fIhostname\fP +the hostname portion of the display to which you are connected. +.TP 8 +.B SRVR_\fIname\fB +the SERVERHOST hostname string turned into a legal identifier. +For example, "my-dpy.lcs.mit.edu" becomes SRVR_my_dpy_lcs_mit_edu. +.TP 8 +.B HOST=\fIhostname\fP +the same as +.BR SERVERHOST . +.TP 8 +.B DISPLAY_NUM=\fInum\fP +the number of the display on the server host. +.TP 8 +.B CLIENTHOST=\fIhostname\fP +the name of the host on which +.I xrdb +is running. +.TP 8 +.B CLNT_\fIname\fB +the CLIENTHOST hostname string turned into a legal identifier. +For example, "expo.lcs.mit.edu" becomes CLNT_expo_lcs_mit_edu. +.TP 8 +.B RELEASE=\fInum\fP +the vendor release number for the server. The interpretation of this +number will vary depending on VENDOR. +.TP 8 +.B REVISION=\fInum\fP +the X protocol minor version supported by this server (currently 0). +.TP 8 +.B VERSION=\fInum\fP +the X protocol major version supported by this server (should always be 11). +.TP 8 +.B VENDOR="\fIvendor\fP" +a string literal specifying the vendor of the server. +.TP 8 +.B VNDR_\fIname\fP +the VENDOR name string turned into a legal identifier. +For example, "MIT X Consortium" becomes VNDR_MIT_X_Consortium. +.TP 8 +.B EXT_\fIname\fP +A symbol is defined for each protocol extension supported by the server. +Each extension string name is turned into a legal identifier. +For example, "X3D-PEX" becomes EXT_X3D_PEX. +.TP 8 +.B NUM_SCREENS=\fInum\fP +the total number of screens. +.TP 8 +.B SCREEN_NUM=\fInum\fP +the number of the current screen (from zero). +.TP 8 +.B BITS_PER_RGB=\fInum\fP +the number of significant bits in an RGB color specification. This is the +log base 2 of the number of distinct shades of each primary that the hardware +can generate. Note that it usually is not related to PLANES. +.TP 8 +.B CLASS=\fIvisualclass\fP +one of StaticGray, GrayScale, StaticColor, PseudoColor, TrueColor, +DirectColor. This is the visual class of the root window. +.TP 8 +.B CLASS_\fIvisualclass\fP=\fIvisualid\fP +the visual class of the root window in a form you can \fI#ifdef\fP on. +The value is the numeric id of the visual. +.TP 8 +.B COLOR +defined only if CLASS is one of StaticColor, PseudoColor, TrueColor, or +DirectColor. +.TP 8 +.B CLASS_\fIvisualclass\fP_\fIdepth\fP=\fInum\fP +A symbol is defined for each visual supported for the screen. +The symbol includes the class of the visual and its depth; +the value is the numeric id of the visual. +(If more than one visual has the same class and depth, the numeric id +of the first one reported by the server is used.) +.TP 8 +.B HEIGHT=\fInum\fP +the height of the root window in pixels. +.TP 8 +.B WIDTH=\fInum\fP +the width of the root window in pixels. +.TP 8 +.B PLANES=\fInum\fP +the number of bit planes (the depth) of the root window. +.TP 8 +.B X_RESOLUTION=\fInum\fP +the x resolution of the screen in pixels per meter. +.TP 8 +.B Y_RESOLUTION=\fInum\fP +the y resolution of the screen in pixels per meter. +.LP +SRVR_\fIname\fP, CLNT_\fIname\fP, VNDR_\fIname\fP, and EXT_\fIname\fP +identifiers are formed by changing all characters other than letters +and digits into underscores (_). +.LP +Lines that begin with an exclamation mark (!) are ignored and may +be used as comments. +.LP +Note that since +.I xrdb +can read from standard input, it can be used to +the change the contents of properties directly from +a terminal or from a shell script. +.SH "OPTIONS" +.PP +.I xrdb +program accepts the following options: +.TP 8 +.B \-help +This option (or any unsupported option) will cause a brief description of +the allowable options and parameters to be printed. +.TP 8 +.B \-display \fIdisplay\fP +This option specifies the X server to be used; see \fIX(__miscmansuffix__)\fP. +It also specifies the screen to use for the \fI-screen\fP option, +and it specifies the screen from which preprocessor symbols are +derived for the \fI-global\fP option. +.TP 8 +.B \-all +This option indicates that operation should be performed on the +screen-independent resource property (RESOURCE_MANAGER), as well as +the screen-specific property (SCREEN_RESOURCES) on every screen of the +display. For example, when used in conjunction with \fI-query\fP, +the contents of all properties are output. For \fI-load\fP, \fI-override\fP +and \fI-merge\fP, +the input file is processed once for each screen. The resources which occur +in common in the output for every screen are collected, and these are applied +as the screen-independent resources. The remaining resources are applied +for each individual per-screen property. This the default mode of operation. +.TP 8 +.B \-global +This option indicates that the operation should only be performed on +the screen-independent RESOURCE_MANAGER property. +.TP 8 +.B \-screen +This option indicates that the operation should only be performed on +the SCREEN_RESOURCES property of the default screen of the display. +.TP 8 +.B \-screens +This option indicates that the operation should be performed on +the SCREEN_RESOURCES property of each screen of the display. +For \fI-load\fP, \fI-override\fP and \fI-merge\fP, the input file is +processed for each screen. +.TP 8 +.B \-n +This option indicates that changes to the specified properties (when used with +\fI-load\fP, \fI-override\fP or \fI-merge\fP) +or to the resource file (when used with \fI-edit\fP) should be shown on the +standard output, but should not be performed. +.TP 8 +.B \-quiet +This option indicates that warning about duplicate entries should not be +displayed. +.TP 8 +.B -cpp \fIfilename\fP +This option specifies the pathname of the C preprocessor program to be used. +Although +.I xrdb +was designed to use CPP, any program that acts as a filter +and accepts the -D, -I, and -U options may be used. +.TP 8 +.B -nocpp +This option indicates that +.I xrdb +should not run the input file through a preprocessor before loading it +into properties. +.TP 8 +.B \-symbols +This option indicates that the symbols that are defined for the preprocessor +should be printed onto the standard output. +.TP 8 +.B \-query +This option indicates that the current contents of the specified +properties should be printed onto the standard output. Note that since +preprocessor commands in the input resource file are part of the input +file, not part of the property, they won't appear in the output from this +option. The +.B \-edit +option can be used to merge the contents of properties back into the input +resource file without damaging preprocessor commands. +.TP 8 +.B \-load +This option indicates that the input should be loaded as the new value +of the specified properties, replacing whatever was there (i.e. +the old contents are removed). This is the default action. +.TP 8 +.B \-override +This option indicates that the input should be added to, instead of +replacing, the current contents of the specified properties. +New entries override previous entries. +.TP 8 +.B \-merge +This option indicates that the input should be merged and lexicographically +sorted with, instead of replacing, the current contents of the specified +properties. +.TP 8 +.B \-remove +This option indicates that the specified properties should be removed +from the server. +.TP 8 +.B \-retain +This option indicates that the server should be instructed not to reset if +\fIxrdb\fP is the first client. This should never be necessary under normal +conditions, since \fIxdm\fP and \fIxinit\fP always act as the first client. +.TP 8 +.B \-edit \fIfilename\fP +This option indicates that the contents of the specified properties +should be edited into the given file, replacing any values already listed +there. This allows you to put changes that you have made to your defaults +back into your resource file, preserving any comments or preprocessor lines. +.TP 8 +.B \-backup \fIstring\fP +This option specifies a suffix to be appended to the filename used with +.B \-edit +to generate a backup file. +.TP 8 +.B \-D\fIname[=value]\fP +This option is passed through to the preprocessor and is used to define +symbols for use with conditionals such as +.I #ifdef. +.TP 8 +.B \-U\fIname\fP +This option is passed through to the preprocessor and is used to remove +any definitions of this symbol. +.TP 8 +.B \-I\fIdirectory\fP +This option is passed through to the preprocessor and is used to specify +a directory to search for files that are referenced with +.I #include. +.SH FILES +Generalizes \fI~/.Xdefaults\fP files. +.SH "SEE ALSO" +X(__miscmansuffix__), appres(__appmansuffix__), listres(__appmansuffix__), +Xlib Resource Manager documentation, Xt resource documentation +.SH ENVIRONMENT +.TP 8 +.B DISPLAY +to figure out which display to use. +.SH BUGS +.PP +The default for no arguments should be to query, not to overwrite, so that +it is consistent with other programs. +.SH AUTHORS +Bob Scheifler, Phil Karlton, rewritten from the original by Jim Gettys diff --git a/apps/xrdb/xrdb.c b/apps/xrdb/xrdb.c new file mode 100644 index 000000000..b7c9fa3aa --- /dev/null +++ b/apps/xrdb/xrdb.c @@ -0,0 +1,1408 @@ +/* + * xrdb - X resource manager database utility + * + */ + +/* + * COPYRIGHT 1987, 1991 + * DIGITAL EQUIPMENT CORPORATION + * MAYNARD, MASSACHUSETTS + * MASSACHUSETTS INSTITUTE OF TECHNOLOGY + * CAMBRIDGE, MASSACHUSETTS + * ALL RIGHTS RESERVED. + * + * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND + * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. + * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR + * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. + * + * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS, + * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT + * SET FORTH ABOVE. + * + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Digital Equipment Corporation not be + * used in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + */ + +/* + * this program is used to load, or dump the resource manager database + * in the server. + * + * Original Author: Jim Gettys, August 28, 1987 + * Extensively Modified: Phil Karlton, January 5, 1987 + * Modified a Bunch More: Bob Scheifler, February, 1991 + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef NEED_SYS_PARAM_H +# include /* defines MAXHOSTNAMELEN on BSD & Linux */ +#endif + +#ifdef NEED_NETDB_H +# include /* defines MAXHOSTNAMELEN on Solaris */ +#endif + +#define SCREEN_RESOURCES "SCREEN_RESOURCES" + +#ifndef CPP +#ifdef __UNIXOS2__ +/* expected to be in path */ +#define CPP "cpp" +#else +#define CPP "/usr/lib/cpp" +#endif /* __UNIXOS2__ */ +#endif /* CPP */ + +#define INIT_BUFFER_SIZE 10000 +#define INIT_ENTRY_SIZE 500 + +#define RALL 0 +#define RGLOBAL 1 +#define RSCREEN 2 +#define RSCREENS 3 + +#define OPSYMBOLS 0 +#define OPQUERY 1 +#define OPREMOVE 2 +#define OPEDIT 3 +#define OPLOAD 4 +#define OPMERGE 5 +#define OPOVERRIDE 6 + +#define RESOURCE_PROPERTY_NAME "RESOURCE_MANAGER" +#define BACKUP_SUFFIX ".bak" /* for editting */ + +typedef struct _Entry { + char *tag, *value; + int lineno; + Bool usable; +} Entry; +typedef struct _Buffer { + char *buff; + int room, used; +} Buffer; +typedef struct _Entries { + Entry *entry; + int room, used; +} Entries; + +/* dynamically allocated strings */ +#define CHUNK_SIZE 4096 +typedef struct _String { + char *val; + int room, used; +} String; + +static char *ProgramName; +static Bool quiet = False; +static char tmpname[32]; +static char *filename = NULL; +#ifdef PATHETICCPP +static Bool need_real_defines = False; +static char tmpname2[32]; +#endif +#ifdef WIN32 +static char tmpname3[32]; +#endif +static int oper = OPLOAD; +static char *editFile = NULL; +static const char *cpp_program = NULL; +static const char* const cpp_locations[] = { CPP }; +static char *backup_suffix = BACKUP_SUFFIX; +static Bool dont_execute = False; +static String defines; +static int defines_base; +#define MAX_CMD_DEFINES 512 +static char *cmd_defines[MAX_CMD_DEFINES]; +static int num_cmd_defines = 0; +static String includes; +static Display *dpy; +static Buffer buffer; +static Entries newDB; + +static void fatal(char *, ...); +static void addstring ( String *arg, const char *s ); +static void addescapedstring ( String *arg, const char *s ); +static void addtokstring ( String *arg, const char *s ); +static void FormatEntries ( Buffer *buffer, Entries *entries ); +static void StoreProperty ( Display *dpy, Window root, Atom res_prop ); +static void Process ( int scrno, Bool doScreen, Bool execute ); +static void ShuffleEntries ( Entries *db, Entries *dbs, int num ); +static void ReProcess ( int scrno, Bool doScreen ); + +#ifndef HAVE_ASPRINTF +/* sprintf variant found in newer libc's which allocates string to print to */ +static int _X_ATTRIBUTE_PRINTF(2,3) +asprintf(char ** ret, const char *format, ...) +{ + char buf[256]; + int len; + va_list ap; + + va_start(ap, format); + len = vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + if (len < 0) + return -1; + + if (len < sizeof(buf)) + { + *ret = strdup(buf); + } + else + { + *ret = malloc(len + 1); /* snprintf doesn't count trailing '\0' */ + if (*ret != NULL) + { + va_start(ap, format); + len = vsnprintf(*ret, len + 1, format, ap); + va_end(ap); + if (len < 0) { + free(*ret); + *ret = NULL; + } + } + } + + if (*ret == NULL) + return -1; + + return len; +} +#endif /* HAVE_ASPRINTF */ + +static void +InitBuffer(Buffer *b) +{ + b->room = INIT_BUFFER_SIZE; + b->used = 0; + b->buff = (char *)malloc(INIT_BUFFER_SIZE*sizeof(char)); +} + +#ifdef notyet +static void +FreeBuffer(Buffer *b) +{ + free(b->buff); +} +#endif + +static void +AppendToBuffer(Buffer *b, char *str, int len) +{ + while (b->used + len > b->room) { + b->buff = (char *)realloc(b->buff, 2*b->room*(sizeof(char))); + b->room *= 2; + } + strncpy(b->buff + b->used, str, len); + b->used += len; +} + +static void +InitEntries(Entries *e) +{ + e->room = INIT_ENTRY_SIZE; + e->used = 0; + e->entry = (Entry *)malloc(INIT_ENTRY_SIZE*sizeof(Entry)); +} + +static void +FreeEntries(Entries *e) +{ + register int i; + + for (i = 0; i < e->used; i++) { + if (e->entry[i].usable) { + free(e->entry[i].tag); + free(e->entry[i].value); + } + } + free((char *)e->entry); +} + +static void +AddEntry(Entries *e, Entry *entry) +{ + register int n; + + for (n = 0; n < e->used; n++) { + if (!strcmp(e->entry[n].tag, entry->tag)) { + /* overwrite old entry */ + if (e->entry[n].lineno && !quiet) { + fprintf (stderr, + "%s: \"%s\" on line %d overrides entry on line %d\n", + ProgramName, entry->tag, entry->lineno, + e->entry[n].lineno); + } + free(e->entry[n].tag); + free(e->entry[n].value); + entry->usable = True; + e->entry[n] = *entry; + return; /* ok to leave, now there's only one of each tag in db */ + } + } + + if (e->used == e->room) { + e->entry = (Entry *)realloc((char *)e->entry, + 2*e->room*(sizeof(Entry))); + e->room *= 2; + } + entry->usable = True; + e->entry[e->used++] = *entry; +} + + +static int +CompareEntries(const void *e1, const void *e2) +{ + return strcmp(((Entry *)e1)->tag, ((Entry *)e2)->tag); +} + +static void +AppendEntryToBuffer(Buffer *buffer, Entry *entry) +{ + AppendToBuffer(buffer, entry->tag, strlen(entry->tag)); + AppendToBuffer(buffer, ":\t", 2); + AppendToBuffer(buffer, entry->value, strlen(entry->value)); + AppendToBuffer(buffer, "\n", 1); +} + +/* + * Return the position of the first unescaped occurrence of dest in string. + * If lines is non-null, return the number of newlines skipped over. + */ +static char * +FindFirst(char *string, char dest, int *lines) +{ + if (lines) + *lines = 0; + for (;;) { + if (*string == '\0') + return NULL; + if (*string == '\\') { + if (*++string == '\0') + return NULL; + } else if (*string == dest) + return string; + if (*string == '\n' && lines) + (*lines)++; + string++; + } +} + +static void +GetEntries(Entries *entries, Buffer *buff, int bequiet) +{ + register char *line, *colon, *temp, *str; + Entry entry; + register int length; + int lineno = 0; + int lines_skipped; + + str = buff->buff; + if (!str) return; + for ( ; str < buff->buff + buff->used; + str = line + 1, lineno += lines_skipped) { + line = FindFirst(str, '\n', &lines_skipped); + lineno++; + if (!line) + line = buff->buff + buff->used; + if (*str == '!') + continue; + if (*str == '\n') + continue; + if (!bequiet && *str == '#') { + int dummy; + if (sscanf (str, "# %d", &dummy) == 1 || + sscanf (str, "# line %d", &dummy) == 1) + lineno = dummy - 1; + continue; + } + for (temp = str; + *temp && *temp != '\n' && isascii(*temp) && isspace(*temp); + temp++) ; + if (!*temp || *temp == '\n') continue; + + colon = FindFirst(str, ':', NULL); + if (!colon || colon > line) { + if (!bequiet && !quiet) + fprintf (stderr, + "%s: colon missing on line %d, ignoring line\n", + ProgramName, lineno); + continue; + } + + /* strip leading and trailing blanks from name and store result */ + while (*str == ' ' || *str == '\t') + str++; + length = colon - str; + while (length && (str[length-1] == ' ' || str[length-1] == '\t')) + length--; + temp = (char *)malloc(length + 1); + strncpy(temp, str, length); + temp[length] = '\0'; + entry.tag = temp; + + /* strip leading and trailing blanks from value and store result */ + colon++; + while (*colon == ' ' || *colon == '\t') + colon++; + length = line - colon; + temp = (char *)malloc(length + 1); + strncpy(temp, colon, length); + temp[length] = '\0'; + entry.value = temp; + entry.lineno = bequiet ? 0 : lineno; + + AddEntry(entries, &entry); + } +} + +static void +GetEntriesString(Entries *entries, char *str) +{ + Buffer buff; + + if (str && *str) { + buff.buff = str; + buff.used = strlen(str); + GetEntries(entries, &buff, 1); + } +} + +static void +ReadFile(Buffer *buffer, FILE *input) +{ + char buf[BUFSIZ + 1]; + register int bytes; + + buffer->used = 0; + while (!feof(input) && (bytes = fread(buf, 1, BUFSIZ, input)) > 0) { +#ifdef WIN32 + char *p; + buf[bytes] = '\0'; + for (p = buf; p = strchr(p, '\r'); ) { + if (p[-1] == '\\' && p[1] == '\n') { + bytes -= 3; + strcpy(p - 1, p + 2); + } + } +#endif + AppendToBuffer(buffer, buf, bytes); + } + AppendToBuffer(buffer, "", 1); +} + +static void +AddDef(String *buff, char *title, char *value) +{ +#ifdef PATHETICCPP + if (need_real_defines) { + addstring(buff, "\n#define "); + addtokstring(buff, title); + if (value && (value[0] != '\0')) { + addstring(buff, " "); + addstring(buff, value); + } + return; + } +#endif + if (buff->used) { + if (oper == OPSYMBOLS) + addstring(buff, "\n-D"); + else + addstring(buff, " -D"); + } else + addstring(buff, "-D"); + addtokstring(buff, title); + if (value && (value[0] != '\0')) { + addstring(buff, "="); + addescapedstring(buff, value); + } +} + +static void +AddSimpleDef(String *buff, char *title) +{ + AddDef(buff, title, (char *)NULL); +} + +static void +AddDefQ(String *buff, char *title, char *value) +{ +#ifdef PATHETICCPP + if (need_real_defines) + AddDef(buff, title, value); + else +#endif + if (value && (value[0] != '\0')) { + AddSimpleDef(buff, title); + addstring(buff, "=\""); + addescapedstring(buff, value); + addstring(buff, "\""); + } else + AddDef(buff, title, NULL); +} + +static void +AddNum(String *buff, char *title, int value) +{ + char num[20]; + snprintf(num, sizeof(num), "%d", value); + AddDef(buff, title, num); +} + +static void +AddDefTok(String *buff, char *prefix, char *title) +{ + char name[512]; + + snprintf(name, sizeof(name), "%s%s", prefix, title); + AddSimpleDef(buff, name); +} + +static void +AddDefHostname(String *buff, char *title, char *value) +{ + char *s; + char name[512]; + char c; + + strncpy (name, value, sizeof(name)-1); + name[sizeof(name)-1] = '\0'; + for (s = name; (c = *s); s++) { + if (!isalpha(c) && !isdigit(c) && c != '_' && c != '.' && c != ':' && c != '-') + *s = '_'; + } + AddDef(buff, title, name); +} + +static void +AddUndef(String *buff, char *title) +{ +#ifdef PATHETICCPP + if (need_real_defines) { + addstring(buff, "\n#undef "); + addstring(buff, title); + return; + } +#endif + if (buff->used) { + if (oper == OPSYMBOLS) + addstring(buff, "\n-U"); + else + addstring(buff, " -U"); + } else + addstring(buff, "-U"); + addtokstring(buff, title); +} + +static void +DoCmdDefines(String *buff) +{ + int i; + char *arg, *val; + + for (i = 0; i < num_cmd_defines; i++) { + arg = cmd_defines[i]; + if (arg[1] == 'D') { + val = strchr(arg, '='); + if (val) { + *val = '\0'; + AddDefQ(buff, arg + 2, val + 1); + *val = '='; + } else + AddSimpleDef(buff, arg + 2); + } else + AddUndef(buff, arg + 2); + } +} + +static int +Resolution(int pixels, int mm) +{ + if (mm == 0) + return 0; + else + return ((pixels * 100000 / mm) + 50) / 100; +} + + +static void +DoDisplayDefines(Display *display, String *defs, char *host) +{ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 255 +#endif + char client[MAXHOSTNAMELEN], server[MAXHOSTNAMELEN], *colon; + char **extnames; + int n; + + XmuGetHostname(client, MAXHOSTNAMELEN); + strncpy(server, XDisplayName(host), sizeof(server)); + server[sizeof(server) - 1] = '\0'; + /* search for final colon to skip over any embedded colons in IPv6 + numeric address forms */ + colon = strrchr(server, ':'); + n = 0; + if (colon) { + /* remove extra colon if there are exactly two, since it indicates + DECnet. Three colons is an IPv6 address ending in :: though. */ + if ((colon > server) && (*(colon-1) == ':') && + ( ((colon - 1) == server) || (*(colon-2) != ':') ) ) { + *(colon-1) = ':'; + } + *colon++ = '\0'; + sscanf(colon, "%d", &n); + } + if (!*server || !strcmp(server, "unix") || !strcmp(server, "localhost")) + strcpy(server, client); + AddDefHostname(defs, "HOST", server); /* R3 compatibility */ + AddDefHostname(defs, "SERVERHOST", server); + AddDefTok(defs, "SRVR_", server); + AddNum(defs, "DISPLAY_NUM", n); + AddDefHostname(defs, "CLIENTHOST", client); + AddDefTok(defs, "CLNT_", client); + AddNum(defs, "VERSION", ProtocolVersion(display)); + AddNum(defs, "REVISION", ProtocolRevision(display)); + AddDefQ(defs, "VENDOR", ServerVendor(display)); + AddDefTok(defs, "VNDR_", ServerVendor(display)); + AddNum(defs, "RELEASE", VendorRelease(display)); + AddNum(defs, "NUM_SCREENS", ScreenCount(display)); + extnames = XListExtensions(display, &n); + while (--n >= 0) + AddDefTok(defs, "EXT_", extnames[n]); + XFreeExtensionList(extnames); +} + +static char *ClassNames[] = { + "StaticGray", + "GrayScale", + "StaticColor", + "PseudoColor", + "TrueColor", + "DirectColor" +}; + +static void +DoScreenDefines(Display *display, int scrno, String *defs) +{ + Screen *screen; + Visual *visual; + XVisualInfo vinfo, *vinfos; + int nv, i, j; + char name[50]; + + screen = ScreenOfDisplay(display, scrno); + visual = DefaultVisualOfScreen(screen); + vinfo.screen = scrno; + vinfos = XGetVisualInfo(display, VisualScreenMask, &vinfo, &nv); + AddNum(defs, "SCREEN_NUM", scrno); + AddNum(defs, "WIDTH", screen->width); + AddNum(defs, "HEIGHT", screen->height); + AddNum(defs, "X_RESOLUTION", Resolution(screen->width,screen->mwidth)); + AddNum(defs, "Y_RESOLUTION", Resolution(screen->height,screen->mheight)); + AddNum(defs, "PLANES", DisplayPlanes(display, scrno)); + AddNum(defs, "BITS_PER_RGB", visual->bits_per_rgb); + AddDefQ(defs, "CLASS", ClassNames[visual->class]); + snprintf(name, sizeof(name), "CLASS_%s", ClassNames[visual->class]); + AddNum(defs, name, (int)visual->visualid); + switch(visual->class) { + case StaticColor: + case PseudoColor: + case TrueColor: + case DirectColor: + AddSimpleDef(defs, "COLOR"); + break; + } + for (i = 0; i < nv; i++) { + for (j = i; --j >= 0; ) { + if (vinfos[j].class == vinfos[i].class && + vinfos[j].depth == vinfos[i].depth) + break; + } + if (j < 0) { + snprintf(name, sizeof(name), "CLASS_%s_%d", + ClassNames[vinfos[i].class], vinfos[i].depth); + AddNum(defs, name, (int)vinfos[i].visualid); + } + } + XFree((char *)vinfos); +} + +static Entry * +FindEntry(Entries *db, Buffer *b) +{ + int i; + register Entry *e; + Entries phoney; + Entry entry; + + entry.usable = False; + entry.tag = NULL; + entry.value = NULL; + phoney.used = 0; + phoney.room = 1; + phoney.entry = &entry; + GetEntries(&phoney, b, 1); + if (phoney.used < 1) + return NULL; + for (i = 0; i < db->used; i++) { + e = &db->entry[i]; + if (!e->usable) + continue; + if (strcmp(e->tag, entry.tag)) + continue; + e->usable = False; + if (strcmp(e->value, entry.value)) + return e; + return NULL; + } + return NULL; +} + +static void +EditFile(Entries *new, FILE *in, FILE *out) +{ + Buffer b; + char buff[BUFSIZ]; + register Entry *e; + register char *c; + int i; + + InitBuffer(&b); + while (in) { + b.used = 0; + while (1) { + buff[0] ='\0'; + if (!fgets(buff, BUFSIZ, in)) + goto cleanup; + AppendToBuffer(&b, buff, strlen(buff)); + c = &b.buff[b.used - 1]; + if ((*(c--) == '\n') && (b.used == 1 || *c != '\\')) + break; + } + if ((e = FindEntry(new, &b))) + fprintf(out, "%s:\t%s\n", e->tag, e->value); + else + fwrite(b.buff, 1, b.used, out); + } +cleanup: + for (i = 0; i < new->used; i++) { + e = &new->entry[i]; + if (e->usable) + fprintf(out, "%s:\t%s\n", e->tag, e->value); + } +} + +static void +Syntax (void) +{ + fprintf (stderr, + "usage: %s [-options ...] [filename]\n\n" + "where options include:\n" + " -display host:dpy display to use\n" + " -all do all resources [default]\n" + " -global do screen-independent resources\n" + " -screen do screen-specific resources for one screen\n" + " -screens do screen-specific resources for all screens\n" + " -n show but don't do changes\n" + " -cpp filename preprocessor to use [%s]\n" + " -nocpp do not use a preprocessor\n" + " -query query resources\n" + " -load load resources from file [default]\n" + " -override add in resources from file\n" + " -merge merge resources from file & sort\n" + " -edit filename edit resources into file\n" + " -backup string backup suffix for -edit [%s]\n" + " -symbols show preprocessor symbols\n" + " -remove remove resources\n" + " -retain avoid server reset (avoid using this)\n" + " -quiet don't warn about duplicates\n" + " -Dname[=value], -Uname, -Idirectory passed to preprocessor\n" + "\n" + "A - or no input filename represents stdin.\n", + ProgramName, cpp_program ? cpp_program : "", BACKUP_SUFFIX); + exit (1); +} + +/* + * The following is a hack until XrmParseCommand is ready. It determines + * whether or not the given string is an abbreviation of the arg. + */ + +static Bool +isabbreviation(char *arg, char *s, int minslen) +{ + int arglen; + int slen; + + /* exact match */ + if (!strcmp (arg, s)) return (True); + + arglen = strlen (arg); + slen = strlen (s); + + /* too long or too short */ + if (slen >= arglen || slen < minslen) return (False); + + /* abbreviation */ + if (strncmp (arg, s, slen) == 0) return (True); + + /* bad */ + return (False); +} + +static void +addstring(String *arg, const char *s) +{ + if(arg->used + strlen(s) + 1 >= arg->room) { + if(arg->val) + arg->val = (char *)realloc(arg->val, arg->room + CHUNK_SIZE); + else + arg->val = (char *)malloc(arg->room + CHUNK_SIZE); + if(arg->val == NULL) + fatal("%s: Not enough memory\n", ProgramName); + arg->room += CHUNK_SIZE; + } + if(arg->used) + strcat(arg->val, s); + else + strcpy(arg->val, s); + arg->used += strlen(s); +} + +static void +addescapedstring(String *arg, const char *s) +{ + char copy[512], *c; + + for (c = copy; *s && c < ©[sizeof(copy)-1]; s++) { + switch (*s) { + case '"': case '\'': case '`': + case '$': case '\\': + *c++ = '_'; + break; + default: + *c++ = *s; + } + } + *c = 0; + addstring (arg, copy); +} + +static void +addtokstring(String *arg, const char *s) +{ + char copy[512], *c; + + for (c = copy; *s && c < ©[sizeof(copy)-1]; s++) { + if (!isalpha(*s) && !isdigit(*s) && *s != '_') + *c++ = '_'; + else + *c++ = *s; + } + *c = 0; + addstring (arg, copy); +} + + +int +main(int argc, char *argv[]) +{ + int i; + char *displayname = NULL; + int whichResources = RALL; + int retainProp = 0; + FILE *fp = NULL; + Bool need_newline; + + ProgramName = argv[0]; + + defines.room = defines.used = includes.room = includes.used = 0; + + /* initialize the includes String struct */ + addstring(&includes, ""); + + /* Pick the default cpp to use. This needs to be done before + * we parse the command line in order to honor -nocpp which sets + * it back to NULL. + */ + if (cpp_program == NULL) { + int number_of_elements + = (sizeof cpp_locations) / (sizeof cpp_locations[0]); + int j; + + for (j = 0; j < number_of_elements; j++) { + char *end, *dup; + /* cut off arguments */ + dup = strdup(cpp_locations[j]); + end = strchr(dup,' '); + if (end) + *end = '\0'; + if (access(dup, X_OK) == 0) { + cpp_program = cpp_locations[j]; + free(dup); + break; + } + free(dup); + } + } + + /* needs to be replaced with XrmParseCommand */ + + for (i = 1; i < argc; i++) { + char *arg = argv[i]; + + if (arg[0] == '-') { + if (arg[1] == '\0') { + filename = NULL; + continue; + } else if (isabbreviation ("-help", arg, 2)) { + Syntax (); + /* doesn't return */ + } else if (isabbreviation ("-display", arg, 2)) { + if (++i >= argc) Syntax (); + displayname = argv[i]; + continue; + } else if (isabbreviation ("-geometry", arg, 3)) { + if (++i >= argc) Syntax (); + /* ignore geometry */ + continue; + } else if (isabbreviation ("-cpp", arg, 2)) { + if (++i >= argc) Syntax (); + cpp_program = argv[i]; + continue; + } else if (!strcmp ("-n", arg)) { + dont_execute = True; + continue; + } else if (isabbreviation ("-nocpp", arg, 3)) { + cpp_program = NULL; + continue; + } else if (isabbreviation ("-query", arg, 2)) { + oper = OPQUERY; + continue; + } else if (isabbreviation ("-load", arg, 2)) { + oper = OPLOAD; + continue; + } else if (isabbreviation ("-merge", arg, 2)) { + oper = OPMERGE; + continue; + } else if (isabbreviation ("-override", arg, 2)) { + oper = OPOVERRIDE; + continue; + } else if (isabbreviation ("-symbols", arg, 3)) { + oper = OPSYMBOLS; + continue; + } else if (isabbreviation ("-remove", arg, 4)) { + oper = OPREMOVE; + continue; + } else if (isabbreviation ("-edit", arg, 2)) { + if (++i >= argc) Syntax (); + oper = OPEDIT; + editFile = argv[i]; + continue; + } else if (isabbreviation ("-backup", arg, 2)) { + if (++i >= argc) Syntax (); + backup_suffix = argv[i]; + continue; + } else if (isabbreviation ("-all", arg, 2)) { + whichResources = RALL; + continue; + } else if (isabbreviation ("-global", arg, 3)) { + whichResources = RGLOBAL; + continue; + } else if (isabbreviation ("-screen", arg, 3)) { + whichResources = RSCREEN; + continue; + } else if (!strcmp ("-screens", arg)) { + whichResources = RSCREENS; + continue; + } else if (isabbreviation ("-retain", arg, 4)) { + retainProp = 1; + continue; + } else if (isabbreviation ("-quiet", arg, 2)) { + quiet = True; + continue; + } else if (arg[1] == 'I') { + addstring(&includes, " "); + addescapedstring(&includes, arg); + continue; + } else if (arg[1] == 'U' || arg[1] == 'D') { + if (num_cmd_defines < MAX_CMD_DEFINES) { + cmd_defines[num_cmd_defines++] = arg; + } else { + fatal("%s: Too many -U/-D arguments\n", ProgramName); + } + continue; + } + Syntax (); + } else if (arg[0] == '=') + continue; + else + filename = arg; + } /* end for */ + +#ifndef WIN32 + while ((i = open("/dev/null", O_RDONLY)) < 3) + ; /* make sure later freopen won't clobber things */ + (void) close(i); +#endif + /* Open display */ + if (!(dpy = XOpenDisplay (displayname))) + fatal("%s: Can't open display '%s'\n", ProgramName, + XDisplayName (displayname)); + + if (whichResources == RALL && ScreenCount(dpy) == 1) + whichResources = RGLOBAL; + +#ifdef PATHETICCPP + if (cpp_program && + (oper == OPLOAD || oper == OPMERGE || oper == OPOVERRIDE)) { + need_real_defines = True; +#ifdef WIN32 + strcpy(tmpname2, "xrdbD_XXXXXX"); + strcpy(tmpname3, "\\temp\\xrdbD_XXXXXX"); +#else +#ifdef __UNIXOS2__ + { char *tmpdir=getenv("TMP"); + if (!tmpdir) tmpdir="/"; + sprintf(tmpname2, "%s/xrdbD_XXXXXX",tmpdir); + } +#else + strcpy(tmpname2, "/tmp/xrdbD_XXXXXX"); +#endif +#endif + (void) mktemp(tmpname2); + } +#endif + + if (!filename && +#ifdef PATHETICCPP + need_real_defines +#else + (oper == OPLOAD || oper == OPMERGE || oper == OPOVERRIDE) && + (whichResources == RALL || whichResources == RSCREENS) +#endif + ) { + char inputbuf[1024]; +#ifdef WIN32 + strcpy(tmpname, "\\temp\\xrdb_XXXXXX"); +#else +#ifdef __UNIXOS2__ + { char *tmpdir=getenv("TMP"); + if (!tmpdir) tmpdir="/"; + sprintf(tmpname, "%s/xrdb_XXXXXX",tmpdir); + } +#else + strcpy(tmpname, "/tmp/xrdb_XXXXXX"); +#endif +#endif +#ifndef HAVE_MKSTEMP + (void) mktemp(tmpname); + filename = tmpname; + fp = fopen(filename, "w"); +#else + { + int fd = mkstemp(tmpname); + filename = tmpname; + fp = fdopen(fd, "w"); + } +#endif /* MKSTEMP */ + if (!fp) + fatal("%s: Failed to open temp file: %s\n", ProgramName, + filename); + while (fgets(inputbuf, sizeof(inputbuf), stdin) != NULL) + fputs(inputbuf, fp); + fclose(fp); + } + + DoDisplayDefines(dpy, &defines, displayname); + defines_base = defines.used; + need_newline = (oper == OPQUERY || oper == OPSYMBOLS || + (dont_execute && oper != OPREMOVE)); + InitBuffer(&buffer); + if (whichResources == RGLOBAL) + Process(DefaultScreen(dpy), False, True); + else if (whichResources == RSCREEN) + Process(DefaultScreen(dpy), True, True); + else if (whichResources == RSCREENS || + (oper != OPLOAD && oper != OPMERGE && oper != OPOVERRIDE)) { + if (whichResources == RALL && oper != OPSYMBOLS) { + if (need_newline) + printf("! screen-independent resources\n"); + Process(0, False, True); + if (need_newline) + printf("\n"); + } + for (i = 0; i < ScreenCount(dpy); i++) { + if (need_newline) { + if (oper == OPSYMBOLS) + printf("# screen %d symbols\n", i); + else { + printf("! screen %d resources\n", i); + printf("#if SCREEN_NUM == %d\n", i); + } + } + Process(i, True, True); + if (need_newline) { + if (oper != OPSYMBOLS) + printf("#endif\n"); + if (i+1 != ScreenCount(dpy)) + printf("\n"); + } + } + } + else { + Entries *dbs; + + dbs = (Entries *)malloc(ScreenCount(dpy) * sizeof(Entries)); + for (i = 0; i < ScreenCount(dpy); i++) { + Process(i, True, False); + dbs[i] = newDB; + } + InitEntries(&newDB); + if (oper == OPMERGE || oper == OPOVERRIDE) + GetEntriesString(&newDB, XResourceManagerString(dpy)); + ShuffleEntries(&newDB, dbs, ScreenCount(dpy)); + if (need_newline) + printf("! screen-independent resources\n"); + ReProcess(0, False); + if (need_newline) + printf("\n"); + for (i = 0; i < ScreenCount(dpy); i++) { + newDB = dbs[i]; + if (need_newline) { + printf("! screen %d resources\n", i); + printf("#if SCREEN_NUM == %d\n", i); + } + ReProcess(i, True); + if (need_newline) { + printf("#endif\n"); + if (i+1 != ScreenCount(dpy)) + printf("\n"); + } + } + } + + if (fp) + unlink(filename); + if (retainProp) + XSetCloseDownMode(dpy, RetainPermanent); + XCloseDisplay(dpy); + exit (0); +} + + +static void +FormatEntries(Buffer *buffer, Entries *entries) +{ + register int i; + + buffer->used = 0; + if (!entries->used) + return; + if (oper == OPMERGE) + qsort(entries->entry, entries->used, sizeof(Entry), + CompareEntries); + for (i = 0; i < entries->used; i++) { + if (entries->entry[i].usable) + AppendEntryToBuffer(buffer, &entries->entry[i]); + } +} + +static void +StoreProperty(Display *dpy, Window root, Atom res_prop) +{ + int len = buffer.used; + int mode = PropModeReplace; + unsigned char *buf = (unsigned char *)buffer.buff; + int max = (XMaxRequestSize(dpy) << 2) - 28; + + if (len > max) { + XGrabServer(dpy); + do { + XChangeProperty(dpy, root, res_prop, XA_STRING, 8, mode, buf, max); + buf += max; + len -= max; + mode = PropModeAppend; + } while (len > max); + } + XChangeProperty(dpy, root, res_prop, XA_STRING, 8, mode, buf, len); + if (mode != PropModeReplace) + XUngrabServer(dpy); +} + +static void +Process(int scrno, Bool doScreen, Bool execute) +{ + char *xdefs; + Window root; + Atom res_prop; + FILE *input, *output; + char *cmd; + + defines.val[defines_base] = '\0'; + defines.used = defines_base; + buffer.used = 0; + InitEntries(&newDB); + DoScreenDefines(dpy, scrno, &defines); + DoCmdDefines(&defines); + if (doScreen) { + xdefs = XScreenResourceString (ScreenOfDisplay(dpy, scrno)); + root = RootWindow(dpy, scrno); + res_prop = XInternAtom(dpy, SCREEN_RESOURCES, False); + } else { + xdefs = XResourceManagerString (dpy); + root = RootWindow(dpy, 0); + res_prop = XA_RESOURCE_MANAGER; + } + if (oper == OPSYMBOLS) { + printf ("%s\n", defines.val); + } else if (oper == OPQUERY) { + if (xdefs) + printf ("%s", xdefs); /* fputs broken in SunOS 4.0 */ + } else if (oper == OPREMOVE) { + if (xdefs) + XDeleteProperty(dpy, root, res_prop); + } else if (oper == OPEDIT) { + char template[100], old[100]; + + input = fopen(editFile, "r"); + snprintf(template, sizeof(template), "%sXXXXXX", editFile); +#ifndef HAVE_MKSTEMP + (void) mktemp(template); + output = fopen(template, "w"); +#else + { + int fd = mkstemp(template); + output = fdopen(fd, "w"); + } +#endif + if (!output) + fatal("%s: can't open temporary file '%s'\n", ProgramName, template); + GetEntriesString(&newDB, xdefs); + EditFile(&newDB, input, output); + if (input) + fclose(input); + fclose(output); + snprintf(old, sizeof(old), "%s%s", editFile, backup_suffix); + if (dont_execute) { /* then write to standard out */ + char buf[BUFSIZ]; + int n; + + output = fopen (template, "r"); + if (output) { + while ((n = fread (buf, 1, sizeof buf, output)) > 0) { + fwrite (buf, 1, n, stdout); + } + fclose (output); + } + unlink (template); + } else { + rename (editFile, old); + if (rename (template, editFile)) + fatal("%s: can't rename file '%s' to '%s'\n", ProgramName, + template, editFile); + } + } else { + if (oper == OPMERGE || oper == OPOVERRIDE) + GetEntriesString(&newDB, xdefs); +#ifdef PATHETICCPP + if (need_real_defines) { +#ifdef WIN32 + if (!(input = fopen(tmpname2, "w"))) + fatal("%s: can't open file '%s'\n", ProgramName, tmpname2); + fputs(defines.val, input); + fprintf(input, "\n#include \"%s\"\n", filename); + fclose(input); + (void) mktemp(tmpname3); + if (asprintf(&cmd, "%s -P%s %s > %s", cpp_program, includes.val, + tmpname2, tmpname3) == -1) + fatal("%s: Out of memory\n", ProgramName); + if (system(cmd) < 0) + fatal("%s: cannot run '%s'\n", ProgramName, cmd); + free(cmd); + if (!(input = fopen(tmpname3, "r"))) + fatal("%s: can't open file '%s'\n", ProgramName, tmpname3); +#else + if (!freopen(tmpname2, "w+", stdin)) + fatal("%s: can't open file '%s'\n", ProgramName, tmpname2); + fputs(defines.val, stdin); + fprintf(stdin, "\n#include \"%s\"\n", filename); + fflush(stdin); + fseek(stdin, 0, 0); + if (asprintf(&cmd, "%s -P%s", cpp_program, includes.val) == -1) + fatal("%s: Out of memory\n", ProgramName); + if (!(input = popen(cmd, "r"))) + fatal("%s: cannot run '%s'\n", ProgramName, cmd); + free(cmd); +#endif + } else { +#endif + if (filename) { + if (!freopen (filename, "r", stdin)) + fatal("%s: can't open file '%s'\n", ProgramName, filename); + } + if (cpp_program) { +#ifdef WIN32 + (void) mktemp(tmpname3); + if (asprintf(&cmd, "%s -P%s %s %s > %s", cpp_program, + includes.val, defines.val, + filename ? filename : "", tmpname3) == -1) + fatal("%s: Out of memory\n", ProgramName); + if (system(cmd) < 0) + fatal("%s: cannot run '%s'\n", ProgramName, cmd); + free(cmd); + if (!(input = fopen(tmpname3, "r"))) + fatal("%s: can't open file '%s'\n", ProgramName, tmpname3); +#else + if (asprintf(&cmd, "%s -P%s %s %s", cpp_program, + includes.val, defines.val, + filename ? filename : "") == -1) + fatal("%s: Out of memory\n", ProgramName); + if (!(input = popen(cmd, "r"))) + fatal("%s: cannot run '%s'\n", ProgramName, cmd); + free(cmd); +#endif + } else { + input = stdin; + } +#ifdef PATHETICCPP + } +#endif + ReadFile(&buffer, input); + if (cpp_program) { +#ifdef WIN32 + fclose(input); +#else + pclose(input); +#endif + } +#ifdef PATHETICCPP + if (need_real_defines) { + unlink(tmpname2); +#ifdef WIN32 + if (tmpname3[strlen(tmpname3) - 1] != 'X') + unlink(tmpname3); +#endif + } +#endif + GetEntries(&newDB, &buffer, 0); + if (execute) { + FormatEntries(&buffer, &newDB); + if (dont_execute) { + if (buffer.used > 0) { + fwrite (buffer.buff, 1, buffer.used, stdout); + if (buffer.buff[buffer.used - 1] != '\n') putchar ('\n'); + } + } else if (buffer.used > 1 || !doScreen) + StoreProperty (dpy, root, res_prop); + else + XDeleteProperty (dpy, root, res_prop); + } + } + if (execute) + FreeEntries(&newDB); + if (doScreen && xdefs) + XFree(xdefs); +} + +static void +ShuffleEntries(Entries *db, Entries *dbs, int num) +{ + int *hits; + register int i, j, k; + Entries cur, cmp; + char *curtag, *curvalue; + + hits = (int *)malloc(num * sizeof(int)); + cur = dbs[0]; + for (i = 0; i < cur.used; i++) { + curtag = cur.entry[i].tag; + curvalue = cur.entry[i].value; + for (j = 1; j < num; j++) { + cmp = dbs[j]; + for (k = 0; k < cmp.used; k++) { + if (cmp.entry[k].usable && + !strcmp(curtag, cmp.entry[k].tag) && + !strcmp(curvalue, cmp.entry[k].value)) + { + hits[j] = k; + break; + } + } + if (k == cmp.used) + break; + } + if (j == num) { + AddEntry(db, &cur.entry[i]); + hits[0] = i; + for (j = 0; j < num; j++) + dbs[j].entry[hits[j]].usable = False; + } + } + free((char *)hits); +} + +static void +ReProcess(int scrno, Bool doScreen) +{ + Window root; + Atom res_prop; + + FormatEntries(&buffer, &newDB); + if (doScreen) { + root = RootWindow(dpy, scrno); + res_prop = XInternAtom(dpy, SCREEN_RESOURCES, False); + } else { + root = RootWindow(dpy, 0); + res_prop = XA_RESOURCE_MANAGER; + } + if (dont_execute) { + if (buffer.used > 0) { + fwrite (buffer.buff, 1, buffer.used, stdout); + if (buffer.buff[buffer.used - 1] != '\n') putchar ('\n'); + } + } else { + if (buffer.used > 1 || !doScreen) + StoreProperty (dpy, root, res_prop); + else + XDeleteProperty (dpy, root, res_prop); + } + FreeEntries(&newDB); +} + +static void +fatal(char *msg, ...) +{ + va_list args; + + if (errno != 0) + perror(ProgramName); + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); + exit(1); +} diff --git a/packages.txt b/packages.txt index b89bc8e94..bf49b88c2 100644 --- a/packages.txt +++ b/packages.txt @@ -87,6 +87,7 @@ xhost-1.0.5 xineramaproto-1.2.1 xkbcomp git version xkeyboard-config git version +xrdb git version xproto-7.0.23 xserver git version xtrans git version -- cgit v1.2.3 From fb84fb26466262dcab4bd31bdf51c982f14f891a Mon Sep 17 00:00:00 2001 From: marha Date: Wed, 6 Mar 2013 08:37:36 +0100 Subject: fontconfig libfontenc mesa xserver git update 6 Mar 2013 xserver commit 103b77c59e3638a45179bf6d7908f5c738d2d872 libfontenc commit 624508365ec3279bc74ce523d024533e062629e1 fontconfig commit e96d7760886a3781a46b3271c76af99e15cb0146 mesa commit 88b20d58344ed336b146799c0bf1149a932dc2d7 --- fontconfig/doc/fcconfig.fncs | 21 + fontconfig/fc-cache/fc-cache.c | 38 +- fontconfig/fontconfig/fontconfig.h | 7 + fontconfig/src/fccache.c | 99 ++-- fontconfig/src/fccfg.c | 57 +++ fontconfig/src/fcinit.c | 30 +- fontconfig/src/fcint.h | 15 +- fontconfig/src/fclang.c | 4 +- fontconfig/src/fcstr.c | 62 ++- libfontenc/src/encparse.c | 2 +- mesalib/bin/get-pick-list.sh | 2 +- mesalib/configure.ac | 16 +- mesalib/scons/llvm.py | 2 +- mesalib/src/gallium/auxiliary/util/u_blitter.c | 5 + mesalib/src/glsl/glsl_parser_extras.cpp | 15 +- mesalib/src/glsl/standalone_scaffolding.cpp | 2 +- mesalib/src/glsl/standalone_scaffolding.h | 2 +- mesalib/src/mesa/main/errors.c | 551 +++++++++------------ mesalib/src/mesa/main/errors.h | 13 +- mesalib/src/mesa/main/get_hash_params.py | 2 +- mesalib/src/mesa/main/mtypes.h | 80 +-- mesalib/src/mesa/main/teximage.c | 1 + mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 20 +- xorg-server/Xi/xibarriers.c | 9 +- xorg-server/configure.ac | 6 +- xorg-server/hw/xfree86/common/xf86DPMS.c | 45 +- 26 files changed, 651 insertions(+), 455 deletions(-) diff --git a/fontconfig/doc/fcconfig.fncs b/fontconfig/doc/fcconfig.fncs index 10028b465..0491a566f 100644 --- a/fontconfig/doc/fcconfig.fncs +++ b/fontconfig/doc/fcconfig.fncs @@ -371,3 +371,24 @@ and parsed. If 'complain' is FcFalse, no warning will be displayed if Returns FcFalse if some error occurred while loading the file, either a parse error, semantic error or allocation failure. Otherwise returns FcTrue. @@ + +@RET@ const FcChar8 * +@FUNC@ FcConfigGetSysRoot +@TYPE1@ const FcConfig * @ARG1@ config +@PURPOSE@ Obtain the system root directory +@DESC@ +Obtrains the system root directory in 'config' if available. +@@ + +@RET@ void +@FUNC@ FcConfigSetSysRoot +@TYPE1@ FcConfig * @ARG1@ config +@TYPE2@ const FcChar8 * @ARG2@ sysroot +@PURPOSE@ Set the system root directory +@DESC@ +Set 'sysroot' as the system root directory. fontconfig prepend 'sysroot' +to the cache directories in order to allow people to generate caches at +the build time. Note that this causes changing current config. i.e. +this function calls FcConfigSetCurrent() internally. +@@ + diff --git a/fontconfig/fc-cache/fc-cache.c b/fontconfig/fc-cache/fc-cache.c index 220609604..aeb0af29b 100644 --- a/fontconfig/fc-cache/fc-cache.c +++ b/fontconfig/fc-cache/fc-cache.c @@ -67,6 +67,7 @@ const struct option longopts[] = { {"force", 0, 0, 'f'}, {"really-force", 0, 0, 'r'}, + {"sysroot", 0, 0, 'y'}, {"system-only", 0, 0, 's'}, {"version", 0, 0, 'V'}, {"verbose", 0, 0, 'v'}, @@ -85,26 +86,28 @@ usage (char *program, int error) { FILE *file = error ? stderr : stdout; #if HAVE_GETOPT_LONG - fprintf (file, "usage: %s [-frsvVh] [--force|--really-force] [--system-only] [--verbose] [--version] [--help] [dirs]\n", + fprintf (file, "usage: %s [-frsvVh] [-y SYSROOT] [--force|--really-force] [--sysroot=SYSROOT] [--system-only] [--verbose] [--version] [--help] [dirs]\n", program); #else - fprintf (file, "usage: %s [-frsvVh] [dirs]\n", + fprintf (file, "usage: %s [-frsvVh] [-y SYSROOT] [dirs]\n", program); #endif fprintf (file, "Build font information caches in [dirs]\n" "(all directories in font configuration by default).\n"); fprintf (file, "\n"); #if HAVE_GETOPT_LONG - fprintf (file, " -f, --force scan directories with apparently valid caches\n"); - fprintf (file, " -r, --really-force erase all existing caches, then rescan\n"); - fprintf (file, " -s, --system-only scan system-wide directories only\n"); - fprintf (file, " -v, --verbose display status information while busy\n"); - fprintf (file, " -V, --version display font config version and exit\n"); - fprintf (file, " -h, --help display this help and exit\n"); + fprintf (file, " -f, --force scan directories with apparently valid caches\n"); + fprintf (file, " -r, --really-force erase all existing caches, then rescan\n"); + fprintf (file, " -s, --system-only scan system-wide directories only\n"); + fprintf (file, " -y, --sysroot=SYSROOT prepend SYSROOT to all paths for scanning\n"); + fprintf (file, " -v, --verbose display status information while busy\n"); + fprintf (file, " -V, --version display font config version and exit\n"); + fprintf (file, " -h, --help display this help and exit\n"); #else fprintf (file, " -f (force) scan directories with apparently valid caches\n"); fprintf (file, " -r, (really force) erase all existing caches, then rescan\n"); fprintf (file, " -s (system) scan system-wide directories only\n"); + fprintf (file, " -y SYSROOT (sysroot) prepend SYSROOT to all paths for scanning\n"); fprintf (file, " -v (verbose) display status information while busy\n"); fprintf (file, " -V (version) display font config version and exit\n"); fprintf (file, " -h (help) display this help and exit\n"); @@ -270,6 +273,7 @@ main (int argc, char **argv) FcBool really_force = FcFalse; FcBool systemOnly = FcFalse; FcConfig *config; + FcChar8 *sysroot = NULL; int i; int changed; int ret; @@ -277,9 +281,9 @@ main (int argc, char **argv) int c; #if HAVE_GETOPT_LONG - while ((c = getopt_long (argc, argv, "frsVvh", longopts, NULL)) != -1) + while ((c = getopt_long (argc, argv, "frsy:Vvh", longopts, NULL)) != -1) #else - while ((c = getopt (argc, argv, "frsVvh")) != -1) + while ((c = getopt (argc, argv, "frsy:Vvh")) != -1) #endif { switch (c) { @@ -292,6 +296,9 @@ main (int argc, char **argv) case 's': systemOnly = FcTrue; break; + case 'y': + sysroot = FcStrCopy ((const FcChar8 *)optarg); + break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); @@ -312,7 +319,16 @@ main (int argc, char **argv) if (systemOnly) FcConfigEnableHome (FcFalse); - config = FcInitLoadConfig (); + if (sysroot) + { + FcConfigSetSysRoot (NULL, sysroot); + FcStrFree (sysroot); + config = FcConfigGetCurrent(); + } + else + { + config = FcInitLoadConfig (); + } if (!config) { fprintf (stderr, "%s: Can't init font config library\n", argv[0]); diff --git a/fontconfig/fontconfig/fontconfig.h b/fontconfig/fontconfig/fontconfig.h index ba4ee6102..fc0ed1ab0 100644 --- a/fontconfig/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig/fontconfig.h @@ -420,6 +420,13 @@ FcConfigSubstitute (FcConfig *config, FcPattern *p, FcMatchKind kind); +FcPublic const FcChar8 * +FcConfigGetSysRoot (const FcConfig *config); + +FcPublic void +FcConfigSetSysRoot (FcConfig *config, + const FcChar8 *sysroot); + /* fccharset.c */ FcPublic FcCharSet* FcCharSetCreate (void); diff --git a/fontconfig/src/fccache.c b/fontconfig/src/fccache.c index 2c631256b..9f1c29827 100644 --- a/fontconfig/src/fccache.c +++ b/fontconfig/src/fccache.c @@ -124,6 +124,7 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config) FcChar8 cache_base[CACHEBASE_LEN]; FcStrList *list; FcChar8 *cache_dir; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); FcDirCacheBasename (dir, cache_base); @@ -133,7 +134,10 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config) while ((cache_dir = FcStrListNext (list))) { - cache_hashed = FcStrPlus (cache_dir, cache_base); + if (sysroot) + cache_hashed = FcStrBuildFilename (sysroot, cache_dir, cache_base, NULL); + else + cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL); if (!cache_hashed) break; (void) unlink ((char *) cache_hashed); @@ -197,7 +201,13 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir, while ((cache_dir = FcStrListNext (list))) { - FcChar8 *cache_hashed = FcStrPlus (cache_dir, cache_base); + const FcChar8 *sysroot = FcConfigGetSysRoot (config); + FcChar8 *cache_hashed; + + if (sysroot) + cache_hashed = FcStrBuildFilename (sysroot, cache_dir, cache_base, NULL); + else + cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL); if (!cache_hashed) break; fd = FcDirCacheOpenFile (cache_hashed, &file_stat); @@ -859,11 +869,12 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) FcAtomic *atomic; FcStrList *list; FcChar8 *cache_dir = NULL; - FcChar8 *test_dir; + FcChar8 *test_dir, *d = NULL; FcCacheSkip *skip; struct stat cache_stat; unsigned int magic; int written; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); /* * Write it to the first directory in the list which is writable @@ -872,10 +883,18 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) list = FcStrListCreate (config->cacheDirs); if (!list) return FcFalse; - while ((test_dir = FcStrListNext (list))) { - if (access ((char *) test_dir, W_OK) == 0) + while ((test_dir = FcStrListNext (list))) + { + if (d) + FcStrFree (d); + if (sysroot) + d = FcStrBuildFilename (sysroot, test_dir, NULL); + else + d = FcStrCopyFilename (test_dir); + + if (access ((char *) d, W_OK) == 0) { - cache_dir = test_dir; + cache_dir = FcStrCopyFilename (d); break; } else @@ -883,35 +902,38 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) /* * If the directory doesn't exist, try to create it */ - if (access ((char *) test_dir, F_OK) == -1) { - if (FcMakeDirectory (test_dir)) + if (access ((char *) d, F_OK) == -1) { + if (FcMakeDirectory (d)) { - cache_dir = test_dir; + cache_dir = FcStrCopyFilename (d); /* Create CACHEDIR.TAG */ - FcDirCacheCreateTagFile (cache_dir); + FcDirCacheCreateTagFile (d); break; } } /* * Otherwise, try making it writable */ - else if (chmod ((char *) test_dir, 0755) == 0) + else if (chmod ((char *) d, 0755) == 0) { - cache_dir = test_dir; + cache_dir = FcStrCopyFilename (d); /* Try to create CACHEDIR.TAG too */ - FcDirCacheCreateTagFile (cache_dir); + FcDirCacheCreateTagFile (d); break; } } } + if (d) + FcStrFree (d); FcStrListDone (list); if (!cache_dir) return FcFalse; FcDirCacheBasename (dir, cache_base); - cache_hashed = FcStrPlus (cache_dir, cache_base); + cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL); if (!cache_hashed) return FcFalse; + FcStrFree (cache_dir); if (FcDebug () & FC_DBG_CACHE) printf ("FcDirCacheWriteDir dir \"%s\" file \"%s\"\n", @@ -989,31 +1011,37 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) { DIR *d; struct dirent *ent; - FcChar8 *dir_base; + FcChar8 *dir; FcBool ret = FcTrue; FcBool remove; FcCache *cache; struct stat target_stat; + const FcChar8 *sysroot; - dir_base = FcStrPlus (cache_dir, (FcChar8 *) FC_DIR_SEPARATOR_S); - if (!dir_base) + /* FIXME: this API needs to support non-current FcConfig */ + sysroot = FcConfigGetSysRoot (NULL); + if (sysroot) + dir = FcStrBuildFilename (sysroot, cache_dir, NULL); + else + dir = FcStrCopyFilename (cache_dir); + if (!dir) { fprintf (stderr, "Fontconfig error: %s: out of memory\n", cache_dir); return FcFalse; } - if (access ((char *) cache_dir, W_OK) != 0) + if (access ((char *) dir, W_OK) != 0) { if (verbose || FcDebug () & FC_DBG_CACHE) - printf ("%s: not cleaning %s cache directory\n", cache_dir, - access ((char *) cache_dir, F_OK) == 0 ? "unwritable" : "non-existent"); + printf ("%s: not cleaning %s cache directory\n", dir, + access ((char *) dir, F_OK) == 0 ? "unwritable" : "non-existent"); goto bail0; } if (verbose || FcDebug () & FC_DBG_CACHE) - printf ("%s: cleaning cache directory\n", cache_dir); - d = opendir ((char *) cache_dir); + printf ("%s: cleaning cache directory\n", dir); + d = opendir ((char *) dir); if (!d) { - perror ((char *) cache_dir); + perror ((char *) dir); ret = FcFalse; goto bail0; } @@ -1030,10 +1058,10 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) strcmp(ent->d_name + 32, "-" FC_ARCHITECTURE FC_CACHE_SUFFIX)) continue; - file_name = FcStrPlus (dir_base, (FcChar8 *) ent->d_name); + file_name = FcStrBuildFilename (dir, (FcChar8 *)ent->d_name, NULL); if (!file_name) { - fprintf (stderr, "Fontconfig error: %s: allocation failure\n", cache_dir); + fprintf (stderr, "Fontconfig error: %s: allocation failure\n", dir); ret = FcFalse; break; } @@ -1042,7 +1070,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) if (!cache) { if (verbose || FcDebug () & FC_DBG_CACHE) - printf ("%s: invalid cache file: %s\n", cache_dir, ent->d_name); + printf ("%s: invalid cache file: %s\n", dir, ent->d_name); remove = FcTrue; } else @@ -1052,7 +1080,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) { if (verbose || FcDebug () & FC_DBG_CACHE) printf ("%s: %s: missing directory: %s \n", - cache_dir, ent->d_name, target_dir); + dir, ent->d_name, target_dir); remove = FcTrue; } FcDirCacheUnload (cache); @@ -1070,7 +1098,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) closedir (d); bail0: - FcStrFree (dir_base); + FcStrFree (dir); return ret; } @@ -1394,7 +1422,7 @@ FcDirCacheCreateTagFile (const FcChar8 *cache_dir) if (access ((char *) cache_dir, W_OK) == 0) { /* Create CACHEDIR.TAG */ - cache_tag = FcStrPlus (cache_dir, (const FcChar8 *) FC_DIR_SEPARATOR_S "CACHEDIR.TAG"); + cache_tag = FcStrBuildFilename (cache_dir, "CACHEDIR.TAG", NULL); if (!cache_tag) return FcFalse; atomic = FcAtomicCreate ((FcChar8 *)cache_tag); @@ -1438,8 +1466,9 @@ FcDirCacheCreateTagFile (const FcChar8 *cache_dir) void FcCacheCreateTagFile (const FcConfig *config) { - FcChar8 *cache_dir = NULL; + FcChar8 *cache_dir = NULL, *d = NULL; FcStrList *list; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); list = FcConfigGetCacheDirs (config); if (!list) @@ -1447,9 +1476,17 @@ FcCacheCreateTagFile (const FcConfig *config) while ((cache_dir = FcStrListNext (list))) { - if (FcDirCacheCreateTagFile (cache_dir)) + if (d) + FcStrFree (d); + if (sysroot) + d = FcStrBuildFilename (sysroot, cache_dir, NULL); + else + d = FcStrCopyFilename (cache_dir); + if (FcDirCacheCreateTagFile (d)) break; } + if (d) + FcStrFree (d); FcStrListDone (list); } diff --git a/fontconfig/src/fccfg.c b/fontconfig/src/fccfg.c index db878d5f4..b762376ae 100644 --- a/fontconfig/src/fccfg.c +++ b/fontconfig/src/fccfg.c @@ -123,6 +123,8 @@ FcConfigCreate (void) config->expr_pool = NULL; + config->sysRoot = NULL; + FcRefInit (&config->ref, 1); return config; @@ -292,6 +294,8 @@ FcConfigDestroy (FcConfig *config) free (page); page = next; } + if (config->sysRoot) + FcStrFree (config->sysRoot); free (config); } @@ -2309,6 +2313,59 @@ FcConfigAcceptFont (FcConfig *config, return FcFalse; return FcTrue; } + +const FcChar8 * +FcConfigGetSysRoot (const FcConfig *config) +{ + if (!config) + { + config = FcConfigGetCurrent (); + if (!config) + return NULL; + } + + return config->sysRoot; +} + +void +FcConfigSetSysRoot (FcConfig *config, + const FcChar8 *sysroot) +{ + FcChar8 *s; + FcBool init = FcFalse; + + if (!config) + { + /* We can't use FcConfigGetCurrent() here to ensure + * the sysroot is set prior to initialize FcConfig, + * to avoid loading caches from non-sysroot dirs. + * So postpone the initialization later. + */ + config = fc_atomic_ptr_get (&_fcConfig); + if (!config) + { + config = FcConfigCreate (); + if (!config) + return; + init = FcTrue; + } + } + + s = FcStrCopyFilename (sysroot); + if (!s) + return; + + if (config->sysRoot) + FcStrFree (config->sysRoot); + + config->sysRoot = s; + if (init) + { + config = FcInitLoadOwnConfigAndFonts (config); + FcConfigSetCurrent (config); + } +} + #define __fccfg__ #include "fcaliastail.h" #undef __fccfg__ diff --git a/fontconfig/src/fcinit.c b/fontconfig/src/fcinit.c index 2360764fc..b8d5d060c 100644 --- a/fontconfig/src/fcinit.c +++ b/fontconfig/src/fcinit.c @@ -65,14 +65,16 @@ FcGetVersion (void) * Load the configuration files */ FcConfig * -FcInitLoadConfig (void) +FcInitLoadOwnConfig (FcConfig *config) { - FcConfig *config; + if (!config) + { + config = FcConfigCreate (); + if (!config) + return NULL; + } FcInitDebug (); - config = FcConfigCreate (); - if (!config) - return NULL; if (!FcConfigParseAndLoad (config, 0, FcTrue)) { @@ -120,15 +122,19 @@ FcInitLoadConfig (void) return config; } +FcConfig * +FcInitLoadConfig (void) +{ + return FcInitLoadOwnConfig (NULL); +} + /* * Load the configuration files and scan for available fonts */ FcConfig * -FcInitLoadConfigAndFonts (void) +FcInitLoadOwnConfigAndFonts (FcConfig *config) { - FcConfig *config = FcInitLoadConfig (); - - FcInitDebug (); + config = FcInitLoadOwnConfig (config); if (!config) return 0; if (!FcConfigBuildFonts (config)) @@ -139,6 +145,12 @@ FcInitLoadConfigAndFonts (void) return config; } +FcConfig * +FcInitLoadConfigAndFonts (void) +{ + return FcInitLoadOwnConfigAndFonts (NULL); +} + /* * Initialize the default library configuration */ diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h index 4eac6105a..d5a7217cc 100644 --- a/fontconfig/src/fcint.h +++ b/fontconfig/src/fcint.h @@ -501,7 +501,9 @@ struct _FcConfig { FcRef ref; /* reference count */ - FcExprPage *expr_pool; /* pool of FcExpr's */ + FcExprPage *expr_pool; /* pool of FcExpr's */ + + FcChar8 *sysRoot; /* override the system root directory */ }; typedef struct _FcFileTime { @@ -819,6 +821,13 @@ FcHashGetSHA256Digest (const FcChar8 *input_strings, FcPrivate FcChar8 * FcHashGetSHA256DigestFromFile (const FcChar8 *filename); +/* fcinit.c */ +FcPrivate FcConfig * +FcInitLoadOwnConfig (FcConfig *config); + +FcPrivate FcConfig * +FcInitLoadOwnConfigAndFonts (FcConfig *config); + /* fcxml.c */ FcPrivate void FcTestDestroy (FcTest *test); @@ -1072,6 +1081,10 @@ FcStrContainsWord (const FcChar8 *s1, const FcChar8 *s2); FcPrivate FcBool FcStrUsesHome (const FcChar8 *s); +FcPrivate FcChar8 * +FcStrBuildFilename (const FcChar8 *path, + ...); + FcPrivate FcChar8 * FcStrLastSlash (const FcChar8 *path); diff --git a/fontconfig/src/fclang.c b/fontconfig/src/fclang.c index 8e9b094b2..9f685f6fd 100644 --- a/fontconfig/src/fclang.c +++ b/fontconfig/src/fclang.c @@ -1027,9 +1027,11 @@ FcLangSetOperate(const FcLangSet *a, const FcChar8 *s)) { FcLangSet *langset = FcLangSetCopy (a); - FcStrList *sl = FcStrListCreate (FcLangSetGetLangs (b)); + FcStrSet *set = FcLangSetGetLangs (b); + FcStrList *sl = FcStrListCreate (set); FcChar8 *str; + FcStrSetDestroy (set); while ((str = FcStrListNext (sl))) { func (langset, str); diff --git a/fontconfig/src/fcstr.c b/fontconfig/src/fcstr.c index 414d6dd6b..4d11a4c65 100644 --- a/fontconfig/src/fcstr.c +++ b/fontconfig/src/fcstr.c @@ -30,6 +30,7 @@ #include #endif + /* Objects MT-safe for readonly access. */ FcChar8 * @@ -863,6 +864,64 @@ FcStrUsesHome (const FcChar8 *s) return *s == '~'; } +FcChar8 * +FcStrBuildFilename (const FcChar8 *path, + ...) +{ + va_list ap; + FcStrSet *sset = FcStrSetCreate (); + FcStrList *list; + FcChar8 *s, *ret = NULL, *p; + size_t len = 0; + + if (!sset || !path) + return NULL; + + if (!FcStrSetAdd (sset, path)) + goto bail0; + + va_start (ap, path); + while (1) + { + s = (FcChar8 *)va_arg (ap, FcChar8 *); + if (!s) + break; + if (!FcStrSetAdd (sset, s)) + goto bail1; + } + list = FcStrListCreate (sset); + while ((s = FcStrListNext (list))) + { + len += strlen ((const char *)s) + 1; + } + list->n = 0; + ret = malloc (sizeof (FcChar8) * (len + 1)); + if (!ret) + goto bail2; + p = ret; + while ((s = FcStrListNext (list))) + { + if (p != ret) + { + p[0] = FC_DIR_SEPARATOR; + p++; + } + len = strlen ((const char *)s); + memcpy (p, s, len); + p += len; + } + *p = 0; + +bail2: + FcStrListDone (list); +bail1: + va_end (ap); +bail0: + FcStrSetDestroy (sset); + + return ret; +} + FcChar8 * FcStrCopyFilename (const FcChar8 *s) { @@ -1052,8 +1111,7 @@ FcStrCanonFilename (const FcChar8 *s) FcChar8 cwd[FC_MAX_FILE_LEN + 2]; if (getcwd ((char *) cwd, FC_MAX_FILE_LEN) == NULL) return NULL; - strcat ((char *) cwd, "/"); - full = FcStrPlus (cwd, s); + full = FcStrBuildFilename (cwd, s, NULL); file = FcStrCanonAbsoluteFilename (full); FcStrFree (full); return file; diff --git a/libfontenc/src/encparse.c b/libfontenc/src/encparse.c index cbcac8023..ee18b3f96 100644 --- a/libfontenc/src/encparse.c +++ b/libfontenc/src/encparse.c @@ -426,7 +426,7 @@ setCode(unsigned from, unsigned to, unsigned row_size, } } else if(*encsize <= index) { *encsize = 0x10000; - if((newenc = realloc(enc, *encsize))==NULL) + if((newenc = realloc(*enc, (*encsize) * sizeof(unsigned short)))==NULL) return 1; *enc = newenc; } diff --git a/mesalib/bin/get-pick-list.sh b/mesalib/bin/get-pick-list.sh index a141afe26..d3ac511c1 100644 --- a/mesalib/bin/get-pick-list.sh +++ b/mesalib/bin/get-pick-list.sh @@ -8,7 +8,7 @@ git log --reverse --grep="cherry picked from commit" origin/master..HEAD |\ sed -e 's/^[[:space:]]*(cherry picked from commit[[:space:]]*//' -e 's/)//' > already_picked # Grep for commits that were marked as a candidate for the stable tree. -git log --reverse --pretty=%H -i --grep='^[[:space:]]*NOTE: This is a candidate' HEAD..origin/master |\ +git log --reverse --pretty=%H -i --grep='^[[:space:]]*NOTE: .*[Cc]andidate' HEAD..origin/master |\ while read sha do # Check to see whether the patch is on the ignore list. diff --git a/mesalib/configure.ac b/mesalib/configure.ac index 5f95a78d2..ea56a044d 100644 --- a/mesalib/configure.ac +++ b/mesalib/configure.ac @@ -832,20 +832,6 @@ if test "x$enable_dri" = xyes; then fi fi -dnl Find out if X is available. -PKG_CHECK_MODULES([X11], [x11], [no_x=no], [no_x=yes]) - -dnl Try to tell the user that the --x-* options are only used when -dnl pkg-config is not available. This must be right after AC_PATH_XTRA. -m4_divert_once([HELP_BEGIN], -[These options are only used when the X libraries cannot be found by the -pkg-config utility.]) - -dnl We need X for xlib and dri, so bomb now if it's not found -if test "x$enable_glx" = xyes -a "x$no_x" = xyes; then - AC_MSG_ERROR([X11 development libraries needed for GLX]) -fi - dnl Direct rendering or just indirect rendering case "$host_os" in gnu*) @@ -1095,7 +1081,7 @@ if test "x$enable_dri" = xyes; then fi # if we are building any dri driver other than swrast or using the dri state tracker ... - if test -n "$DRI_DIRS" -a x"$DRI_DIRS" != xswrast || test "x$enable_dri" = xyes; then + if test -n "$DRI_DIRS" -a x"$DRI_DIRS" != xswrast -a "x$enable_dri" = xyes; then # ... libdrm is required if test "x$have_libdrm" != xyes; then AC_MSG_ERROR([DRI drivers requires libdrm >= $LIBDRM_REQUIRED]) diff --git a/mesalib/scons/llvm.py b/mesalib/scons/llvm.py index 7f00c6ce1..7cd609c20 100644 --- a/mesalib/scons/llvm.py +++ b/mesalib/scons/llvm.py @@ -174,7 +174,7 @@ def generate(env): env.Append(LINKFLAGS = ['/nodefaultlib:LIBCMT']) else: if not env.Detect('llvm-config'): - print 'scons: llvm-config script not found' % llvm_version + print 'scons: llvm-config script not found' return llvm_version = env.backtick('llvm-config --version').rstrip() diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c index e37be4e0a..a85183644 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.c +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c @@ -924,6 +924,11 @@ void util_blitter_cache_all_shaders(struct blitter_context *blitter) (target == PIPE_TEXTURE_CUBE_ARRAY)) continue; + if (i > 1 && + (target != PIPE_TEXTURE_2D && + target != PIPE_TEXTURE_2D_ARRAY)) + continue; + blitter_get_fs_texfetch_col(ctx, target, i); blitter_get_fs_texfetch_depth(ctx, target, i); if (ctx->has_stencil_export) { diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 9d7de3381..56082f761 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -308,9 +308,10 @@ _mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target) 'id' is the implementation-defined ID of the given message. */ static void _mesa_glsl_msg(const YYLTYPE *locp, _mesa_glsl_parse_state *state, - GLenum type, GLuint id, const char *fmt, va_list ap) + GLenum type, const char *fmt, va_list ap) { - bool error = (type == GL_DEBUG_TYPE_ERROR_ARB); + bool error = (type == MESA_DEBUG_TYPE_ERROR); + GLuint msg_id = 0; assert(state->info_log != NULL); @@ -326,9 +327,9 @@ _mesa_glsl_msg(const YYLTYPE *locp, _mesa_glsl_parse_state *state, const char *const msg = &state->info_log[msg_offset]; struct gl_context *ctx = state->ctx; + /* Report the error via GL_ARB_debug_output. */ - if (error) - _mesa_shader_debug(ctx, type, id, msg, strlen(msg)); + _mesa_shader_debug(ctx, type, &msg_id, msg, strlen(msg)); ralloc_strcat(&state->info_log, "\n"); } @@ -338,12 +339,11 @@ _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state, const char *fmt, ...) { va_list ap; - GLenum type = GL_DEBUG_TYPE_ERROR_ARB; state->error = true; va_start(ap, fmt); - _mesa_glsl_msg(locp, state, type, SHADER_ERROR_UNKNOWN, fmt, ap); + _mesa_glsl_msg(locp, state, MESA_DEBUG_TYPE_ERROR, fmt, ap); va_end(ap); } @@ -353,10 +353,9 @@ _mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state, const char *fmt, ...) { va_list ap; - GLenum type = GL_DEBUG_TYPE_OTHER_ARB; va_start(ap, fmt); - _mesa_glsl_msg(locp, state, type, 0, fmt, ap); + _mesa_glsl_msg(locp, state, MESA_DEBUG_TYPE_OTHER, fmt, ap); va_end(ap); } diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp index 8c0091e84..b5ef768bd 100644 --- a/mesalib/src/glsl/standalone_scaffolding.cpp +++ b/mesalib/src/glsl/standalone_scaffolding.cpp @@ -60,7 +60,7 @@ _mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr, } void -_mesa_shader_debug(struct gl_context *, GLenum, GLuint, +_mesa_shader_debug(struct gl_context *, GLenum, GLuint *id, const char *, int) { } diff --git a/mesalib/src/glsl/standalone_scaffolding.h b/mesalib/src/glsl/standalone_scaffolding.h index 096b2f114..0a2cde8a3 100644 --- a/mesalib/src/glsl/standalone_scaffolding.h +++ b/mesalib/src/glsl/standalone_scaffolding.h @@ -44,7 +44,7 @@ extern "C" struct gl_shader * _mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type); extern "C" void -_mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint id, +_mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id, const char *msg, int len); /** diff --git a/mesalib/src/mesa/main/errors.c b/mesalib/src/mesa/main/errors.c index 0c5e36d5a..97f1b8a03 100644 --- a/mesalib/src/mesa/main/errors.c +++ b/mesalib/src/mesa/main/errors.c @@ -29,19 +29,20 @@ #include "errors.h" - +#include "enums.h" #include "imports.h" #include "context.h" #include "dispatch.h" #include "hash.h" #include "mtypes.h" #include "version.h" +#include "hash_table.h" +#include "glapi/glthread.h" +_glthread_DECLARE_STATIC_MUTEX(DynamicIDMutex); +static GLuint NextDynamicID = 1; -#define MAXSTRING MAX_DEBUG_MESSAGE_LENGTH - - -struct gl_client_severity +struct gl_debug_severity { struct simple_node link; GLuint ID; @@ -49,82 +50,89 @@ struct gl_client_severity static char out_of_memory[] = "Debugging error: out of memory"; -#define enum_is(e, kind1, kind2) \ - ((e) == GL_DEBUG_##kind1##_##kind2##_ARB || (e) == GL_DONT_CARE) -#define severity_is(sev, kind) enum_is(sev, SEVERITY, kind) -#define source_is(s, kind) enum_is(s, SOURCE, kind) -#define type_is(t, kind) enum_is(t, TYPE, kind) - -/* Prevent define collision on Windows */ -#undef ERROR - -enum { - SOURCE_APPLICATION, - SOURCE_THIRD_PARTY, - - SOURCE_COUNT, - SOURCE_ANY = -1 +static const GLenum debug_source_enums[] = { + GL_DEBUG_SOURCE_API, + GL_DEBUG_SOURCE_WINDOW_SYSTEM, + GL_DEBUG_SOURCE_SHADER_COMPILER, + GL_DEBUG_SOURCE_THIRD_PARTY, + GL_DEBUG_SOURCE_APPLICATION, + GL_DEBUG_SOURCE_OTHER, }; -enum { - TYPE_ERROR, - TYPE_DEPRECATED, - TYPE_UNDEFINED, - TYPE_PORTABILITY, - TYPE_PERFORMANCE, - TYPE_OTHER, - - TYPE_COUNT, - TYPE_ANY = -1 +static const GLenum debug_type_enums[] = { + GL_DEBUG_TYPE_ERROR, + GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, + GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, + GL_DEBUG_TYPE_PORTABILITY, + GL_DEBUG_TYPE_PERFORMANCE, + GL_DEBUG_TYPE_OTHER, }; -enum { - SEVERITY_LOW, - SEVERITY_MEDIUM, - SEVERITY_HIGH, - - SEVERITY_COUNT, - SEVERITY_ANY = -1 +static const GLenum debug_severity_enums[] = { + GL_DEBUG_SEVERITY_LOW, + GL_DEBUG_SEVERITY_MEDIUM, + GL_DEBUG_SEVERITY_HIGH, }; -static int -enum_to_index(GLenum e) +static enum mesa_debug_source +gl_enum_to_debug_source(GLenum e) { - switch (e) { - case GL_DEBUG_SOURCE_APPLICATION_ARB: - return (int)SOURCE_APPLICATION; - case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: - return (int)SOURCE_THIRD_PARTY; + int i; - case GL_DEBUG_TYPE_ERROR_ARB: - return (int)TYPE_ERROR; - case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: - return (int)TYPE_DEPRECATED; - case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: - return (int)TYPE_UNDEFINED; - case GL_DEBUG_TYPE_PERFORMANCE_ARB: - return (int)TYPE_PERFORMANCE; - case GL_DEBUG_TYPE_PORTABILITY_ARB: - return (int)TYPE_PORTABILITY; - case GL_DEBUG_TYPE_OTHER_ARB: - return (int)TYPE_OTHER; + for (i = 0; i < Elements(debug_source_enums); i++) { + if (debug_source_enums[i] == e) + break; + } + return i; +} - case GL_DEBUG_SEVERITY_LOW_ARB: - return (int)SEVERITY_LOW; - case GL_DEBUG_SEVERITY_MEDIUM_ARB: - return (int)SEVERITY_MEDIUM; - case GL_DEBUG_SEVERITY_HIGH_ARB: - return (int)SEVERITY_HIGH; +static enum mesa_debug_type +gl_enum_to_debug_type(GLenum e) +{ + int i; - case GL_DONT_CARE: - return (int)TYPE_ANY; + for (i = 0; i < Elements(debug_type_enums); i++) { + if (debug_type_enums[i] == e) + break; + } + return i; +} - default: - assert(0 && "unreachable"); - return -2; - }; +static enum mesa_debug_severity +gl_enum_to_debug_severity(GLenum e) +{ + int i; + + for (i = 0; i < Elements(debug_severity_enums); i++) { + if (debug_severity_enums[i] == e) + break; + } + return i; } +/** + * Handles generating a GL_ARB_debug_output message ID generated by the GL or + * GLSL compiler. + * + * The GL API has this "ID" mechanism, where the intention is to allow a + * client to filter in/out messages based on source, type, and ID. Of course, + * building a giant enum list of all debug output messages that Mesa might + * generate is ridiculous, so instead we have our caller pass us a pointer to + * static storage where the ID should get stored. This ID will be shared + * across all contexts for that message (which seems like a desirable + * property, even if it's not expected by the spec), but note that it won't be + * the same between executions if messages aren't generated in the same order. + */ +static void +debug_get_id(GLuint *id) +{ + if (!(*id)) { + _glthread_LOCK_MUTEX(DynamicIDMutex); + if (!(*id)) + *id = NextDynamicID++; + _glthread_UNLOCK_MUTEX(DynamicIDMutex); + } +} /* * We store a bitfield in the hash table, with five possible values total. @@ -168,17 +176,17 @@ enum { }; /** - * Returns the state of the given message ID in a client-controlled - * namespace. - * 'source', 'type', and 'severity' are array indices like TYPE_ERROR, - * not GL enums. + * Returns the state of the given message source/type/ID tuple. */ static GLboolean -get_message_state(struct gl_context *ctx, int source, int type, - GLuint id, int severity) +should_log(struct gl_context *ctx, + enum mesa_debug_source source, + enum mesa_debug_type type, + GLuint id, + enum mesa_debug_severity severity) { - struct gl_client_namespace *nspace = - &ctx->Debug.ClientIDs.Namespaces[source][type]; + struct gl_debug_namespace *nspace = + &ctx->Debug.Namespaces[source][type]; uintptr_t state; /* In addition to not being able to store zero as a value, HashTable also @@ -191,10 +199,10 @@ get_message_state(struct gl_context *ctx, int source, int type, /* Only do this once for each ID. This makes sure the ID exists in, at most, one list, and does not pointlessly appear multiple times. */ if (!(state & KNOWN_SEVERITY)) { - struct gl_client_severity *entry; + struct gl_debug_severity *entry; if (state == NOT_FOUND) { - if (ctx->Debug.ClientIDs.Defaults[severity][source][type]) + if (ctx->Debug.Defaults[severity][source][type]) state = ENABLED; else state = DISABLED; @@ -220,16 +228,16 @@ out: } /** - * Sets the state of the given message ID in a client-controlled - * namespace. - * 'source' and 'type' are array indices like TYPE_ERROR, not GL enums. + * Sets the state of the given message source/type/ID tuple. */ static void -set_message_state(struct gl_context *ctx, int source, int type, +set_message_state(struct gl_context *ctx, + enum mesa_debug_source source, + enum mesa_debug_type type, GLuint id, GLboolean enabled) { - struct gl_client_namespace *nspace = - &ctx->Debug.ClientIDs.Namespaces[source][type]; + struct gl_debug_namespace *nspace = + &ctx->Debug.Namespaces[source][type]; uintptr_t state; /* In addition to not being able to store zero as a value, HashTable also @@ -254,41 +262,6 @@ set_message_state(struct gl_context *ctx, int source, int type, nspace->ZeroID = state; } -/** - * Whether a debugging message should be logged or not. - * For implementation-controlled namespaces, we keep an array - * of booleans per namespace, per context, recording whether - * each individual message is enabled or not. The message ID - * is an index into the namespace's array. - */ -static GLboolean -should_log(struct gl_context *ctx, GLenum source, GLenum type, - GLuint id, GLenum severity) -{ - if (source == GL_DEBUG_SOURCE_APPLICATION_ARB || - source == GL_DEBUG_SOURCE_THIRD_PARTY_ARB) { - int s, t, sev; - s = enum_to_index(source); - t = enum_to_index(type); - sev = enum_to_index(severity); - - return get_message_state(ctx, s, t, sev, id); - } - - if (type_is(type, ERROR)) { - if (source_is(source, API)) - return ctx->Debug.ApiErrors[id]; - if (source_is(source, WINDOW_SYSTEM)) - return ctx->Debug.WinsysErrors[id]; - if (source_is(source, SHADER_COMPILER)) - return ctx->Debug.ShaderErrors[id]; - if (source_is(source, OTHER)) - return ctx->Debug.OtherErrors[id]; - } - - return (severity != GL_DEBUG_SEVERITY_LOW_ARB); -} - /** * 'buf' is not necessarily a null-terminated string. When logging, copy * 'len' characters from it, store them in a new, null-terminated string, @@ -296,8 +269,9 @@ should_log(struct gl_context *ctx, GLenum source, GLenum type, * the null terminator this time. */ static void -_mesa_log_msg(struct gl_context *ctx, GLenum source, GLenum type, - GLuint id, GLenum severity, GLint len, const char *buf) +_mesa_log_msg(struct gl_context *ctx, enum mesa_debug_source source, + enum mesa_debug_type type, GLuint id, + enum mesa_debug_severity severity, GLint len, const char *buf) { GLint nextEmpty; struct gl_debug_msg *emptySlot; @@ -308,7 +282,10 @@ _mesa_log_msg(struct gl_context *ctx, GLenum source, GLenum type, return; if (ctx->Debug.Callback) { - ctx->Debug.Callback(source, type, id, severity, + ctx->Debug.Callback(debug_source_enums[source], + debug_type_enums[type], + id, + debug_severity_enums[severity], len, buf, ctx->Debug.CallbackData); return; } @@ -333,13 +310,16 @@ _mesa_log_msg(struct gl_context *ctx, GLenum source, GLenum type, emptySlot->id = id; emptySlot->severity = severity; } else { + static GLuint oom_msg_id = 0; + debug_get_id(&oom_msg_id); + /* malloc failed! */ emptySlot->message = out_of_memory; emptySlot->length = strlen(out_of_memory)+1; - emptySlot->source = GL_DEBUG_SOURCE_OTHER_ARB; - emptySlot->type = GL_DEBUG_TYPE_ERROR_ARB; - emptySlot->id = OTHER_ERROR_OUT_OF_MEMORY; - emptySlot->severity = GL_DEBUG_SEVERITY_HIGH_ARB; + emptySlot->source = MESA_DEBUG_SOURCE_OTHER; + emptySlot->type = MESA_DEBUG_TYPE_ERROR; + emptySlot->id = oom_msg_id; + emptySlot->severity = MESA_DEBUG_SEVERITY_HIGH; } if (ctx->Debug.NumMessages == 0) @@ -377,11 +357,11 @@ _mesa_get_msg(struct gl_context *ctx, GLenum *source, GLenum *type, return 0; if (severity) - *severity = msg->severity; + *severity = debug_severity_enums[msg->severity]; if (source) - *source = msg->source; + *source = debug_source_enums[msg->source]; if (type) - *type = msg->type; + *type = debug_type_enums[msg->type]; if (id) *id = msg->id; @@ -498,7 +478,10 @@ _mesa_DebugMessageInsertARB(GLenum source, GLenum type, GLuint id, return; } - _mesa_log_msg(ctx, source, type, id, severity, length, buf); + _mesa_log_msg(ctx, + gl_enum_to_debug_source(source), + gl_enum_to_debug_type(type), id, + gl_enum_to_debug_severity(severity), length, buf); } GLuint GLAPIENTRY @@ -547,42 +530,9 @@ _mesa_GetDebugMessageLogARB(GLuint count, GLsizei logSize, GLenum* sources, } /** - * 'array' is an array representing a particular debugging-message namespace. - * I.e., the set of all API errors, or the set of all Shader Compiler errors. - * 'size' is the size of 'array'. 'count' is the size of 'ids', an array - * of indices into 'array'. All the elements of 'array' at the indices - * listed in 'ids' will be overwritten with the value of 'enabled'. - * - * If 'count' is zero, all elements in 'array' are overwritten with the - * value of 'enabled'. - */ -static void -control_messages(GLboolean *array, GLuint size, - GLsizei count, const GLuint *ids, GLboolean enabled) -{ - GLsizei i; - - if (!count) { - GLuint id; - for (id = 0; id < size; id++) { - array[id] = enabled; - } - return; - } - - for (i = 0; i < count; i++) { - if (ids[i] >= size) { - /* XXX: The spec doesn't say what to do with a non-existent ID. */ - continue; - } - array[ids[i]] = enabled; - } -} - -/** - * Set the state of all message IDs found in the given intersection - * of 'source', 'type', and 'severity'. Note that all three of these - * parameters are array indices, not the corresponding GL enums. + * Set the state of all message IDs found in the given intersection of + * 'source', 'type', and 'severity'. The _COUNT enum can be used for + * GL_DONT_CARE (include all messages in the class). * * This requires both setting the state of all previously seen message * IDs in the hash table, and setting the default state for all @@ -591,29 +541,31 @@ control_messages(GLboolean *array, GLuint size, * impacted as if they were already known. */ static void -control_app_messages_by_group(struct gl_context *ctx, int source, int type, - int severity, GLboolean enabled) +control_messages(struct gl_context *ctx, + enum mesa_debug_source source, + enum mesa_debug_type type, + enum mesa_debug_severity severity, + GLboolean enabled) { - struct gl_client_debug *ClientIDs = &ctx->Debug.ClientIDs; int s, t, sev, smax, tmax, sevmax; - if (source == SOURCE_ANY) { + if (source == MESA_DEBUG_SOURCE_COUNT) { source = 0; - smax = SOURCE_COUNT; + smax = MESA_DEBUG_SOURCE_COUNT; } else { smax = source+1; } - if (type == TYPE_ANY) { + if (type == MESA_DEBUG_TYPE_COUNT) { type = 0; - tmax = TYPE_COUNT; + tmax = MESA_DEBUG_TYPE_COUNT; } else { tmax = type+1; } - if (severity == SEVERITY_ANY) { + if (severity == MESA_DEBUG_SEVERITY_COUNT) { severity = 0; - sevmax = SEVERITY_COUNT; + sevmax = MESA_DEBUG_SEVERITY_COUNT; } else { sevmax = severity+1; } @@ -622,14 +574,14 @@ control_app_messages_by_group(struct gl_context *ctx, int source, int type, for (s = source; s < smax; s++) for (t = type; t < tmax; t++) { struct simple_node *node; - struct gl_client_severity *entry; + struct gl_debug_severity *entry; /* change the default for IDs we've never seen before. */ - ClientIDs->Defaults[sev][s][t] = enabled; + ctx->Debug.Defaults[sev][s][t] = enabled; /* Now change the state of IDs we *have* seen... */ - foreach(node, &ClientIDs->Namespaces[s][t].Severity[sev]) { - entry = (struct gl_client_severity *)node; + foreach(node, &ctx->Debug.Namespaces[s][t].Severity[sev]) { + entry = (struct gl_debug_severity *)node; set_message_state(ctx, s, t, entry->ID, enabled); } } @@ -652,16 +604,15 @@ control_app_messages(struct gl_context *ctx, GLenum esource, GLenum etype, GLenum eseverity, GLsizei count, const GLuint *ids, GLboolean enabled) { - int source, type, severity; GLsizei i; - - source = enum_to_index(esource); - type = enum_to_index(etype); - severity = enum_to_index(eseverity); + enum mesa_debug_source source = gl_enum_to_debug_source(esource); + enum mesa_debug_type type = gl_enum_to_debug_type(etype); + enum mesa_debug_severity severity = gl_enum_to_debug_severity(eseverity); if (count) - assert(severity == SEVERITY_ANY && type != TYPE_ANY - && source != SOURCE_ANY); + assert(severity == MESA_DEBUG_SEVERITY_COUNT + && type != MESA_DEBUG_TYPE_COUNT + && source != MESA_DEBUG_SOURCE_COUNT); for (i = 0; i < count; i++) set_message_state(ctx, source, type, ids[i], enabled); @@ -669,14 +620,18 @@ control_app_messages(struct gl_context *ctx, GLenum esource, GLenum etype, if (count) return; - control_app_messages_by_group(ctx, source, type, severity, enabled); + control_messages(ctx, source, type, severity, enabled); } void GLAPIENTRY -_mesa_DebugMessageControlARB(GLenum source, GLenum type, GLenum severity, +_mesa_DebugMessageControlARB(GLenum gl_source, GLenum gl_type, + GLenum gl_severity, GLsizei count, const GLuint *ids, GLboolean enabled) { + enum mesa_debug_source source; + enum mesa_debug_type type; + enum mesa_debug_severity severity; GET_CURRENT_CONTEXT(ctx); if (count < 0) { @@ -685,36 +640,22 @@ _mesa_DebugMessageControlARB(GLenum source, GLenum type, GLenum severity, return; } - if (!validate_params(ctx, CONTROL, source, type, severity)) + if (!validate_params(ctx, CONTROL, gl_source, gl_type, gl_severity)) return; /* GL_INVALID_ENUM */ - if (count && (severity != GL_DONT_CARE || type == GL_DONT_CARE - || source == GL_DONT_CARE)) { + if (count && (gl_severity != GL_DONT_CARE || gl_type == GL_DONT_CARE + || gl_source == GL_DONT_CARE)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDebugMessageControlARB" "(When passing an array of ids, severity must be" " GL_DONT_CARE, and source and type must not be GL_DONT_CARE."); return; } - if (source_is(source, APPLICATION) || source_is(source, THIRD_PARTY)) - control_app_messages(ctx, source, type, severity, count, ids, enabled); - - if (severity_is(severity, HIGH)) { - if (type_is(type, ERROR)) { - if (source_is(source, API)) - control_messages(ctx->Debug.ApiErrors, API_ERROR_COUNT, - count, ids, enabled); - if (source_is(source, WINDOW_SYSTEM)) - control_messages(ctx->Debug.WinsysErrors, WINSYS_ERROR_COUNT, - count, ids, enabled); - if (source_is(source, SHADER_COMPILER)) - control_messages(ctx->Debug.ShaderErrors, SHADER_ERROR_COUNT, - count, ids, enabled); - if (source_is(source, OTHER)) - control_messages(ctx->Debug.OtherErrors, OTHER_ERROR_COUNT, - count, ids, enabled); - } - } + source = gl_enum_to_debug_severity(gl_source); + type = gl_enum_to_debug_severity(gl_type); + severity = gl_enum_to_debug_severity(gl_severity); + + control_app_messages(ctx, source, type, severity, count, ids, enabled); } void GLAPIENTRY @@ -729,7 +670,6 @@ void _mesa_init_errors(struct gl_context *ctx) { int s, t, sev; - struct gl_client_debug *ClientIDs = &ctx->Debug.ClientIDs; ctx->Debug.Callback = NULL; ctx->Debug.SyncOutput = GL_FALSE; @@ -739,44 +679,47 @@ _mesa_init_errors(struct gl_context *ctx) ctx->Debug.NextMsgLength = 0; /* Enable all the messages with severity HIGH or MEDIUM by default. */ - memset(ctx->Debug.ApiErrors, GL_TRUE, sizeof ctx->Debug.ApiErrors); - memset(ctx->Debug.WinsysErrors, GL_TRUE, sizeof ctx->Debug.WinsysErrors); - memset(ctx->Debug.ShaderErrors, GL_TRUE, sizeof ctx->Debug.ShaderErrors); - memset(ctx->Debug.OtherErrors, GL_TRUE, sizeof ctx->Debug.OtherErrors); - memset(ClientIDs->Defaults[SEVERITY_HIGH], GL_TRUE, - sizeof ClientIDs->Defaults[SEVERITY_HIGH]); - memset(ClientIDs->Defaults[SEVERITY_MEDIUM], GL_TRUE, - sizeof ClientIDs->Defaults[SEVERITY_MEDIUM]); - memset(ClientIDs->Defaults[SEVERITY_LOW], GL_FALSE, - sizeof ClientIDs->Defaults[SEVERITY_LOW]); - - /* Initialize state for filtering client-provided debug messages. */ - for (s = 0; s < SOURCE_COUNT; s++) - for (t = 0; t < TYPE_COUNT; t++) { - ClientIDs->Namespaces[s][t].IDs = _mesa_NewHashTable(); - assert(ClientIDs->Namespaces[s][t].IDs); - - for (sev = 0; sev < SEVERITY_COUNT; sev++) - make_empty_list(&ClientIDs->Namespaces[s][t].Severity[sev]); + memset(ctx->Debug.Defaults[MESA_DEBUG_SEVERITY_HIGH], GL_TRUE, + sizeof ctx->Debug.Defaults[MESA_DEBUG_SEVERITY_HIGH]); + memset(ctx->Debug.Defaults[MESA_DEBUG_SEVERITY_MEDIUM], GL_TRUE, + sizeof ctx->Debug.Defaults[MESA_DEBUG_SEVERITY_MEDIUM]); + memset(ctx->Debug.Defaults[MESA_DEBUG_SEVERITY_LOW], GL_FALSE, + sizeof ctx->Debug.Defaults[MESA_DEBUG_SEVERITY_LOW]); + + /* Initialize state for filtering known debug messages. */ + for (s = 0; s < MESA_DEBUG_SOURCE_COUNT; s++) + for (t = 0; t < MESA_DEBUG_TYPE_COUNT; t++) { + ctx->Debug.Namespaces[s][t].IDs = _mesa_NewHashTable(); + assert(ctx->Debug.Namespaces[s][t].IDs); + + for (sev = 0; sev < MESA_DEBUG_SEVERITY_COUNT; sev++) + make_empty_list(&ctx->Debug.Namespaces[s][t].Severity[sev]); } } +static void +do_nothing(GLuint key, void *data, void *userData) +{ +} + void _mesa_free_errors_data(struct gl_context *ctx) { - int s, t, sev; - struct gl_client_debug *ClientIDs = &ctx->Debug.ClientIDs; - - /* Tear down state for filtering client-provided debug messages. */ - for (s = 0; s < SOURCE_COUNT; s++) - for (t = 0; t < TYPE_COUNT; t++) { - _mesa_DeleteHashTable(ClientIDs->Namespaces[s][t].IDs); - for (sev = 0; sev < SEVERITY_COUNT; sev++) { + enum mesa_debug_type t; + enum mesa_debug_source s; + enum mesa_debug_severity sev; + + /* Tear down state for filtering debug messages. */ + for (s = 0; s < MESA_DEBUG_SOURCE_COUNT; s++) + for (t = 0; t < MESA_DEBUG_TYPE_COUNT; t++) { + _mesa_HashDeleteAll(ctx->Debug.Namespaces[s][t].IDs, do_nothing, NULL); + _mesa_DeleteHashTable(ctx->Debug.Namespaces[s][t].IDs); + for (sev = 0; sev < MESA_DEBUG_SEVERITY_COUNT; sev++) { struct simple_node *node, *tmp; - struct gl_client_severity *entry; + struct gl_debug_severity *entry; - foreach_s(node, tmp, &ClientIDs->Namespaces[s][t].Severity[sev]) { - entry = (struct gl_client_severity *)node; + foreach_s(node, tmp, &ctx->Debug.Namespaces[s][t].Severity[sev]) { + entry = (struct gl_debug_severity *)node; free(entry); } } @@ -838,38 +781,6 @@ output_if_debug(const char *prefixString, const char *outputString, } } - -/** - * Return string version of GL error code. - */ -static const char * -error_string( GLenum error ) -{ - switch (error) { - case GL_NO_ERROR: - return "GL_NO_ERROR"; - case GL_INVALID_VALUE: - return "GL_INVALID_VALUE"; - case GL_INVALID_ENUM: - return "GL_INVALID_ENUM"; - case GL_INVALID_OPERATION: - return "GL_INVALID_OPERATION"; - case GL_STACK_OVERFLOW: - return "GL_STACK_OVERFLOW"; - case GL_STACK_UNDERFLOW: - return "GL_STACK_UNDERFLOW"; - case GL_OUT_OF_MEMORY: - return "GL_OUT_OF_MEMORY"; - case GL_TABLE_TOO_LARGE: - return "GL_TABLE_TOO_LARGE"; - case GL_INVALID_FRAMEBUFFER_OPERATION_EXT: - return "GL_INVALID_FRAMEBUFFER_OPERATION"; - default: - return "unknown"; - } -} - - /** * When a new type of error is recorded, print a message describing * previous errors which were accumulated. @@ -877,12 +788,12 @@ error_string( GLenum error ) static void flush_delayed_errors( struct gl_context *ctx ) { - char s[MAXSTRING]; + char s[MAX_DEBUG_MESSAGE_LENGTH]; if (ctx->ErrorDebugCount) { - _mesa_snprintf(s, MAXSTRING, "%d similar %s errors", + _mesa_snprintf(s, MAX_DEBUG_MESSAGE_LENGTH, "%d similar %s errors", ctx->ErrorDebugCount, - error_string(ctx->ErrorValue)); + _mesa_lookup_enum_by_nr(ctx->ErrorValue)); output_if_debug("Mesa", s, GL_TRUE); @@ -901,10 +812,10 @@ flush_delayed_errors( struct gl_context *ctx ) void _mesa_warning( struct gl_context *ctx, const char *fmtString, ... ) { - char str[MAXSTRING]; + char str[MAX_DEBUG_MESSAGE_LENGTH]; va_list args; va_start( args, fmtString ); - (void) _mesa_vsnprintf( str, MAXSTRING, fmtString, args ); + (void) _mesa_vsnprintf( str, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args ); va_end( args ); if (ctx) @@ -925,7 +836,7 @@ void _mesa_problem( const struct gl_context *ctx, const char *fmtString, ... ) { va_list args; - char str[MAXSTRING]; + char str[MAX_DEBUG_MESSAGE_LENGTH]; static int numCalls = 0; (void) ctx; @@ -934,7 +845,7 @@ _mesa_problem( const struct gl_context *ctx, const char *fmtString, ... ) numCalls++; va_start( args, fmtString ); - _mesa_vsnprintf( str, MAXSTRING, fmtString, args ); + _mesa_vsnprintf( str, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args ); va_end( args ); fprintf(stderr, "Mesa %s implementation error: %s\n", MESA_VERSION_STRING, str); @@ -978,6 +889,27 @@ should_output(struct gl_context *ctx, GLenum error, const char *fmtString) return GL_FALSE; } +void +_mesa_gl_debug(struct gl_context *ctx, + GLuint *id, + enum mesa_debug_type type, + enum mesa_debug_severity severity, + const char *fmtString, ...) +{ + char s[MAX_DEBUG_MESSAGE_LENGTH]; + int len; + va_list args; + + debug_get_id(id); + + va_start(args, fmtString); + len = _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args); + va_end(args); + + _mesa_log_msg(ctx, MESA_DEBUG_SOURCE_API, type, + *id, severity, len, s); +} + /** * Record an OpenGL state error. These usually occur when the user @@ -995,29 +927,39 @@ void _mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... ) { GLboolean do_output, do_log; + /* Ideally this would be set up by the caller, so that we had proper IDs + * per different message. + */ + static GLuint error_msg_id = 0; + + debug_get_id(&error_msg_id); do_output = should_output(ctx, error, fmtString); - do_log = should_log(ctx, GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_ERROR_ARB, - API_ERROR_UNKNOWN, GL_DEBUG_SEVERITY_HIGH_ARB); + do_log = should_log(ctx, + MESA_DEBUG_SOURCE_API, + MESA_DEBUG_TYPE_ERROR, + error_msg_id, + MESA_DEBUG_SEVERITY_HIGH); if (do_output || do_log) { - char s[MAXSTRING], s2[MAXSTRING]; + char s[MAX_DEBUG_MESSAGE_LENGTH], s2[MAX_DEBUG_MESSAGE_LENGTH]; int len; va_list args; va_start(args, fmtString); - len = _mesa_vsnprintf(s, MAXSTRING, fmtString, args); + len = _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args); va_end(args); - if (len >= MAXSTRING) { + if (len >= MAX_DEBUG_MESSAGE_LENGTH) { /* Too long error message. Whoever calls _mesa_error should use * shorter strings. */ ASSERT(0); return; } - len = _mesa_snprintf(s2, MAXSTRING, "%s in %s", error_string(error), s); - if (len >= MAXSTRING) { + len = _mesa_snprintf(s2, MAX_DEBUG_MESSAGE_LENGTH, "%s in %s", + _mesa_lookup_enum_by_nr(error), s); + if (len >= MAX_DEBUG_MESSAGE_LENGTH) { /* Same as above. */ ASSERT(0); return; @@ -1030,8 +972,11 @@ _mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... ) /* Log the error via ARB_debug_output if needed.*/ if (do_log) { - _mesa_log_msg(ctx, GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_ERROR_ARB, - API_ERROR_UNKNOWN, GL_DEBUG_SEVERITY_HIGH_ARB, len, s2); + _mesa_log_msg(ctx, + MESA_DEBUG_SOURCE_API, + MESA_DEBUG_TYPE_ERROR, + error_msg_id, + MESA_DEBUG_SEVERITY_HIGH, len, s2); } } @@ -1051,10 +996,10 @@ void _mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) { #ifdef DEBUG - char s[MAXSTRING]; + char s[MAX_DEBUG_MESSAGE_LENGTH]; va_list args; va_start(args, fmtString); - _mesa_vsnprintf(s, MAXSTRING, fmtString, args); + _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args); va_end(args); output_if_debug("Mesa", s, GL_FALSE); #endif /* DEBUG */ @@ -1073,27 +1018,13 @@ _mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) * \param len The length of 'msg'. If negative, 'msg' must be null-terminated. */ void -_mesa_shader_debug( struct gl_context *ctx, GLenum type, GLuint id, +_mesa_shader_debug( struct gl_context *ctx, GLenum type, GLuint *id, const char *msg, int len ) { - GLenum source = GL_DEBUG_SOURCE_SHADER_COMPILER_ARB, - severity; + enum mesa_debug_source source = MESA_DEBUG_SOURCE_SHADER_COMPILER; + enum mesa_debug_severity severity = MESA_DEBUG_SEVERITY_HIGH; - switch (type) { - case GL_DEBUG_TYPE_ERROR_ARB: - assert(id < SHADER_ERROR_COUNT); - severity = GL_DEBUG_SEVERITY_HIGH_ARB; - break; - case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: - case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: - case GL_DEBUG_TYPE_PORTABILITY_ARB: - case GL_DEBUG_TYPE_PERFORMANCE_ARB: - case GL_DEBUG_TYPE_OTHER_ARB: - assert(0 && "other categories not implemented yet"); - default: - _mesa_problem(ctx, "bad enum in _mesa_shader_debug()"); - return; - } + debug_get_id(id); if (len < 0) len = strlen(msg); @@ -1102,7 +1033,7 @@ _mesa_shader_debug( struct gl_context *ctx, GLenum type, GLuint id, if (len >= MAX_DEBUG_MESSAGE_LENGTH) len = MAX_DEBUG_MESSAGE_LENGTH - 1; - _mesa_log_msg(ctx, source, type, id, severity, len, msg); + _mesa_log_msg(ctx, source, type, *id, severity, len, msg); } /*@}*/ diff --git a/mesalib/src/mesa/main/errors.h b/mesalib/src/mesa/main/errors.h index c92ee0a6e..7d8be5aca 100644 --- a/mesalib/src/mesa/main/errors.h +++ b/mesalib/src/mesa/main/errors.h @@ -44,8 +44,9 @@ extern "C" { #endif +#include "mtypes.h" + struct _glapi_table; -struct gl_context; extern void _mesa_init_errors( struct gl_context *ctx ); @@ -66,7 +67,15 @@ extern void _mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) PRINTFLIKE(2, 3); extern void -_mesa_shader_debug( struct gl_context *ctx, GLenum type, GLuint id, const char *msg, int len ); +_mesa_gl_debug(struct gl_context *ctx, + GLuint *id, + enum mesa_debug_type type, + enum mesa_debug_severity severity, + const char *fmtString, ...) PRINTFLIKE(5, 6); + +extern void +_mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id, + const char *msg, int len); void GLAPIENTRY _mesa_DebugMessageInsertARB(GLenum source, GLenum type, GLuint id, diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py index 5022ddc40..7d4f7e2a4 100644 --- a/mesalib/src/mesa/main/get_hash_params.py +++ b/mesalib/src/mesa/main/get_hash_params.py @@ -412,7 +412,7 @@ descriptor=[ [ "DEPTH_SCALE", "CONTEXT_FLOAT(Pixel.DepthScale), NO_EXTRA" ], [ "DOUBLEBUFFER", "BUFFER_INT(Visual.doubleBufferMode), NO_EXTRA" ], [ "DRAW_BUFFER", "BUFFER_ENUM(ColorDrawBuffer[0]), NO_EXTRA" ], - [ "EDGE_FLAG", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ], + [ "EDGE_FLAG", "LOC_CUSTOM, TYPE_BOOLEAN, 0, extra_flush_current" ], [ "FEEDBACK_BUFFER_SIZE", "CONTEXT_INT(Feedback.BufferSize), NO_EXTRA" ], [ "FEEDBACK_BUFFER_TYPE", "CONTEXT_ENUM(Feedback.Type), NO_EXTRA" ], [ "FOG_INDEX", "CONTEXT_FLOAT(Fog.Index), NO_EXTRA" ], diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index a80944c81..4f0951339 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -3368,52 +3368,61 @@ struct gl_dlist_state } Current; }; +/** @{ + * + * These are a mapping of the GL_ARB_debug_output enums to small enums + * suitable for use as an array index. + */ + +enum mesa_debug_source { + MESA_DEBUG_SOURCE_API, + MESA_DEBUG_SOURCE_WINDOW_SYSTEM, + MESA_DEBUG_SOURCE_SHADER_COMPILER, + MESA_DEBUG_SOURCE_THIRD_PARTY, + MESA_DEBUG_SOURCE_APPLICATION, + MESA_DEBUG_SOURCE_OTHER, + MESA_DEBUG_SOURCE_COUNT, +}; + +enum mesa_debug_type { + MESA_DEBUG_TYPE_ERROR, + MESA_DEBUG_TYPE_DEPRECATED, + MESA_DEBUG_TYPE_UNDEFINED, + MESA_DEBUG_TYPE_PORTABILITY, + MESA_DEBUG_TYPE_PERFORMANCE, + MESA_DEBUG_TYPE_OTHER, + MESA_DEBUG_TYPE_COUNT, +}; + +enum mesa_debug_severity { + MESA_DEBUG_SEVERITY_LOW, + MESA_DEBUG_SEVERITY_MEDIUM, + MESA_DEBUG_SEVERITY_HIGH, + MESA_DEBUG_SEVERITY_COUNT, +}; + +/** @} */ + /** * An error, warning, or other piece of debug information for an application * to consume via GL_ARB_debug_output. */ struct gl_debug_msg { - GLenum source; - GLenum type; + enum mesa_debug_source source; + enum mesa_debug_type type; GLuint id; - GLenum severity; + enum mesa_debug_severity severity; GLsizei length; GLcharARB *message; }; -typedef enum { - API_ERROR_UNKNOWN, - API_ERROR_COUNT -} gl_api_error; - -typedef enum { - WINSYS_ERROR_UNKNOWN, - WINSYS_ERROR_COUNT -} gl_winsys_error; - -typedef enum { - SHADER_ERROR_UNKNOWN, - SHADER_ERROR_COUNT -} gl_shader_error; - -typedef enum { - OTHER_ERROR_UNKNOWN, - OTHER_ERROR_OUT_OF_MEMORY, - OTHER_ERROR_COUNT -} gl_other_error; - -struct gl_client_namespace +struct gl_debug_namespace { struct _mesa_HashTable *IDs; unsigned ZeroID; /* a HashTable won't take zero, so store its state here */ - struct simple_node Severity[3]; /* lists of IDs in the hash table */ -}; - -struct gl_client_debug -{ - GLboolean Defaults[3][2][6]; /* severity, source, type */ - struct gl_client_namespace Namespaces[2][6]; /* source, type */ + /** lists of IDs in the hash table at each severity */ + struct simple_node Severity[MESA_DEBUG_SEVERITY_COUNT]; }; struct gl_debug_state @@ -3421,11 +3430,8 @@ struct gl_debug_state GLDEBUGPROCARB Callback; GLvoid *CallbackData; GLboolean SyncOutput; - GLboolean ApiErrors[API_ERROR_COUNT]; - GLboolean WinsysErrors[WINSYS_ERROR_COUNT]; - GLboolean ShaderErrors[SHADER_ERROR_COUNT]; - GLboolean OtherErrors[OTHER_ERROR_COUNT]; - struct gl_client_debug ClientIDs; + GLboolean Defaults[MESA_DEBUG_SEVERITY_COUNT][MESA_DEBUG_SOURCE_COUNT][MESA_DEBUG_TYPE_COUNT]; + struct gl_debug_namespace Namespaces[MESA_DEBUG_SOURCE_COUNT][MESA_DEBUG_TYPE_COUNT]; struct gl_debug_msg Log[MAX_DEBUG_LOGGED_MESSAGES]; GLint NumMessages; GLint NextMsg; diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 0dcf88ae4..9d4a17052 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -1416,6 +1416,7 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, return GL_FALSE; return GL_TRUE; + case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index c41b5833e..131ecb22a 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -2714,16 +2714,28 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) switch (ir->op) { case ir_tex: opcode = (is_cube_array && ir->shadow_comparitor) ? TGSI_OPCODE_TEX2 : TGSI_OPCODE_TEX; + if (ir->offset) { + ir->offset->accept(this); + offset = this->result; + } break; case ir_txb: opcode = is_cube_array ? TGSI_OPCODE_TXB2 : TGSI_OPCODE_TXB; ir->lod_info.bias->accept(this); lod_info = this->result; + if (ir->offset) { + ir->offset->accept(this); + offset = this->result; + } break; case ir_txl: opcode = is_cube_array ? TGSI_OPCODE_TXL2 : TGSI_OPCODE_TXL; ir->lod_info.lod->accept(this); lod_info = this->result; + if (ir->offset) { + ir->offset->accept(this); + offset = this->result; + } break; case ir_txd: opcode = TGSI_OPCODE_TXD; @@ -2731,6 +2743,10 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) dx = this->result; ir->lod_info.grad.dPdy->accept(this); dy = this->result; + if (ir->offset) { + ir->offset->accept(this); + offset = this->result; + } break; case ir_txs: opcode = TGSI_OPCODE_TXQ; @@ -2742,8 +2758,8 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) ir->lod_info.lod->accept(this); lod_info = this->result; if (ir->offset) { - ir->offset->accept(this); - offset = this->result; + ir->offset->accept(this); + offset = this->result; } break; case ir_txf_ms: diff --git a/xorg-server/Xi/xibarriers.c b/xorg-server/Xi/xibarriers.c index 7b7b83f1c..fccab8615 100644 --- a/xorg-server/Xi/xibarriers.c +++ b/xorg-server/Xi/xibarriers.c @@ -435,6 +435,7 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen, dir = barrier_get_direction(current_x, current_y, x, y); while (dir != 0) { + int new_sequence; struct PointerBarrierDevice *pbd; c = barrier_find_nearest(cs, master, dir, current_x, current_y, x, y); @@ -444,6 +445,8 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen, nearest = &c->barrier; pbd = GetBarrierDevice(c, master->id); + new_sequence = !pbd->hit; + pbd->seen = TRUE; pbd->hit = TRUE; @@ -466,7 +469,7 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen, ev.event_id = pbd->barrier_event_id; ev.barrierid = c->id; - ev.dt = ms - pbd->last_timestamp; + ev.dt = new_sequence ? 0 : ms - pbd->last_timestamp; ev.window = c->window; pbd->last_timestamp = ms; @@ -676,8 +679,8 @@ BarrierFreeBarrier(void *data, XID id) continue; ev.deviceid = dev->id; - ev.event_id = pbd->barrier_event_id, - ev.dt = ms - pbd->last_timestamp, + ev.event_id = pbd->barrier_event_id; + ev.dt = ms - pbd->last_timestamp; GetSpritePosition(dev, &root_x, &root_y); ev.root_x = root_x; diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 53335b1d1..6e1ff65c4 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -26,9 +26,9 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.60) -AC_INIT([xorg-server], 1.13.99.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) -RELEASE_DATE="2013-02-12" -RELEASE_NAME="Ginger Beer" +AC_INIT([xorg-server], 1.14.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) +RELEASE_DATE="2013-03-05" +RELEASE_NAME="Keemun Mao Feng" AC_CONFIG_SRCDIR([Makefile.am]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) diff --git a/xorg-server/hw/xfree86/common/xf86DPMS.c b/xorg-server/hw/xfree86/common/xf86DPMS.c index ef4a2c19b..3f1e142c7 100644 --- a/xorg-server/hw/xfree86/common/xf86DPMS.c +++ b/xorg-server/hw/xfree86/common/xf86DPMS.c @@ -130,6 +130,19 @@ DPMSClose(ScreenPtr pScreen) return pScreen->CloseScreen(pScreen); } +static void +DPMSSetScreen(ScrnInfoPtr pScrn, int level) +{ + ScreenPtr pScreen = xf86ScrnToScreen(pScrn); + DPMSPtr pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey); + + if (pDPMS && pScrn->DPMSSet && pDPMS->Enabled && pScrn->vtSema) { + xf86VGAarbiterLock(pScrn); + pScrn->DPMSSet(pScrn, level, 0); + xf86VGAarbiterUnlock(pScrn); + } +} + /* * DPMSSet -- * Device dependent DPMS mode setting hook. This is called whenever @@ -139,8 +152,6 @@ int DPMSSet(ClientPtr client, int level) { int rc, i; - DPMSPtr pDPMS; - ScrnInfoPtr pScrn; DPMSPowerLevel = level; @@ -155,17 +166,23 @@ DPMSSet(ClientPtr client, int level) /* For each screen, set the DPMS level */ for (i = 0; i < xf86NumScreens; i++) { - pScrn = xf86Screens[i]; - pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey); - if (pDPMS && pScrn->DPMSSet && pDPMS->Enabled && pScrn->vtSema) { - xf86VGAarbiterLock(pScrn); - pScrn->DPMSSet(pScrn, level, 0); - xf86VGAarbiterUnlock(pScrn); - } + DPMSSetScreen(xf86Screens[i], level); + } + for (i = 0; i < xf86NumGPUScreens; i++) { + DPMSSetScreen(xf86GPUScreens[i], level); } return Success; } +static Bool +DPMSSupportedOnScreen(ScrnInfoPtr pScrn) +{ + ScreenPtr pScreen = xf86ScrnToScreen(pScrn); + DPMSPtr pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey); + + return pDPMS && pScrn->DPMSSet; +} + /* * DPMSSupported -- * Return TRUE if any screen supports DPMS. @@ -174,8 +191,6 @@ Bool DPMSSupported(void) { int i; - DPMSPtr pDPMS; - ScrnInfoPtr pScrn; if (DPMSKey == NULL) { return FALSE; @@ -183,9 +198,11 @@ DPMSSupported(void) /* For each screen, check if DPMS is supported */ for (i = 0; i < xf86NumScreens; i++) { - pScrn = xf86Screens[i]; - pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey); - if (pDPMS && pScrn->DPMSSet) + if (DPMSSupportedOnScreen(xf86Screens[i])) + return TRUE; + } + for (i = 0; i < xf86NumGPUScreens; i++) { + if (DPMSSupportedOnScreen(xf86GPUScreens[i])) return TRUE; } return FALSE; -- cgit v1.2.3 From a2ce004b2966da2fe0249e72e2fb99255cef3092 Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 11 Mar 2013 09:17:45 +0100 Subject: fontconfig libX11 mesa pixman xserver xkeyboard-config git update 11 Mar 2013 xserver commit 5047810a4c20fab444b8c6eb146c55dcdb0d4219 xkeyboard-config commit 2ed85c1e936f7cd4a9540ace5c12b9fec60ee1fb libX11 commit 3996543c1b2919e97d61a5d70fe1ebd7cd76fc83 pixman commit aaae3d8eefa069098e9014822817ca1429fdea46 fontconfig commit bdf1581e3de5528f397f19bfd4ca9caaf9e7fe4a mesa commit b21a9d46e4be0c666327569f07b9cddeb4d42d38 --- fontconfig/src/fccfg.c | 2 +- fontconfig/src/fcmatch.c | 5 ++- libX11/configure.ac | 2 +- libX11/include/X11/Xlibint.h | 19 +++++++- libX11/man/XrmEnumerateDatabase.man | 2 + libX11/man/XrmGetFileDatabase.man | 2 + libX11/man/XrmGetResource.man | 2 + libX11/man/XrmInitialize.man | 2 + libX11/man/XrmMergeDatabases.man | 2 + libX11/man/XrmPutResource.man | 2 + libX11/man/XrmUniqueQuark.man | 2 + libX11/nls/Makefile.am | 4 +- libX11/nls/en_US.UTF-8/Compose.pre | 52 ++++++++++----------- libX11/nls/pt_BR.UTF-8/Compose.pre | 52 ++++++++++----------- libX11/src/GetFProp.c | 27 +++++------ libX11/src/PropAlloc.c | 7 +-- libX11/src/udcInf.c | 8 ++-- mesalib/configure.ac | 55 +++++++++++------------ mesalib/docs/viewperf.html | 29 ++++++++++++ mesalib/src/gallium/auxiliary/util/u_cpu_detect.c | 2 +- mesalib/src/mapi/glapi/gen/Makefile.am | 14 +++--- mesalib/src/mesa/main/get.c | 12 ++++- mesalib/src/mesa/main/glformats.c | 2 +- mesalib/src/mesa/main/samplerobj.c | 12 ++++- mesalib/src/mesa/main/samplerobj.h | 2 + mesalib/src/mesa/main/teximage.c | 2 +- mesalib/src/mesa/vbo/vbo_save_draw.c | 2 +- pixman/pixman/pixman-mmx.c | 2 - xorg-server/fb/wfbrename.h | 1 + xorg-server/xkeyboard-config/rules/base.o_s.part | 1 + xorg-server/xkeyboard-config/rules/base.xml.in | 6 +++ xorg-server/xkeyboard-config/symbols/altwin | 8 ++++ xorg-server/xkeyboard-config/symbols/cm | 6 +-- 33 files changed, 218 insertions(+), 130 deletions(-) diff --git a/fontconfig/src/fccfg.c b/fontconfig/src/fccfg.c index b762376ae..7da50b50f 100644 --- a/fontconfig/src/fccfg.c +++ b/fontconfig/src/fccfg.c @@ -429,7 +429,7 @@ retry: if (config == cfg) return FcTrue; - if (!config->fonts[FcSetSystem]) + if (config && !config->fonts[FcSetSystem]) if (!FcConfigBuildFonts (config)) return FcFalse; diff --git a/fontconfig/src/fcmatch.c b/fontconfig/src/fcmatch.c index 23f985a6c..7993b81de 100644 --- a/fontconfig/src/fcmatch.c +++ b/fontconfig/src/fcmatch.c @@ -532,7 +532,10 @@ FcFontRenderPrepare (FcConfig *config, { pe = &FcPatternElts(pat)[i]; fe = FcPatternObjectFindElt (font, pe->object); - if (!fe) + if (!fe && + pe->object != FC_FAMILYLANG_OBJECT && + pe->object != FC_STYLELANG_OBJECT && + pe->object != FC_FULLNAMELANG_OBJECT) { FcPatternObjectListAdd (new, pe->object, FcValueListDuplicate (FcPatternEltValues(pe)), diff --git a/libX11/configure.ac b/libX11/configure.ac index 4d7d411ae..7734219f4 100644 --- a/libX11/configure.ac +++ b/libX11/configure.ac @@ -1,7 +1,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) -AC_INIT([libX11], [1.5.0], +AC_INIT([libX11], [1.5.99.901], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libX11]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([src/config.h include/X11/XlibConf.h]) diff --git a/libX11/include/X11/Xlibint.h b/libX11/include/X11/Xlibint.h index 40965c449..06395b32e 100644 --- a/libX11/include/X11/Xlibint.h +++ b/libX11/include/X11/Xlibint.h @@ -486,6 +486,14 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); req = (xReq *) _XGetRequest(dpy, X_/**/name, SIZEOF(xReq)) #endif +/* + * MakeBigReq sets the CARD16 "req->length" to 0 and inserts a new CARD32 + * length, after req->length, before the data in the request. The new length + * includes the "n" extra 32-bit words. + * + * Do not use MakeBigReq if there is no data already in the request. + * req->length must already be >= 2. + */ #ifdef LONG64 #define MakeBigReq(req,n) \ { \ @@ -493,7 +501,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); CARD32 _BRlen = req->length - 1; \ req->length = 0; \ _BRdat = ((CARD32 *)req)[_BRlen]; \ - memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \ + memmove(((char *)req) + 8, ((char *)req) + 4, (_BRlen - 1) << 2); \ ((CARD32 *)req)[1] = _BRlen + n + 2; \ Data32(dpy, &_BRdat, 4); \ } @@ -504,12 +512,19 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); CARD32 _BRlen = req->length - 1; \ req->length = 0; \ _BRdat = ((CARD32 *)req)[_BRlen]; \ - memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \ + memmove(((char *)req) + 8, ((char *)req) + 4, (_BRlen - 1) << 2); \ ((CARD32 *)req)[1] = _BRlen + n + 2; \ Data32(dpy, &_BRdat, 4); \ } #endif +/* + * SetReqLen increases the count of 32-bit words in the request by "n", + * or by "badlen" if "n" is too large. + * + * Do not use SetReqLen if "req" does not already have data after the + * xReq header. req->length must already be >= 2. + */ #ifndef __clang_analyzer__ #define SetReqLen(req,n,badlen) \ if ((req->length + n) > (unsigned)65535) { \ diff --git a/libX11/man/XrmEnumerateDatabase.man b/libX11/man/XrmEnumerateDatabase.man index 843100635..03c0f30e2 100644 --- a/libX11/man/XrmEnumerateDatabase.man +++ b/libX11/man/XrmEnumerateDatabase.man @@ -84,6 +84,8 @@ .SH NAME XrmEnumerateDatabase \- enumerate resource database entries .SH SYNTAX +.HP +#include .TS lw(.5i) lw(2i) lw(2.5i). T{ diff --git a/libX11/man/XrmGetFileDatabase.man b/libX11/man/XrmGetFileDatabase.man index 3a8a6fa82..71ddd9f10 100644 --- a/libX11/man/XrmGetFileDatabase.man +++ b/libX11/man/XrmGetFileDatabase.man @@ -93,6 +93,8 @@ XrmGetFileDatabase, XrmPutFileDatabase, XrmGetStringDatabase, XrmLocaleOfDatabase, XrmGetDatabase, XrmSetDatabase, XrmDestroyDatabase \- retrieve and store resource databases .SH SYNTAX .HP +#include +.HP XrmDatabase XrmGetFileDatabase\^(\^char *\fIfilename\fP\^); .HP void XrmPutFileDatabase\^(\^XrmDatabase \fIdatabase\fP\^, char diff --git a/libX11/man/XrmGetResource.man b/libX11/man/XrmGetResource.man index 76ca9218c..ef2cf9ada 100644 --- a/libX11/man/XrmGetResource.man +++ b/libX11/man/XrmGetResource.man @@ -85,6 +85,8 @@ XrmGetResource, XrmQGetResource, XrmQGetSearchList, XrmQGetSearchResource \- retrieve database resources and search lists .SH SYNTAX .HP +#include +.HP Bool XrmGetResource\^(\^XrmDatabase \fIdatabase\fP\^, char *\fIstr_name\fP\^, char *\fIstr_class\fP\^, char **\fIstr_type_return\fP\^, XrmValue *\fIvalue_return\fP\^); diff --git a/libX11/man/XrmInitialize.man b/libX11/man/XrmInitialize.man index b8b549db6..3b3ddd78b 100644 --- a/libX11/man/XrmInitialize.man +++ b/libX11/man/XrmInitialize.man @@ -83,6 +83,8 @@ XrmInitialize, XrmParseCommand, XrmValue, XrmOptionKind, XrmOptionDescRec \- initialize the Resource Manager, Resource Manager structures, and parse the command line .SH SYNTAX .HP +#include +.HP void XrmInitialize\^(void\^); .HP void XrmParseCommand\^(\^XrmDatabase *\fIdatabase\fP\^, XrmOptionDescList diff --git a/libX11/man/XrmMergeDatabases.man b/libX11/man/XrmMergeDatabases.man index 57a6578ec..41b27bb63 100644 --- a/libX11/man/XrmMergeDatabases.man +++ b/libX11/man/XrmMergeDatabases.man @@ -83,6 +83,8 @@ XrmMergeDatabases, XrmCombineDatabase, XrmCombineFileDatabase \- merge resource databases .SH SYNTAX .HP +#include +.HP void XrmMergeDatabases(\^XrmDatabase \fIsource_db\fP, XrmDatabase *\fItarget_db\fP\^); .HP diff --git a/libX11/man/XrmPutResource.man b/libX11/man/XrmPutResource.man index 9f9d08884..fd644630d 100644 --- a/libX11/man/XrmPutResource.man +++ b/libX11/man/XrmPutResource.man @@ -83,6 +83,8 @@ XrmPutResource, XrmQPutResource, XrmPutStringResource, XrmQPutStringResource, XrmPutLineResource \- store database resources .SH SYNTAX .HP +#include +.HP void XrmPutResource\^(\^XrmDatabase *\fIdatabase\fP\^, char *\fIspecifier\fP\^, char *\fItype\fP\^, XrmValue *\fIvalue\fP\^); .HP diff --git a/libX11/man/XrmUniqueQuark.man b/libX11/man/XrmUniqueQuark.man index 383d26c50..93755f71b 100644 --- a/libX11/man/XrmUniqueQuark.man +++ b/libX11/man/XrmUniqueQuark.man @@ -83,6 +83,8 @@ XrmUniqueQuark, XrmStringToQuark, XrmPermStringToQuark, XrmQuarkToString, XrmStringToQuarkList, XrmStringToBindingQuarkList \- manipulate resource quarks .SH SYNOPSIS .HP +#include +.HP XrmQuark XrmUniqueQuark\^(void); .LP \&#define XrmStringToName(string) XrmStringToQuark(string) diff --git a/libX11/nls/Makefile.am b/libX11/nls/Makefile.am index 0eced4cd8..53eaacdf6 100644 --- a/libX11/nls/Makefile.am +++ b/libX11/nls/Makefile.am @@ -37,8 +37,8 @@ locale.dir: locale.dir.pre cat locale.dir.l2 locale.dir.l1 > locale.dir if HAVE_PERL -TESTS_ENVIRONMENT = $(PERL) -TESTS = $(srcdir)/compose-check.pl +LOG_COMPILER = $(PERL) +TESTS = compose-check.pl endif HAVE_PERL diff --git a/libX11/nls/en_US.UTF-8/Compose.pre b/libX11/nls/en_US.UTF-8/Compose.pre index de24dadec..8b45d920d 100644 --- a/libX11/nls/en_US.UTF-8/Compose.pre +++ b/libX11/nls/en_US.UTF-8/Compose.pre @@ -1481,30 +1481,30 @@ XCOMM Part 3 : "ǿ" U01FF # LATIN SMALL LETTER O WITH STROKE AND ACUTE : "ǿ" U01FF # LATIN SMALL LETTER O WITH STROKE AND ACUTE : "ǿ" U01FF # LATIN SMALL LETTER O WITH STROKE AND ACUTE - : "Ȁ" U0200 # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE - : "ȁ" U0201 # LATIN SMALL LETTER A WITH DOUBLE GRAVE - : "Ȃ" U0202 # LATIN CAPITAL LETTER A WITH INVERTED BREVE - : "ȃ" U0203 # LATIN SMALL LETTER A WITH INVERTED BREVE - : "Ȅ" U0204 # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE - : "ȅ" U0205 # LATIN SMALL LETTER E WITH DOUBLE GRAVE - : "Ȇ" U0206 # LATIN CAPITAL LETTER E WITH INVERTED BREVE - : "ȇ" U0207 # LATIN SMALL LETTER E WITH INVERTED BREVE - : "Ȉ" U0208 # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE - : "ȉ" U0209 # LATIN SMALL LETTER I WITH DOUBLE GRAVE - : "Ȋ" U020A # LATIN CAPITAL LETTER I WITH INVERTED BREVE - : "ȋ" U020B # LATIN SMALL LETTER I WITH INVERTED BREVE - : "Ȍ" U020C # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE - : "ȍ" U020D # LATIN SMALL LETTER O WITH DOUBLE GRAVE - : "Ȏ" U020E # LATIN CAPITAL LETTER O WITH INVERTED BREVE - : "ȏ" U020F # LATIN SMALL LETTER O WITH INVERTED BREVE - : "Ȑ" U0210 # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE - : "ȑ" U0211 # LATIN SMALL LETTER R WITH DOUBLE GRAVE - : "Ȓ" U0212 # LATIN CAPITAL LETTER R WITH INVERTED BREVE - : "ȓ" U0213 # LATIN SMALL LETTER R WITH INVERTED BREVE - : "Ȕ" U0214 # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE - : "ȕ" U0215 # LATIN SMALL LETTER U WITH DOUBLE GRAVE - : "Ȗ" U0216 # LATIN CAPITAL LETTER U WITH INVERTED BREVE - : "ȗ" U0217 # LATIN SMALL LETTER U WITH INVERTED BREVE + : "Ȁ" U0200 # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE + : "ȁ" U0201 # LATIN SMALL LETTER A WITH DOUBLE GRAVE + : "Ȃ" U0202 # LATIN CAPITAL LETTER A WITH INVERTED BREVE + : "ȃ" U0203 # LATIN SMALL LETTER A WITH INVERTED BREVE + : "Ȅ" U0204 # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE + : "ȅ" U0205 # LATIN SMALL LETTER E WITH DOUBLE GRAVE + : "Ȇ" U0206 # LATIN CAPITAL LETTER E WITH INVERTED BREVE + : "ȇ" U0207 # LATIN SMALL LETTER E WITH INVERTED BREVE + : "Ȉ" U0208 # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE + : "ȉ" U0209 # LATIN SMALL LETTER I WITH DOUBLE GRAVE + : "Ȋ" U020A # LATIN CAPITAL LETTER I WITH INVERTED BREVE + : "ȋ" U020B # LATIN SMALL LETTER I WITH INVERTED BREVE + : "Ȍ" U020C # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE + : "ȍ" U020D # LATIN SMALL LETTER O WITH DOUBLE GRAVE + : "Ȏ" U020E # LATIN CAPITAL LETTER O WITH INVERTED BREVE + : "ȏ" U020F # LATIN SMALL LETTER O WITH INVERTED BREVE + : "Ȑ" U0210 # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE + : "ȑ" U0211 # LATIN SMALL LETTER R WITH DOUBLE GRAVE + : "Ȓ" U0212 # LATIN CAPITAL LETTER R WITH INVERTED BREVE + : "ȓ" U0213 # LATIN SMALL LETTER R WITH INVERTED BREVE + : "Ȕ" U0214 # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE + : "ȕ" U0215 # LATIN SMALL LETTER U WITH DOUBLE GRAVE + : "Ȗ" U0216 # LATIN CAPITAL LETTER U WITH INVERTED BREVE + : "ȗ" U0217 # LATIN SMALL LETTER U WITH INVERTED BREVE : "Ȟ" U021E # LATIN CAPITAL LETTER H WITH CARON : "Ȟ" U021E # LATIN CAPITAL LETTER H WITH CARON : "ȟ" U021F # LATIN SMALL LETTER H WITH CARON @@ -1784,8 +1784,8 @@ XCOMM Part 3 : "ў" U045E # CYRILLIC SMALL LETTER SHORT U : "ў" U045E # CYRILLIC SMALL LETTER SHORT U : "ў" U045E # CYRILLIC SMALL LETTER SHORT U - : "Ѷ" U0476 # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT - : "ѷ" U0477 # CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT + : "Ѷ" U0476 # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT + : "ѷ" U0477 # CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT : "Ғ" U0492 # CYRILLIC CAPITAL LETTER GHE WITH STROKE : "Ғ" U0492 # CYRILLIC CAPITAL LETTER GHE WITH STROKE : "ғ" U0493 # CYRILLIC SMALL LETTER GHE WITH STROKE diff --git a/libX11/nls/pt_BR.UTF-8/Compose.pre b/libX11/nls/pt_BR.UTF-8/Compose.pre index b6d7c8acc..9e0ca4e42 100644 --- a/libX11/nls/pt_BR.UTF-8/Compose.pre +++ b/libX11/nls/pt_BR.UTF-8/Compose.pre @@ -1086,30 +1086,30 @@ XCOMM : "ǻ" U01FB # LATIN SMALL LETTER A WITH : "ǿ" U01FF # LATIN SMALL LETTER O WITH STROKE AND ACUTE : "ǿ" U01FF # LATIN SMALL LETTER O WITH STROKE AND ACUTE : "ǿ" U01FF # LATIN SMALL LETTER O WITH STROKE AND ACUTE - : "Ȁ" U0200 # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE - : "ȁ" U0201 # LATIN SMALL LETTER A WITH DOUBLE GRAVE - : "Ȃ" U0202 # LATIN CAPITAL LETTER A WITH INVERTED BREVE - : "ȃ" U0203 # LATIN SMALL LETTER A WITH INVERTED BREVE - : "Ȅ" U0204 # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE - : "ȅ" U0205 # LATIN SMALL LETTER E WITH DOUBLE GRAVE - : "Ȇ" U0206 # LATIN CAPITAL LETTER E WITH INVERTED BREVE - : "ȇ" U0207 # LATIN SMALL LETTER E WITH INVERTED BREVE - : "Ȉ" U0208 # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE - : "ȉ" U0209 # LATIN SMALL LETTER I WITH DOUBLE GRAVE - : "Ȋ" U020A # LATIN CAPITAL LETTER I WITH INVERTED BREVE - : "ȋ" U020B # LATIN SMALL LETTER I WITH INVERTED BREVE - : "Ȍ" U020C # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE - : "ȍ" U020D # LATIN SMALL LETTER O WITH DOUBLE GRAVE - : "Ȏ" U020E # LATIN CAPITAL LETTER O WITH INVERTED BREVE - : "ȏ" U020F # LATIN SMALL LETTER O WITH INVERTED BREVE - : "Ȑ" U0210 # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE - : "ȑ" U0211 # LATIN SMALL LETTER R WITH DOUBLE GRAVE - : "Ȓ" U0212 # LATIN CAPITAL LETTER R WITH INVERTED BREVE - : "ȓ" U0213 # LATIN SMALL LETTER R WITH INVERTED BREVE - : "Ȕ" U0214 # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE - : "ȕ" U0215 # LATIN SMALL LETTER U WITH DOUBLE GRAVE - : "Ȗ" U0216 # LATIN CAPITAL LETTER U WITH INVERTED BREVE - : "ȗ" U0217 # LATIN SMALL LETTER U WITH INVERTED BREVE + : "Ȁ" U0200 # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE + : "ȁ" U0201 # LATIN SMALL LETTER A WITH DOUBLE GRAVE + : "Ȃ" U0202 # LATIN CAPITAL LETTER A WITH INVERTED BREVE + : "ȃ" U0203 # LATIN SMALL LETTER A WITH INVERTED BREVE + : "Ȅ" U0204 # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE + : "ȅ" U0205 # LATIN SMALL LETTER E WITH DOUBLE GRAVE + : "Ȇ" U0206 # LATIN CAPITAL LETTER E WITH INVERTED BREVE + : "ȇ" U0207 # LATIN SMALL LETTER E WITH INVERTED BREVE + : "Ȉ" U0208 # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE + : "ȉ" U0209 # LATIN SMALL LETTER I WITH DOUBLE GRAVE + : "Ȋ" U020A # LATIN CAPITAL LETTER I WITH INVERTED BREVE + : "ȋ" U020B # LATIN SMALL LETTER I WITH INVERTED BREVE + : "Ȍ" U020C # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE + : "ȍ" U020D # LATIN SMALL LETTER O WITH DOUBLE GRAVE + : "Ȏ" U020E # LATIN CAPITAL LETTER O WITH INVERTED BREVE + : "ȏ" U020F # LATIN SMALL LETTER O WITH INVERTED BREVE + : "Ȑ" U0210 # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE + : "ȑ" U0211 # LATIN SMALL LETTER R WITH DOUBLE GRAVE + : "Ȓ" U0212 # LATIN CAPITAL LETTER R WITH INVERTED BREVE + : "ȓ" U0213 # LATIN SMALL LETTER R WITH INVERTED BREVE + : "Ȕ" U0214 # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE + : "ȕ" U0215 # LATIN SMALL LETTER U WITH DOUBLE GRAVE + : "Ȗ" U0216 # LATIN CAPITAL LETTER U WITH INVERTED BREVE + : "ȗ" U0217 # LATIN SMALL LETTER U WITH INVERTED BREVE : "Ș" U0218 # LATIN CAPITAL LETTER S WITH COMMA BELOW : "ș" U0219 # LATIN SMALL LETTER S WITH COMMA BELOW : "Ț" U021A # LATIN CAPITAL LETTER T WITH COMMA BELOW @@ -1371,8 +1371,8 @@ XCOMM : "ǻ" U01FB # LATIN SMALL LETTER A WITH : "ў" U045E # CYRILLIC SMALL LETTER SHORT U : "ў" U045E # CYRILLIC SMALL LETTER SHORT U : "ў" U045E # CYRILLIC SMALL LETTER SHORT U - : "Ѷ" U0476 # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT - : "ѷ" U0477 # CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT + : "Ѷ" U0476 # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT + : "ѷ" U0477 # CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT : "Ғ" U0492 # CYRILLIC CAPITAL LETTER GHE WITH STROKE : "Ғ" U0492 # CYRILLIC CAPITAL LETTER GHE WITH STROKE : "ғ" U0493 # CYRILLIC SMALL LETTER GHE WITH STROKE diff --git a/libX11/src/GetFProp.c b/libX11/src/GetFProp.c index 27ec98b72..1e0cd3285 100644 --- a/libX11/src/GetFProp.c +++ b/libX11/src/GetFProp.c @@ -29,27 +29,24 @@ in this Software without prior written authorization from The Open Group. #endif #include "Xlibint.h" -Bool XGetFontProperty ( +Bool +XGetFontProperty( XFontStruct *fs, register Atom name, unsigned long *valuePtr) { /* XXX this is a simple linear search for now. If the - protocol is changed to sort the property list, this should - become a binary search. */ + protocol is changed to sort the property list, this should + become a binary search. */ register XFontProp *prop = fs->properties; register XFontProp *last = prop + fs->n_properties; + while (prop != last) { - if (prop->name == name) { - *valuePtr = prop->card32; - return (1); - } - prop++; - } - return (0); + if (prop->name == name) { + *valuePtr = prop->card32; + return (1); + } + prop++; } - - - - - + return (0); +} diff --git a/libX11/src/PropAlloc.c b/libX11/src/PropAlloc.c index bad768153..516283080 100644 --- a/libX11/src/PropAlloc.c +++ b/libX11/src/PropAlloc.c @@ -58,12 +58,7 @@ XWMHints *XAllocWMHints (void) XClassHint *XAllocClassHint (void) { - register XClassHint *h; - - if ((h = (XClassHint *) Xcalloc (1, (unsigned) sizeof (XClassHint)))) - h->res_name = h->res_class = NULL; - - return h; + return Xcalloc (1, sizeof (XClassHint)); } diff --git a/libX11/src/udcInf.c b/libX11/src/udcInf.c index db7ad10f3..b7577ac96 100644 --- a/libX11/src/udcInf.c +++ b/libX11/src/udcInf.c @@ -702,14 +702,14 @@ int *num_gi; _XlcCloseConverter(conv); _XlcDestroyLC(lcd); - *gi = (_XUDCGIInf *)Xmalloc(sizeof(_XUDCGIInf)); - (*gi)->charset_str = (char *)Xmalloc(strlen(charsetname)+1); - strcpy((*gi)->charset_str,charsetname); - (*gi)->glyph_index = glyph; + *gi = Xmalloc(sizeof(_XUDCGIInf)); if(*gi == NULL){ _xudc_utyerrno = 0x03 ; return(_XUDC_ERROR); } + (*gi)->charset_str = Xmalloc(strlen(charsetname)+1); + strcpy((*gi)->charset_str,charsetname); + (*gi)->glyph_index = glyph; *num_gi = 1; return(0); } diff --git a/mesalib/configure.ac b/mesalib/configure.ac index ea56a044d..320486910 100644 --- a/mesalib/configure.ac +++ b/mesalib/configure.ac @@ -1062,26 +1062,24 @@ if test "x$enable_dri" = xyes; then DRI_DIRS=`echo "$DRI_DIRS" | $SED 's/ */ /g'` # Check for expat - if test "x$enable_dri" = xyes; then - EXPAT_INCLUDES="" - EXPAT_LIB=-lexpat - AC_ARG_WITH([expat], - [AS_HELP_STRING([--with-expat=DIR], - [expat install directory])],[ - EXPAT_INCLUDES="-I$withval/include" - CPPFLAGS="$CPPFLAGS $EXPAT_INCLUDES" - LDFLAGS="$LDFLAGS -L$withval/$LIB_DIR" - EXPAT_LIB="-L$withval/$LIB_DIR -lexpat" - ]) - AC_CHECK_HEADER([expat.h],[],[AC_MSG_ERROR([Expat required for DRI.])]) - save_LIBS="$LIBS" - AC_CHECK_LIB([expat],[XML_ParserCreate],[], - [AC_MSG_ERROR([Expat required for DRI.])]) - LIBS="$save_LIBS" - fi - - # if we are building any dri driver other than swrast or using the dri state tracker ... - if test -n "$DRI_DIRS" -a x"$DRI_DIRS" != xswrast -a "x$enable_dri" = xyes; then + EXPAT_INCLUDES="" + EXPAT_LIB=-lexpat + AC_ARG_WITH([expat], + [AS_HELP_STRING([--with-expat=DIR], + [expat install directory])],[ + EXPAT_INCLUDES="-I$withval/include" + CPPFLAGS="$CPPFLAGS $EXPAT_INCLUDES" + LDFLAGS="$LDFLAGS -L$withval/$LIB_DIR" + EXPAT_LIB="-L$withval/$LIB_DIR -lexpat" + ]) + AC_CHECK_HEADER([expat.h],[],[AC_MSG_ERROR([Expat required for DRI.])]) + save_LIBS="$LIBS" + AC_CHECK_LIB([expat],[XML_ParserCreate],[], + [AC_MSG_ERROR([Expat required for DRI.])]) + LIBS="$save_LIBS" + + # If we are building any DRI driver other than swrast. + if test -n "$DRI_DIRS" -a x"$DRI_DIRS" != xswrast; then # ... libdrm is required if test "x$have_libdrm" != xyes; then AC_MSG_ERROR([DRI drivers requires libdrm >= $LIBDRM_REQUIRED]) @@ -1149,14 +1147,6 @@ case $DRI_DIRS in ;; esac -AM_CONDITIONAL(HAVE_I915_DRI, test x$HAVE_I915_DRI = xyes) -AM_CONDITIONAL(HAVE_I965_DRI, test x$HAVE_I965_DRI = xyes) -AM_CONDITIONAL(HAVE_NOUVEAU_DRI, test x$HAVE_NOUVEAU_DRI = xyes) -AM_CONDITIONAL(HAVE_R200_DRI, test x$HAVE_R200_DRI = xyes) -AM_CONDITIONAL(HAVE_RADEON_DRI, test x$HAVE_RADEON_DRI = xyes) -AM_CONDITIONAL(HAVE_SWRAST_DRI, test x$HAVE_SWRAST_DRI = xyes) -AM_CONDITIONAL(HAVE_COMMON_DRI, test x$HAVE_COMMON_DRI = xyes) - dnl dnl OSMesa configuration dnl @@ -1755,6 +1745,7 @@ gallium_check_st() { fi if test "x$HAVE_ST_DRI" = xyes && test "x$2" != x; then GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $2" + HAVE_COMMON_DRI=yes fi if test "x$HAVE_ST_XORG" = xyes && test "x$3" != x; then GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $3" @@ -1996,6 +1987,14 @@ for driver in $GALLIUM_DRIVERS_DIRS; do esac done +AM_CONDITIONAL(HAVE_I915_DRI, test x$HAVE_I915_DRI = xyes) +AM_CONDITIONAL(HAVE_I965_DRI, test x$HAVE_I965_DRI = xyes) +AM_CONDITIONAL(HAVE_NOUVEAU_DRI, test x$HAVE_NOUVEAU_DRI = xyes) +AM_CONDITIONAL(HAVE_R200_DRI, test x$HAVE_R200_DRI = xyes) +AM_CONDITIONAL(HAVE_RADEON_DRI, test x$HAVE_RADEON_DRI = xyes) +AM_CONDITIONAL(HAVE_SWRAST_DRI, test x$HAVE_SWRAST_DRI = xyes) +AM_CONDITIONAL(HAVE_COMMON_DRI, test x$HAVE_COMMON_DRI = xyes) + AM_CONDITIONAL(HAVE_GALAHAD_GALLIUM, test x$HAVE_GALAHAD_GALLIUM = xyes) AM_CONDITIONAL(HAVE_IDENTITY_GALLIUM, test x$HAVE_IDENTITY_GALLIUM = xyes) AM_CONDITIONAL(HAVE_NOOP_GALLIUM, test x$HAVE_NOOP_GALLIUM = xyes) diff --git a/mesalib/docs/viewperf.html b/mesalib/docs/viewperf.html index ab2fd67ef..3bbe1978a 100644 --- a/mesalib/docs/viewperf.html +++ b/mesalib/docs/viewperf.html @@ -203,6 +203,35 @@ This causes the object in question to be drawn in a strange orientation and with a semi-random color (between white and black) since GL_FOG is enabled.

+ +

Proe-05 test 1

+ +

+This uses depth testing but there's two problems: +

    +
  1. The glXChooseFBConfig() call doesn't request a depth buffer +
  2. The test never calls glClear(GL_DEPTH_BUFFER_BIT) to initialize the depth buffer +
+

+If the chosen visual does not have a depth buffer, you'll see the wireframe +car model but it won't be rendered correctly. +

+If (by luck) the chosen visual has a depth buffer, its initial contents +will be undefined so you may or may not see parts of the model. +

+Interestingly, with NVIDIA's driver most visuals happen to have a depth buffer +and apparently the contents are initialized to 1.0 by default so this test +just happens to work with their drivers. +

+ +

+Finally, even if a depth buffer was requested and the glClear(GL_COLOR_BUFFER_BIT) +calls were changed to glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) +the problem still wouldn't be fixed because GL_DEPTH_WRITEMASK=GL_FALSE when +glClear is called so clearing the depth buffer would be a no-op anyway. +

+ + diff --git a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c index d7f0be40e..03280515b 100644 --- a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c +++ b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c @@ -270,7 +270,7 @@ util_cpu_detect(void) util_cpu_caps.x86_cpu_type = 8 + ((regs2[0] >> 20) & 255); /* use extended family (P4, IA64) */ /* general feature flags */ - util_cpu_caps.has_tsc = (regs2[3] >> 8) & 1; /* 0x0000010 */ + util_cpu_caps.has_tsc = (regs2[3] >> 4) & 1; /* 0x0000010 */ util_cpu_caps.has_mmx = (regs2[3] >> 23) & 1; /* 0x0800000 */ util_cpu_caps.has_sse = (regs2[3] >> 25) & 1; /* 0x2000000 */ util_cpu_caps.has_sse2 = (regs2[3] >> 26) & 1; /* 0x4000000 */ diff --git a/mesalib/src/mapi/glapi/gen/Makefile.am b/mesalib/src/mapi/glapi/gen/Makefile.am index 4d51bbca6..36e47e21e 100644 --- a/mesalib/src/mapi/glapi/gen/Makefile.am +++ b/mesalib/src/mapi/glapi/gen/Makefile.am @@ -246,19 +246,19 @@ $(MESA_GLX_DIR)/indirect_size.c: glX_proto_size.py $(COMMON_GLX) ###################################################################### $(XORG_GLX_DIR)/indirect_dispatch.c: glX_proto_recv.py $(COMMON_GLX) - $(PYTHON_GEN) $(PYTHON_FLAGS) $< -f $(srcdir)/gl_API.xml -m dispatch_c \ + $(PYTHON_GEN) $< -f $(srcdir)/gl_API.xml -m dispatch_c \ | $(INDENT) $(XORG_INDENT_FLAGS) > $@ $(XORG_GLX_DIR)/indirect_dispatch_swap.c: glX_proto_recv.py $(COMMON_GLX) - $(PYTHON_GEN) $(PYTHON_FLAGS) $< -f $(srcdir)/gl_API.xml -m dispatch_c -s \ + $(PYTHON_GEN) $< -f $(srcdir)/gl_API.xml -m dispatch_c -s \ | $(INDENT) $(XORG_INDENT_FLAGS) > $@ $(XORG_GLX_DIR)/indirect_dispatch.h: glX_proto_recv.py gl_and_glX_API.xml $(COMMON_GLX) - $(PYTHON_GEN) $(PYTHON_FLAGS) $< -m dispatch_h -f $(srcdir)/gl_and_glX_API.xml -s \ + $(PYTHON_GEN) $< -m dispatch_h -f $(srcdir)/gl_and_glX_API.xml -s \ | $(INDENT) $(XORG_INDENT_FLAGS) > $@ $(XORG_GLX_DIR)/indirect_size_get.h: glX_proto_size.py $(COMMON_GLX) - $(PYTHON_GEN) $(PYTHON_FLAGS) $< -f $(srcdir)/gl_API.xml -m size_h \ + $(PYTHON_GEN) $< -f $(srcdir)/gl_API.xml -m size_h \ --only-get -h '_INDIRECT_SIZE_GET_H_' \ | $(INDENT) $(XORG_INDENT_FLAGS) > $@ @@ -267,14 +267,14 @@ $(XORG_GLX_DIR)/indirect_size_get.c: glX_proto_size.py $(COMMON_GLX) | $(INDENT) $(INDENT_FLAGS) > $@ $(XORG_GLX_DIR)/indirect_reqsize.h: glX_proto_size.py $(COMMON_GLX) - $(PYTHON_GEN) $(PYTHON_FLAGS) $< -f $(srcdir)/gl_API.xml -m reqsize_h \ + $(PYTHON_GEN) $< -f $(srcdir)/gl_API.xml -m reqsize_h \ --only-get -h '_INDIRECT_SIZE_GET_H_' \ | $(INDENT) $(XORG_INDENT_FLAGS) > $@ $(XORG_GLX_DIR)/indirect_reqsize.c: glX_proto_size.py $(COMMON_GLX) - $(PYTHON_GEN) $(PYTHON_FLAGS) $< -f $(srcdir)/gl_API.xml -m reqsize_c \ + $(PYTHON_GEN) $< -f $(srcdir)/gl_API.xml -m reqsize_c \ | $(INDENT) $(XORG_INDENT_FLAGS) > $@ $(XORG_GLX_DIR)/indirect_table.c: glX_server_table.py gl_and_glX_API.xml $(COMMON_GLX) - $(PYTHON_GEN) $(PYTHON_FLAGS) $< -f $(srcdir)/gl_and_glX_API.xml \ + $(PYTHON_GEN) $< -f $(srcdir)/gl_and_glX_API.xml \ | $(INDENT) $(XORG_INDENT_FLAGS) > $@ diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index 2399f9c9d..582ef3198 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -34,6 +34,7 @@ #include "state.h" #include "texcompress.h" #include "framebuffer.h" +#include "samplerobj.h" /* This is a table driven implemetation of the glGet*v() functions. * The basic idea is that most getters just look up an int somewhere @@ -827,7 +828,16 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu { struct gl_sampler_object *samp = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler; - v->value_int = samp ? samp->Name : 0; + + /* + * The sampler object may have been deleted on another context, + * so we try to lookup the sampler object before returning its Name. + */ + if (samp && _mesa_lookup_samplerobj(ctx, samp->Name)) { + v->value_int = samp->Name; + } else { + v->value_int = 0; + } } break; /* GL_ARB_uniform_buffer_object */ diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c index 8728540cf..c1e16587a 100644 --- a/mesalib/src/mesa/main/glformats.c +++ b/mesalib/src/mesa/main/glformats.c @@ -917,7 +917,7 @@ _mesa_is_compressed_format(struct gl_context *ctx, GLenum format) case GL_COMPRESSED_SIGNED_RG11_EAC: case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: - return _mesa_is_gles3(ctx); + return _mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility; case GL_PALETTE4_RGB8_OES: case GL_PALETTE4_RGBA8_OES: case GL_PALETTE4_R5_G6_B5_OES: diff --git a/mesalib/src/mesa/main/samplerobj.c b/mesalib/src/mesa/main/samplerobj.c index 319a444d7..5cff32936 100644 --- a/mesalib/src/mesa/main/samplerobj.c +++ b/mesalib/src/mesa/main/samplerobj.c @@ -40,7 +40,7 @@ #include "main/samplerobj.h" -static struct gl_sampler_object * +struct gl_sampler_object * _mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name) { if (name == 0) @@ -206,9 +206,19 @@ _mesa_DeleteSamplers(GLsizei count, const GLuint *samplers) for (i = 0; i < count; i++) { if (samplers[i]) { + GLuint j; struct gl_sampler_object *sampObj = _mesa_lookup_samplerobj(ctx, samplers[i]); + if (sampObj) { + /* If the sampler is currently bound, unbind it. */ + for (j = 0; j < ctx->Const.MaxCombinedTextureImageUnits; j++) { + if (ctx->Texture.Unit[j].Sampler == sampObj) { + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[j].Sampler, NULL); + } + } + /* The ID is immediately freed for re-use */ _mesa_HashRemove(ctx->Shared->SamplerObjects, samplers[i]); /* But the object exists until its reference count goes to zero */ diff --git a/mesalib/src/mesa/main/samplerobj.h b/mesalib/src/mesa/main/samplerobj.h index 311425701..69e389949 100644 --- a/mesalib/src/mesa/main/samplerobj.h +++ b/mesalib/src/mesa/main/samplerobj.h @@ -62,6 +62,8 @@ _mesa_reference_sampler_object(struct gl_context *ctx, _mesa_reference_sampler_object_(ctx, ptr, samp); } +extern struct gl_sampler_object * +_mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name); extern struct gl_sampler_object * _mesa_new_sampler_object(struct gl_context *ctx, GLuint name); diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 9d4a17052..7d996da47 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -520,7 +520,7 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) } } - if (_mesa_is_gles3(ctx)) { + if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility) { switch (internalFormat) { case GL_COMPRESSED_RGB8_ETC2: case GL_COMPRESSED_SRGB8_ETC2: diff --git a/mesalib/src/mesa/vbo/vbo_save_draw.c b/mesalib/src/mesa/vbo/vbo_save_draw.c index efb386e5c..f5b5c411d 100644 --- a/mesalib/src/mesa/vbo/vbo_save_draw.c +++ b/mesalib/src/mesa/vbo/vbo_save_draw.c @@ -253,7 +253,7 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data) struct vbo_save_context *save = &vbo_context(ctx)->save; GLboolean remap_vertex_store = GL_FALSE; - if (save->vertex_store->buffer) { + if (save->vertex_store && save->vertex_store->buffer) { /* The vertex store is currently mapped but we're about to replay * a display list. This can happen when a nested display list is * being build with GL_COMPILE_AND_EXECUTE. diff --git a/pixman/pixman/pixman-mmx.c b/pixman/pixman/pixman-mmx.c index ca2ac83d9..14790c029 100644 --- a/pixman/pixman/pixman-mmx.c +++ b/pixman/pixman/pixman-mmx.c @@ -44,8 +44,6 @@ #include "pixman-combine32.h" #include "pixman-inlines.h" -#define no_vERBOSE - #ifdef VERBOSE #define CHECKPOINT() error_f ("at %s %d\n", __FUNCTION__, __LINE__) #else diff --git a/xorg-server/fb/wfbrename.h b/xorg-server/fb/wfbrename.h index 588440c2b..54d00d003 100644 --- a/xorg-server/fb/wfbrename.h +++ b/xorg-server/fb/wfbrename.h @@ -52,6 +52,7 @@ #define fbCreatePixmap wfbCreatePixmap #define fbCreatePixmapBpp wfbCreatePixmapBpp #define fbCreateWindow wfbCreateWindow +#define fbDestroyGlyphCache wfbDestroyGlyphCache #define fbDestroyPixmap wfbDestroyPixmap #define fbDestroyWindow wfbDestroyWindow #define fbDoCopy wfbDoCopy diff --git a/xorg-server/xkeyboard-config/rules/base.o_s.part b/xorg-server/xkeyboard-config/rules/base.o_s.part index 721291985..46c07b01d 100644 --- a/xorg-server/xkeyboard-config/rules/base.o_s.part +++ b/xorg-server/xkeyboard-config/rules/base.o_s.part @@ -1,5 +1,6 @@ altwin:menu = +altwin(menu) altwin:meta_alt = +altwin(meta_alt) + altwin:alt_win = +altwin(alt_win) altwin:ctrl_win = +altwin(ctrl_win) altwin:ctrl_alt_win = +altwin(ctrl_alt_win) altwin:meta_win = +altwin(meta_win) diff --git a/xorg-server/xkeyboard-config/rules/base.xml.in b/xorg-server/xkeyboard-config/rules/base.xml.in index 95790dda8..1d346238e 100644 --- a/xorg-server/xkeyboard-config/rules/base.xml.in +++ b/xorg-server/xkeyboard-config/rules/base.xml.in @@ -6219,6 +6219,12 @@ <_description>Alt and Meta are on Alt keys +
+

February 24, 2013

diff --git a/mesalib/docs/relnotes-9.1.1.html b/mesalib/docs/relnotes-9.1.1.html new file mode 100644 index 000000000..a73c97424 --- /dev/null +++ b/mesalib/docs/relnotes-9.1.1.html @@ -0,0 +1,235 @@ + + + + + Mesa Release Notes + + + + +

+

The Mesa 3D Graphics Library

+
+ + +
+ +

Mesa 9.1.1 Release Notes / March 19th, 2013

+ +

+Mesa 9.1.1 is a bug fix release which fixes bugs found since the 9.1 release. +

+

+Mesa 9.1 implements the OpenGL 3.1 API, but the version reported by +glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) / +glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used. +Some drivers don't support all the features required in OpenGL 3.1. OpenGL +3.1 is only available if requested at context creation +because GL_ARB_compatibility is not supported. +

+ +

MD5 checksums

+
+6508d9882d8dce7106717f365632700c  MesaLib-9.1.1.tar.gz
+6ea2bdc3b7ecfb4257b39814b4182580  MesaLib-9.1.1.tar.bz2
+3434c0eb47849a08c53cd32833d10d13  MesaLib-9.1.1.zip
+
+ +

New features

+

None.

+ +

Bug fixes

+ +

This list is likely incomplete.

+ +
    +
  • Bug 30232 - [GM45] mesa demos spriteblast render incorrectly
  • + +
  • Bug 32429 - [gles2] Ironlake: gl_PointCoord takes no effect for point sprites
  • + +
  • Bug 38086 - Mesa 7.11-devel implementation error: Unexpected program target in destroy_program_variants_cb()
  • + +
  • Bug 57121 - [snb] corrupted GLSL built-in function results when using Uniform Buffer contents as arguments
  • + +
  • Bug 58042 - [bisected] Garbled UI in Team Fortress 2 and Counter-Strike: Source
  • + +
  • Bug 58960 - Texture flicker with fragment shader
  • + +
  • Bug 59495 - [i965 Bisected]Oglc fbblit(advanced.blitFb-3d-cube.mirror.both) fails
  • + +
  • Bug 59783 - [IVB bisected] 3DMMES2.0 Taiji performance reduced by ~13% with gnome-session enable compositing
  • + +
  • Bug 60121 - build - libvdpau_softpipe fails at runtime.
  • + +
  • Bug 60143 - gbm_dri_bo_create fails to initialize bo->base.base.format
  • + +
  • Bug 60802 - Corruption with DMA ring on cayman
  • + +
  • Bug 60848 - [bisected] r600g: add htile support cause gpu lockup in Dishonored wine.
  • + +
  • Bug 60938 - [softpipe] piglit interpolation-noperspective-gl_BackColor-flat-fixed regression
  • + +
  • Bug 61012 - alloc_layout_array tx * ty assertion failure when making pbuffer current
  • + +
  • Bug 61026 - Segfault in glBitmap when called with PBO source
  • + + +
+ + +

Changes

+

The full set of changes can be viewed by using the following GIT command:

+ +
+  git log mesa-9.1..mesa-9.1.1
+
+ + +

Adam Sampson (1):

+
    +
  • autotools: oprofilejit should be included in the list of LLVM components required
  • +
+ +

Alex Deucher (2):

+
    +
  • r600g: add Richland APU pci ids
  • +
  • r600g: Use blitter rather than DMA for 128bpp on cayman (v3)
  • +
+ +

Andreas Boll (2):

+
    +
  • docs: Add 9.1 release md5sums
  • +
  • docs: add news item for 9.1 release
  • +
+ +

Anuj Phogat (1):

+
    +
  • meta: Allocate texture before initializing texture coordinates
  • +
+ +

Brian Paul (11):

+
    +
  • docs: remove stray 'date' text
  • +
  • docs: insert links to the 9.0.3 release
  • +
  • draw: fix non-perspective interpolation in interp()
  • +
  • st/mesa: implement glBitmap unpacking from a PBO, for the cache path
  • +
  • st/xlib: initialize the drawable size in create_xmesa_buffer()
  • +
  • st/mesa: fix trimming of GL_QUAD_STRIP
  • +
  • st/mesa: check for dummy programs in destroy_program_variants()
  • +
  • st/mesa: fix polygon offset state translation logic
  • +
  • draw: fix broken polygon offset stage
  • +
  • llvmpipe: add missing checks for polygon offset point/line modes
  • +
  • svga: always link with C++
  • +
+ +

Daniel van Vugt (1):

+
    +
  • gbm: Remember to init format on gbm_dri_bo_create.
  • +
+ +

Eric Anholt (7):

+
    +
  • i965/fs: Do a general SEND dependency workaround for the original 965.
  • +
  • i965/fs: Fix copy propagation with smearing.
  • +
  • i965/fs: Delay setup of uniform loads until after pre-regalloc scheduling.
  • +
  • i965/fs: Only do CSE when the dst types match.
  • +
  • i965/fs: Fix broken math on values loaded from uniform buffers on gen6.
  • +
  • mesa: Fix setup of ctx->Point.PointSprite for GLES2.
  • +
  • i965: Fix the W value of deprecated pointcoords on pre-gen6.
  • +
+ +

Frank Henigman (1):

+
    +
  • i965: Link i965_dri.so with C++ linker.
  • +
+ +

Ian Romanick (3):

+
    +
  • mesa: Add previously picked commit to .cherry-ignore
  • +
  • mesa: Modify candidate search string
  • +
  • egl: Allow 24-bit visuals for 32-bit RGBA8888 configs
  • +
+ +

Jakub Bogusz (1):

+
    +
  • vdpau-softpipe: Build correct source file - vl_winsys_xsp.c
  • +
+ +

Jerome Glisse (1):

+
    +
  • r600g: workaround hyperz lockup on evergreen
  • +
+ +

John Kåre Alsaker (1):

+
    +
  • llvmpipe: Fix creation of shared and scanout textures.
  • +
+ +

Jordan Justen (1):

+
    +
  • attrib: push/pop FRAGMENT_PROGRAM_ARB state
  • +
+ +

José Fonseca (3):

+
    +
  • scons: Allows choosing VS 10 or 11.
  • +
  • scons: Define _ALLOW_KEYWORD_MACROS on MSVC builds.
  • +
  • scons: Warn when using MSVS versions prior to 2012.
  • +
+ +

Keith Kriewall (1):

+
    +
  • scons: Fix Windows build with LLVM 3.2
  • +
+ +

Kenneth Graunke (1):

+
    +
  • i965: Fix Crystal Well PCI IDs.
  • +
+ +

Marek Olšák (5):

+
    +
  • r600g: use async DMA with a non-zero src offset
  • +
  • r600g: flush and invalidate htile cache when appropriate
  • +
  • gallium/util: add helper code for 1D integer range
  • +
  • r600g: always map uninitialized buffer range as unsynchronized
  • +
  • r600g: pad the DMA CS to a multiple of 8 dwords
  • +
+ +

Martin Andersson (1):

+
    +
  • winsys/radeon: Only add bo to hash table when creating flink
  • +
+ +

Matt Turner (1):

+
    +
  • mesa: Allow ETC2/EAC formats with ARB_ES3_compatibility.
  • +
+ +

Michel Dänzer (3):

+
    +
  • radeonsi: Fix up and enable flat shading.
  • +
  • r600g/Cayman: Fix blending using destination alpha factor but non-alpha dest
  • +
  • radeonsi: Fix off-by-one for maximum vertex element index in some cases
  • +
+ +

Tapani Pälli (2):

+
    +
  • mesa: add missing case in _mesa_GetTexParameterfv()
  • +
  • mesa/es: NULL check in EGLImageTargetTexture2DOES
  • +
+ +

Vadim Girlin (1):

+
    +
  • r600g: fix check_and_set_bank_swizzle for cayman
  • +
+ +

Vincent Lejeune (2):

+
    +
  • r600g/llvm: Add support for UBO
  • +
  • r600g: Check comp_mask before merging export instructions
  • +
+ +
+ + diff --git a/mesalib/include/GL/internal/dri_interface.h b/mesalib/include/GL/internal/dri_interface.h index 42147e90e..30ce175e6 100644 --- a/mesalib/include/GL/internal/dri_interface.h +++ b/mesalib/include/GL/internal/dri_interface.h @@ -938,7 +938,7 @@ struct __DRIdri2ExtensionRec { * extensions. */ #define __DRI_IMAGE "DRI_IMAGE" -#define __DRI_IMAGE_VERSION 6 +#define __DRI_IMAGE_VERSION 7 /** * These formats correspond to the similarly named MESA_FORMAT_* @@ -1021,6 +1021,9 @@ struct __DRIdri2ExtensionRec { #define __DRI_IMAGE_ATTRIB_WIDTH 0x2004 /* available in versions 4+ */ #define __DRI_IMAGE_ATTRIB_HEIGHT 0x2005 #define __DRI_IMAGE_ATTRIB_COMPONENTS 0x2006 /* available in versions 5+ */ +#define __DRI_IMAGE_ATTRIB_FD 0x2007 /* available in versions + * 7+. Each query will return a + * new fd. */ /** * \name Reasons that __DRIimageExtensionRec::createImageFromTexture might fail @@ -1117,6 +1120,16 @@ struct __DRIimageExtensionRec { int level, unsigned *error, void *loaderPrivate); + /** + * Like createImageFromNames, but takes a prime fd instead. + * + * \since 7 + */ + __DRIimage *(*createImageFromFds)(__DRIscreen *screen, + int width, int height, int fourcc, + int *fds, int num_fds, + int *strides, int *offsets, + void *loaderPrivate); }; diff --git a/mesalib/scons/gallium.py b/mesalib/scons/gallium.py index b28be5d89..57b5b418f 100644 --- a/mesalib/scons/gallium.py +++ b/mesalib/scons/gallium.py @@ -402,7 +402,7 @@ def generate(env): '/Oi', # enable intrinsic functions ] else: - if distutils.version.LooseVersion(env['MSVC_VERSION']) < distutils.version.LooseVersion('11.0'): + if 'MSVC_VERSION' in env and distutils.version.LooseVersion(env['MSVC_VERSION']) < distutils.version.LooseVersion('11.0'): print 'scons: warning: Visual Studio versions prior to 2012 are known to produce incorrect code when optimizations are enabled ( https://bugs.freedesktop.org/show_bug.cgi?id=58718 )' ccflags += [ '/O2', # optimize for speed diff --git a/mesalib/src/gallium/auxiliary/Makefile.sources b/mesalib/src/gallium/auxiliary/Makefile.sources index 74c7902ae..898abe024 100644 --- a/mesalib/src/gallium/auxiliary/Makefile.sources +++ b/mesalib/src/gallium/auxiliary/Makefile.sources @@ -164,6 +164,7 @@ GALLIVM_SOURCES := \ gallivm/lp_bld_flow.c \ gallivm/lp_bld_format_aos.c \ gallivm/lp_bld_format_aos_array.c \ + gallivm/lp_bld_format_float.c \ gallivm/lp_bld_format_soa.c \ gallivm/lp_bld_format_yuv.c \ gallivm/lp_bld_gather.c \ diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index a783dcc3b..8b0a24805 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -291,6 +291,14 @@ glsl_type::generate_140_types(glsl_symbol_table *symtab) } +void +glsl_type::generate_150_types(glsl_symbol_table *symtab) +{ + generate_140_types(symtab); + generate_ARB_texture_multisample_types(symtab, false); +} + + void glsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab, bool warn) @@ -385,9 +393,11 @@ _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state) glsl_type::generate_130_types(state->symbols, true, skip_1d); break; case 140: - case 150: glsl_type::generate_140_types(state->symbols); break; + case 150: + glsl_type::generate_150_types(state->symbols); + break; default: assert(!"Unexpected language version"); break; diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h index 79304269d..2f3b19f51 100644 --- a/mesalib/src/glsl/glsl_types.h +++ b/mesalib/src/glsl/glsl_types.h @@ -583,6 +583,7 @@ private: static void generate_130_types(glsl_symbol_table *, bool add_deprecated, bool skip_1d); static void generate_140_types(glsl_symbol_table *); + static void generate_150_types(glsl_symbol_table *); static void generate_ARB_texture_rectangle_types(glsl_symbol_table *, bool); static void generate_EXT_texture_array_types(glsl_symbol_table *, bool); static void generate_OES_texture_3D_types(glsl_symbol_table *, bool); diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp index ed6f12279..ce084b4d7 100644 --- a/mesalib/src/glsl/main.cpp +++ b/mesalib/src/glsl/main.cpp @@ -47,7 +47,7 @@ initialize_context(struct gl_context *ctx, gl_api api) /* The standalone compiler needs to claim support for almost * everything in order to compile the built-in functions. */ - ctx->Const.GLSLVersion = 140; + ctx->Const.GLSLVersion = 150; ctx->Extensions.ARB_ES3_compatibility = true; ctx->Const.MaxClipPlanes = 8; diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index 29a209ede..8114550ba 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -3118,6 +3118,7 @@ setup_texture_coords(GLenum faceTarget, GLint slice, GLint width, GLint height, + GLint depth, GLfloat coords0[3], GLfloat coords1[3], GLfloat coords2[3], @@ -3134,8 +3135,11 @@ setup_texture_coords(GLenum faceTarget, case GL_TEXTURE_2D: case GL_TEXTURE_3D: case GL_TEXTURE_2D_ARRAY: - if (faceTarget == GL_TEXTURE_3D) - r = 1.0F / slice; + if (faceTarget == GL_TEXTURE_3D) { + assert(slice < depth); + assert(depth >= 1); + r = (slice + 0.5f) / depth; + } else if (faceTarget == GL_TEXTURE_2D_ARRAY) r = slice; else @@ -3571,10 +3575,10 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, else assert(!genMipmapSave); - /* Setup texture coordinates */ + /* Setup texture coordinates */ setup_texture_coords(faceTarget, slice, - 0, 0, /* width, height never used here */ + 0, 0, 1, /* width, height never used here */ verts[0].tex, verts[1].tex, verts[2].tex, @@ -3840,6 +3844,7 @@ decompress_texture_image(struct gl_context *ctx, struct gl_texture_object *texObj = texImage->TexObject; const GLint width = texImage->Width; const GLint height = texImage->Height; + const GLint depth = texImage->Height; const GLenum target = texObj->Target; GLenum faceTarget; struct vertex { @@ -3935,7 +3940,7 @@ decompress_texture_image(struct gl_context *ctx, _mesa_BindSampler(ctx->Texture.CurrentUnit, decompress->Sampler); } - setup_texture_coords(faceTarget, slice, width, height, + setup_texture_coords(faceTarget, slice, width, height, depth, verts[0].tex, verts[1].tex, verts[2].tex, diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h b/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h index 1e7eced06..7b441c68f 100644 --- a/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h +++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h @@ -75,6 +75,11 @@ DRI_CONF_OPT_BEGIN(always_flush_cache,bool,def) \ DRI_CONF_DESC(en,gettext("Enable flushing GPU caches with each draw call")) \ DRI_CONF_OPT_END +#define DRI_CONF_DISABLE_THROTTLING(def) \ +DRI_CONF_OPT_BEGIN(disable_throttling,bool,def) \ + DRI_CONF_DESC(en,gettext("Disable throttling on first batch after flush")) \ +DRI_CONF_OPT_END + #define DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN(def) \ DRI_CONF_OPT_BEGIN(force_glsl_extensions_warn,bool,def) \ DRI_CONF_DESC(en,gettext("Force GLSL extension default behavior to 'warn'")) \ diff --git a/mesalib/src/mesa/main/compiler.h b/mesalib/src/mesa/main/compiler.h index 48712485a..8b23665e6 100644 --- a/mesalib/src/mesa/main/compiler.h +++ b/mesalib/src/mesa/main/compiler.h @@ -307,8 +307,9 @@ static INLINE GLuint CPU_TO_LE32(GLuint x) * USE_IEEE: Determine if we're using IEEE floating point */ #if defined(__i386__) || defined(__386__) || defined(__sparc__) || \ - defined(__s390x__) || defined(__powerpc__) || \ + defined(__s390__) || defined(__s390x__) || defined(__powerpc__) || \ defined(__x86_64__) || \ + defined(__m68k__) || \ defined(ia64) || defined(__ia64__) || \ defined(__hppa__) || defined(hpux) || \ defined(__mips) || defined(_MIPS_ARCH) || \ diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index 4860d4d12..8f3cd3d6b 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -195,9 +195,10 @@ struct dd_function_table { GLenum srcFormat, GLenum srcType ); /** - * Determine sample counts support for a particular format + * Determine sample counts support for a particular target and format * * \param ctx GL context + * \param target GL target enum * \param internalFormat GL format enum * \param samples Buffer to hold the returned sample counts. * Drivers \b must \b not return more than 16 counts. @@ -207,6 +208,7 @@ struct dd_function_table { * \c internaFormat is not renderable, zero is returned. */ size_t (*QuerySamplesForFormat)(struct gl_context *ctx, + GLenum target, GLenum internalFormat, int samples[16]); diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 0126e2930..3fdf62667 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -43,6 +43,7 @@ #include "hash.h" #include "macros.h" #include "mfeatures.h" +#include "multisample.h" #include "mtypes.h" #include "renderbuffer.h" #include "state.h" @@ -473,6 +474,32 @@ _mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) } +/** + * Return true if the framebuffer has a combined depth/stencil + * renderbuffer attached. + */ +GLboolean +_mesa_has_depthstencil_combined(const struct gl_framebuffer *fb) +{ + const struct gl_renderbuffer_attachment *depth = + &fb->Attachment[BUFFER_DEPTH]; + const struct gl_renderbuffer_attachment *stencil = + &fb->Attachment[BUFFER_STENCIL]; + + if (depth->Type == stencil->Type) { + if (depth->Type == GL_RENDERBUFFER_EXT && + depth->Renderbuffer == stencil->Renderbuffer) + return GL_TRUE; + + if (depth->Type == GL_TEXTURE && + depth->Texture == stencil->Texture) + return GL_TRUE; + } + + return GL_FALSE; +} + + /** * For debug only. */ @@ -1466,6 +1493,7 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, "glRenderbufferStorage" : "glRenderbufferStorageMultisample"; struct gl_renderbuffer *rb; GLenum baseFormat; + GLenum sample_count_error; GET_CURRENT_CONTEXT(ctx); if (MESA_VERBOSE & VERBOSE_API) { @@ -1509,9 +1537,14 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, /* NumSamples == 0 indicates non-multisampling */ samples = 0; } - else if (samples > (GLsizei) ctx->Const.MaxSamples) { - /* note: driver may choose to use more samples than what's requested */ - _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples)", func); + + /* check the sample count; + * note: driver may choose to use more samples than what's requested + */ + sample_count_error = _mesa_check_sample_count(ctx, target, + internalFormat, samples); + if (sample_count_error != GL_NO_ERROR) { + _mesa_error(ctx, sample_count_error, "%s(samples)", func); return; } diff --git a/mesalib/src/mesa/main/fbobject.h b/mesalib/src/mesa/main/fbobject.h index ec8b0afe4..0358864d7 100644 --- a/mesalib/src/mesa/main/fbobject.h +++ b/mesalib/src/mesa/main/fbobject.h @@ -113,6 +113,9 @@ _mesa_framebuffer_renderbuffer(struct gl_context *ctx, extern void _mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb); +extern GLboolean +_mesa_has_depthstencil_combined(const struct gl_framebuffer *fb); + extern void _mesa_test_framebuffer_completeness(struct gl_context *ctx, struct gl_framebuffer *fb); diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp index 186988bbd..01a4542d7 100644 --- a/mesalib/src/mesa/main/ff_fragment_shader.cpp +++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp @@ -1350,22 +1350,6 @@ create_new_program(struct gl_context *ctx, struct state_key *key) _mesa_glsl_link_shader(ctx, p.shader_program); - /* Set the sampler uniforms, and relink to get them into the linked - * program. - */ - struct gl_shader *const fs = - p.shader_program->_LinkedShaders[MESA_SHADER_FRAGMENT]; - struct gl_program *const fp = fs->Program; - - _mesa_generate_parameters_list_for_uniforms(p.shader_program, fs, - fp->Parameters); - - _mesa_associate_uniform_storage(ctx, p.shader_program, fp->Parameters); - - _mesa_update_shader_textures_used(p.shader_program, fp); - if (ctx->Driver.SamplerUniformChange) - ctx->Driver.SamplerUniformChange(ctx, fp->Target, fp); - if (!p.shader_program->LinkStatus) _mesa_problem(ctx, "Failed to link fixed function fragment shader: %s\n", p.shader_program->InfoLog); diff --git a/mesalib/src/mesa/main/formatquery.c b/mesalib/src/mesa/main/formatquery.c index bd895e874..78c5fbe5e 100644 --- a/mesalib/src/mesa/main/formatquery.c +++ b/mesalib/src/mesa/main/formatquery.c @@ -59,9 +59,10 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: - /* Mesa does not currently support GL_ARB_texture_multisample, so these - * enums are not valid on this implementation either. - */ + /* These enums are only valid if ARB_texture_multisample is supported */ + if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample) + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(target=%s)", @@ -96,7 +97,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, switch (pname) { case GL_SAMPLES: - count = ctx->Driver.QuerySamplesForFormat(ctx, internalformat, buffer); + count = ctx->Driver.QuerySamplesForFormat(ctx, target, + internalformat, buffer); break; case GL_NUM_SAMPLE_COUNTS: { /* The driver can return 0, and we should pass that along to the @@ -115,7 +117,7 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, * returned." */ const size_t num_samples = - ctx->Driver.QuerySamplesForFormat(ctx, internalformat, buffer); + ctx->Driver.QuerySamplesForFormat(ctx, target, internalformat, buffer); /* QuerySamplesForFormat writes some stuff to buffer, so we have to * separately over-write it with the requested value. diff --git a/mesalib/src/mesa/main/framebuffer.c b/mesalib/src/mesa/main/framebuffer.c index d3abc2b30..619aaa337 100644 --- a/mesalib/src/mesa/main/framebuffer.c +++ b/mesalib/src/mesa/main/framebuffer.c @@ -923,10 +923,10 @@ _mesa_get_color_read_type(struct gl_context *ctx) * Returns the read renderbuffer for the specified format. */ struct gl_renderbuffer * -_mesa_get_read_renderbuffer_for_format(struct gl_context *ctx, +_mesa_get_read_renderbuffer_for_format(const struct gl_context *ctx, GLenum format) { - struct gl_framebuffer *rfb = ctx->ReadBuffer; + const struct gl_framebuffer *rfb = ctx->ReadBuffer; if (_mesa_is_color_format(format)) { return rfb->Attachment[rfb->_ColorReadBufferIndex].Renderbuffer; diff --git a/mesalib/src/mesa/main/framebuffer.h b/mesalib/src/mesa/main/framebuffer.h index 06db04925..9b94452d6 100644 --- a/mesalib/src/mesa/main/framebuffer.h +++ b/mesalib/src/mesa/main/framebuffer.h @@ -98,7 +98,7 @@ extern GLenum _mesa_get_color_read_format(struct gl_context *ctx); extern struct gl_renderbuffer * -_mesa_get_read_renderbuffer_for_format(struct gl_context *ctx, +_mesa_get_read_renderbuffer_for_format(const struct gl_context *ctx, GLenum format); extern void diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 83b6c8984..a0e7e281d 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1179,6 +1179,7 @@ struct gl_texture_object GLfloat Priority; /**< in [0,1] */ GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */ GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */ + GLint ImmutableLevels; /**< ES 3.0 / ARB_texture_view */ GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */ GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */ GLint CropRect[4]; /**< GL_OES_draw_texture */ @@ -1796,6 +1797,7 @@ struct gl_transform_feedback_state typedef enum { PROGRAM_TEMPORARY, /**< machine->Temporary[] */ + PROGRAM_ARRAY, /**< Arrays & Matrixes */ PROGRAM_INPUT, /**< machine->Inputs[] */ PROGRAM_OUTPUT, /**< machine->Outputs[] */ PROGRAM_LOCAL_PARAM, /**< gl_program->LocalParams[] */ diff --git a/mesalib/src/mesa/main/multisample.c b/mesalib/src/mesa/main/multisample.c index 248494615..b0f45d933 100644 --- a/mesalib/src/mesa/main/multisample.c +++ b/mesalib/src/mesa/main/multisample.c @@ -29,6 +29,7 @@ #include "main/multisample.h" #include "main/mtypes.h" #include "main/fbobject.h" +#include "main/glformats.h" /** @@ -112,3 +113,79 @@ _mesa_SampleMaski(GLuint index, GLbitfield mask) FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE); ctx->Multisample.SampleMaskValue = mask; } + + +/* Helper for checking a requested sample count against the limit + * for a particular (target, internalFormat) pair. The limit imposed, + * and the error generated, both depend on which extensions are supported. + * + * Returns a GL error enum, or GL_NO_ERROR if the requested sample count is + * acceptable. + */ +GLenum +_mesa_check_sample_count(struct gl_context *ctx, GLenum target, + GLenum internalFormat, GLsizei samples) +{ + /* If ARB_internalformat_query is supported, then treat its highest returned sample + * count as the absolute maximum for this format; it is allowed to exceed MAX_SAMPLES. + * + * From the ARB_internalformat_query spec: + * + * "If then the error INVALID_OPERATION is generated." + */ + if (ctx->Extensions.ARB_internalformat_query) { + GLint buffer[16]; + int count = ctx->Driver.QuerySamplesForFormat(ctx, target, internalFormat, buffer); + int limit = count ? buffer[0] : -1; + + return samples > limit ? GL_INVALID_OPERATION : GL_NO_ERROR; + } + + /* If ARB_texture_multisample is supported, we have separate limits, + * which may be lower than MAX_SAMPLES: + * + * From the ARB_texture_multisample spec, when describing the operation + * of RenderbufferStorageMultisample: + * + * "If is a signed or unsigned integer format and + * is greater than the value of MAX_INTEGER_SAMPLES, then the + * error INVALID_OPERATION is generated" + * + * And when describing the operation of TexImage*Multisample: + * + * "The error INVALID_OPERATION may be generated if any of the following are true: + * + * * is a depth/stencil-renderable format and + * is greater than the value of MAX_DEPTH_TEXTURE_SAMPLES + * * is a color-renderable format and is + * grater than the value of MAX_COLOR_TEXTURE_SAMPLES + * * is a signed or unsigned integer format and + * is greater than the value of MAX_INTEGER_SAMPLES + */ + + if (ctx->Extensions.ARB_texture_multisample) { + if (_mesa_is_enum_format_integer(internalFormat)) + return samples > ctx->Const.MaxIntegerSamples ? GL_INVALID_OPERATION : GL_NO_ERROR; + + if (target == GL_TEXTURE_2D_MULTISAMPLE || + target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) { + + if (_mesa_is_depth_or_stencil_format(internalFormat)) + return samples > ctx->Const.MaxDepthTextureSamples + ? GL_INVALID_OPERATION : GL_NO_ERROR; + else + return samples > ctx->Const.MaxColorTextureSamples + ? GL_INVALID_OPERATION : GL_NO_ERROR; + } + } + + /* No more specific limit is available, so just use MAX_SAMPLES: + * + * On p205 of the GL3.1 spec: + * + * "... or if samples is greater than MAX_SAMPLES, then the error + * INVALID_VALUE is generated" + */ + return samples > ctx->Const.MaxSamples ? GL_INVALID_VALUE : GL_NO_ERROR; +} diff --git a/mesalib/src/mesa/main/multisample.h b/mesalib/src/mesa/main/multisample.h index 9e6b8e0d3..f2f01de5c 100644 --- a/mesalib/src/mesa/main/multisample.h +++ b/mesalib/src/mesa/main/multisample.h @@ -44,4 +44,9 @@ _mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat* val); extern void GLAPIENTRY _mesa_SampleMaski(GLuint index, GLbitfield mask); + +extern GLenum +_mesa_check_sample_count(struct gl_context *ctx, GLenum target, + GLenum internalFormat, GLsizei samples); + #endif diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c index 2f130ae9a..d3d09dea3 100644 --- a/mesalib/src/mesa/main/readpix.c +++ b/mesalib/src/mesa/main/readpix.c @@ -41,11 +41,212 @@ /** - * Tries to implement glReadPixels() of GL_DEPTH_COMPONENT using memcpy of the - * mapping. + * Return true if the conversion L=R+G+B is needed. */ static GLboolean -fast_read_depth_pixels( struct gl_context *ctx, +need_rgb_to_luminance_conversion(gl_format texFormat, GLenum format) +{ + GLenum baseTexFormat = _mesa_get_format_base_format(texFormat); + + return (baseTexFormat == GL_RG || + baseTexFormat == GL_RGB || + baseTexFormat == GL_RGBA) && + (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA); +} + + +/** + * Return transfer op flags for this ReadPixels operation. + */ +static GLbitfield +get_readpixels_transfer_ops(const struct gl_context *ctx, gl_format texFormat, + GLenum format, GLenum type, GLboolean uses_blit) +{ + GLbitfield transferOps = ctx->_ImageTransferState; + + if (format == GL_DEPTH_COMPONENT || + format == GL_DEPTH_STENCIL || + format == GL_STENCIL_INDEX) { + return 0; + } + + /* Pixel transfer ops (scale, bias, table lookup) do not apply + * to integer formats. + */ + if (_mesa_is_enum_format_integer(format)) { + return 0; + } + + if (uses_blit) { + /* For blit-based ReadPixels packing, the clamping is done automatically + * unless the type is float. */ + if (ctx->Color._ClampReadColor == GL_TRUE && + (type == GL_FLOAT || type == GL_HALF_FLOAT)) { + transferOps |= IMAGE_CLAMP_BIT; + } + } + else { + /* For CPU-based ReadPixels packing, the clamping must always be done + * for non-float types, */ + if (ctx->Color._ClampReadColor == GL_TRUE || + (type != GL_FLOAT && type != GL_HALF_FLOAT)) { + transferOps |= IMAGE_CLAMP_BIT; + } + } + + /* If the format is unsigned normalized, we can ignore clamping + * because the values are already in the range [0,1] so it won't + * have any effect anyway. + */ + if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED && + !need_rgb_to_luminance_conversion(texFormat, format)) { + transferOps &= ~IMAGE_CLAMP_BIT; + } + + return transferOps; +} + + +/** + * Return true if memcpy cannot be used for ReadPixels. + * + * If uses_blit is true, the function returns true if a simple 3D engine blit + * cannot be used for ReadPixels packing. + * + * NOTE: This doesn't take swizzling and format conversions between + * the readbuffer and the pixel pack buffer into account. + */ +GLboolean +_mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format, + GLenum type, GLboolean uses_blit) +{ + struct gl_renderbuffer *rb = + _mesa_get_read_renderbuffer_for_format(ctx, format); + GLenum srcType; + + ASSERT(rb); + + /* There are different rules depending on the base format. */ + switch (format) { + case GL_DEPTH_STENCIL: + return !_mesa_has_depthstencil_combined(ctx->ReadBuffer) || + ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f || + ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || + ctx->Pixel.MapStencilFlag; + + case GL_DEPTH_COMPONENT: + return ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f; + + case GL_STENCIL_INDEX: + return ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || + ctx->Pixel.MapStencilFlag; + + default: + /* Color formats. */ + if (need_rgb_to_luminance_conversion(rb->Format, format)) { + return GL_TRUE; + } + + /* Conversion between signed and unsigned integers needs masking + * (it isn't just memcpy). */ + srcType = _mesa_get_format_datatype(rb->Format); + + if ((srcType == GL_INT && + (type == GL_UNSIGNED_INT || + type == GL_UNSIGNED_SHORT || + type == GL_UNSIGNED_BYTE)) || + (srcType == GL_UNSIGNED_INT && + (type == GL_INT || + type == GL_SHORT || + type == GL_BYTE))) { + return GL_TRUE; + } + + /* And finally, see if there are any transfer ops. */ + return get_readpixels_transfer_ops(ctx, rb->Format, format, type, + uses_blit) != 0; + } + return GL_FALSE; +} + + +static GLboolean +readpixels_can_use_memcpy(const struct gl_context *ctx, GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing) +{ + struct gl_renderbuffer *rb = + _mesa_get_read_renderbuffer_for_format(ctx, format); + + ASSERT(rb); + + if (_mesa_readpixels_needs_slow_path(ctx, format, type, GL_FALSE)) { + return GL_FALSE; + } + + /* The base internal format and the base Mesa format must match. */ + if (rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) { + return GL_FALSE; + } + + /* The Mesa format must match the input format and type. */ + if (!_mesa_format_matches_format_and_type(rb->Format, format, type, + packing->SwapBytes)) { + return GL_FALSE; + } + + return GL_TRUE; +} + + +static GLboolean +readpixels_memcpy(struct gl_context *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + GLvoid *pixels, + const struct gl_pixelstore_attrib *packing) +{ + struct gl_renderbuffer *rb = + _mesa_get_read_renderbuffer_for_format(ctx, format); + GLubyte *dst, *map; + int dstStride, stride, j, texelBytes; + + /* Fail if memcpy cannot be used. */ + if (!readpixels_can_use_memcpy(ctx, format, type, packing)) { + return GL_FALSE; + } + + dstStride = _mesa_image_row_stride(packing, width, format, type); + dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, + format, type, 0, 0); + + ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, + &map, &stride); + if (!map) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); + return GL_TRUE; /* don't bother trying the slow path */ + } + + texelBytes = _mesa_get_format_bytes(rb->Format); + + /* memcpy*/ + for (j = 0; j < height; j++) { + memcpy(dst, map, width * texelBytes); + dst += dstStride; + map += stride; + } + + ctx->Driver.UnmapRenderbuffer(ctx, rb); + return GL_TRUE; +} + + +/** + * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT, + * GL_UNSIGNED_INT. + */ +static GLboolean +read_uint_depth_pixels( struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, GLvoid *pixels, @@ -65,10 +266,6 @@ fast_read_depth_pixels( struct gl_context *ctx, if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED) return GL_FALSE; - if (!((type == GL_UNSIGNED_SHORT && rb->Format == MESA_FORMAT_Z16) || - type == GL_UNSIGNED_INT)) - return GL_FALSE; - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, &map, &stride); @@ -82,12 +279,7 @@ fast_read_depth_pixels( struct gl_context *ctx, GL_DEPTH_COMPONENT, type, 0, 0); for (j = 0; j < height; j++) { - if (type == GL_UNSIGNED_INT) { - _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst); - } else { - ASSERT(type == GL_UNSIGNED_SHORT && rb->Format == MESA_FORMAT_Z16); - memcpy(dst, map, width * 2); - } + _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst); map += stride; dst += dstStride; @@ -123,8 +315,10 @@ read_depth_pixels( struct gl_context *ctx, ASSERT(x + width <= (GLint) rb->Width); ASSERT(y + height <= (GLint) rb->Height); - if (fast_read_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) + if (type == GL_UNSIGNED_INT && + read_uint_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) { return; + } dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type); dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, @@ -212,21 +406,20 @@ read_stencil_pixels( struct gl_context *ctx, /** - * Try to do glReadPixels of RGBA data using a simple memcpy or swizzle. + * Try to do glReadPixels of RGBA data using swizzle. * \return GL_TRUE if successful, GL_FALSE otherwise (use the slow path) */ static GLboolean -fast_read_rgba_pixels_memcpy( struct gl_context *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - GLbitfield transferOps ) +read_rgba_pixels_swizzle(struct gl_context *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + GLvoid *pixels, + const struct gl_pixelstore_attrib *packing) { struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; GLubyte *dst, *map; - int dstStride, stride, j, texelBytes; + int dstStride, stride, j; GLboolean swizzle_rb = GL_FALSE, copy_xrgb = GL_FALSE; /* XXX we could check for other swizzle/special cases here as needed */ @@ -242,19 +435,9 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx, !ctx->Pack.SwapBytes) { copy_xrgb = GL_TRUE; } - else if (!_mesa_format_matches_format_and_type(rb->Format, format, type, - ctx->Pack.SwapBytes)) - return GL_FALSE; - - /* If the format is unsigned normalized then we can ignore clamping - * because the values are already in the range [0,1] so it won't - * have any effect anyway. - */ - if (_mesa_get_format_datatype(rb->Format) == GL_UNSIGNED_NORMALIZED) - transferOps &= ~IMAGE_CLAMP_BIT; - - if (transferOps) + else { return GL_FALSE; + } dstStride = _mesa_image_row_stride(packing, width, format, type); dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, @@ -267,8 +450,6 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx, return GL_TRUE; /* don't bother trying the slow path */ } - texelBytes = _mesa_get_format_bytes(rb->Format); - if (swizzle_rb) { /* swap R/B */ for (j = 0; j < height; j++) { @@ -294,13 +475,6 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx, dst += dstStride; map += stride; } - } else { - /* just memcpy */ - for (j = 0; j < height; j++) { - memcpy(dst, map, width * texelBytes); - dst += dstStride; - map += stride; - } } ctx->Driver.UnmapRenderbuffer(ctx, rb); @@ -379,22 +553,20 @@ read_rgba_pixels( struct gl_context *ctx, GLenum format, GLenum type, GLvoid *pixels, const struct gl_pixelstore_attrib *packing ) { - GLbitfield transferOps = ctx->_ImageTransferState; + GLbitfield transferOps; struct gl_framebuffer *fb = ctx->ReadBuffer; struct gl_renderbuffer *rb = fb->_ColorReadBuffer; if (!rb) return; - if ((ctx->Color._ClampReadColor == GL_TRUE || type != GL_FLOAT) && - !_mesa_is_enum_format_integer(format)) { - transferOps |= IMAGE_CLAMP_BIT; - } + transferOps = get_readpixels_transfer_ops(ctx, rb->Format, format, type, + GL_FALSE); /* Try the optimized paths first. */ - if (fast_read_rgba_pixels_memcpy(ctx, x, y, width, height, - format, type, pixels, packing, - transferOps)) { + if (!transferOps && + read_rgba_pixels_swizzle(ctx, x, y, width, height, + format, type, pixels, packing)) { return; } @@ -649,6 +821,14 @@ _mesa_readpixels(struct gl_context *ctx, pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels); if (pixels) { + /* Try memcpy first. */ + if (readpixels_memcpy(ctx, x, y, width, height, format, type, + pixels, packing)) { + _mesa_unmap_pbo_dest(ctx, &clippedPacking); + return; + } + + /* Otherwise take the slow path. */ switch (format) { case GL_STENCIL_INDEX: read_stencil_pixels(ctx, x, y, width, height, type, pixels, diff --git a/mesalib/src/mesa/main/readpix.h b/mesalib/src/mesa/main/readpix.h index 5a5f73f52..7491c22ff 100644 --- a/mesalib/src/mesa/main/readpix.h +++ b/mesalib/src/mesa/main/readpix.h @@ -33,6 +33,10 @@ struct gl_context; struct gl_pixelstore_attrib; +extern GLboolean +_mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format, + GLenum type, GLboolean uses_blit); + extern void _mesa_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height, diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c index 7299a4b23..74b09ef2c 100644 --- a/mesalib/src/mesa/main/texgetimage.c +++ b/mesalib/src/mesa/main/texgetimage.c @@ -518,6 +518,7 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions, if (type_needs_clamping(type)) { /* the returned image type can't have negative values */ if (dataType == GL_FLOAT || + dataType == GL_HALF_FLOAT || dataType == GL_SIGNED_NORMALIZED || format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) { diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 4042e7969..bc755ae79 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -40,6 +40,7 @@ #include "imports.h" #include "macros.h" #include "mfeatures.h" +#include "multisample.h" #include "state.h" #include "texcompress.h" #include "texcompress_cpal.h" @@ -4199,6 +4200,7 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, struct gl_texture_image *texImage; GLboolean sizeOK, dimensionsOK; gl_format texFormat; + GLenum sample_count_error; GET_CURRENT_CONTEXT(ctx); @@ -4225,35 +4227,13 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, return; } - if (_mesa_is_enum_format_integer(internalformat)) { - if (samples > ctx->Const.MaxIntegerSamples) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexImage%uDMultisample(samples>GL_MAX_INTEGER_SAMPLES)", - dims); - return; - } - } - else if (_mesa_is_depth_or_stencil_format(internalformat)) { - if (samples > ctx->Const.MaxDepthTextureSamples) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexImage%uDMultisample(samples>GL_MAX_DEPTH_TEXTURE_SAMPLES)", - dims); - return; - } - } - else { - if (samples > ctx->Const.MaxColorTextureSamples) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexImage%uDMultisample(samples>GL_MAX_COLOR_TEXTURE_SAMPLES)", - dims); - return; - } + sample_count_error = _mesa_check_sample_count(ctx, target, + internalformat, samples); + if (sample_count_error != GL_NO_ERROR) { + _mesa_error(ctx, sample_count_error, "glTexImage%uDMultisample(samples)", dims); + return; } - /* TODO: should ask the driver for the exact limit for this internalformat - * once IDR's internalformat_query bits land - */ - texObj = _mesa_get_current_tex_object(ctx, target); texImage = _mesa_get_tex_image(ctx, texObj, 0, 0); diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index 120845b4a..bd2f75170 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -1460,6 +1460,12 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) *params = (GLfloat) obj->Immutable; break; + case GL_TEXTURE_IMMUTABLE_LEVELS: + if (!_mesa_is_gles3(ctx)) + goto invalid_pname; + *params = (GLfloat) obj->ImmutableLevels; + break; + case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) goto invalid_pname; @@ -1637,6 +1643,12 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) *params = (GLint) obj->Immutable; break; + case GL_TEXTURE_IMMUTABLE_LEVELS: + if (!_mesa_is_gles3(ctx)) + goto invalid_pname; + *params = obj->ImmutableLevels; + break; + case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) goto invalid_pname; diff --git a/mesalib/src/mesa/main/texstorage.c b/mesalib/src/mesa/main/texstorage.c index 00f19bae5..675fd745b 100644 --- a/mesalib/src/mesa/main/texstorage.c +++ b/mesalib/src/mesa/main/texstorage.c @@ -397,6 +397,7 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, } texObj->Immutable = GL_TRUE; + texObj->ImmutableLevels = levels; } } diff --git a/mesalib/src/mesa/state_tracker/st_cb_blit.c b/mesalib/src/mesa/state_tracker/st_cb_blit.c index c463e3b04..50cab4294 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_blit.c +++ b/mesalib/src/mesa/state_tracker/st_cb_blit.c @@ -239,31 +239,22 @@ st_BlitFramebuffer(struct gl_context *ctx, /* depth and/or stencil blit */ /* get src/dst depth surfaces */ - struct gl_renderbuffer_attachment *srcDepth = - &readFB->Attachment[BUFFER_DEPTH]; - struct gl_renderbuffer_attachment *dstDepth = - &drawFB->Attachment[BUFFER_DEPTH]; - struct gl_renderbuffer_attachment *srcStencil = - &readFB->Attachment[BUFFER_STENCIL]; - struct gl_renderbuffer_attachment *dstStencil = - &drawFB->Attachment[BUFFER_STENCIL]; - struct st_renderbuffer *srcDepthRb = - st_renderbuffer(srcDepth->Renderbuffer); + st_renderbuffer(readFB->Attachment[BUFFER_DEPTH].Renderbuffer); struct st_renderbuffer *dstDepthRb = - st_renderbuffer(dstDepth->Renderbuffer); + st_renderbuffer(drawFB->Attachment[BUFFER_DEPTH].Renderbuffer); struct pipe_surface *dstDepthSurf = dstDepthRb ? dstDepthRb->surface : NULL; struct st_renderbuffer *srcStencilRb = - st_renderbuffer(srcStencil->Renderbuffer); + st_renderbuffer(readFB->Attachment[BUFFER_STENCIL].Renderbuffer); struct st_renderbuffer *dstStencilRb = - st_renderbuffer(dstStencil->Renderbuffer); + st_renderbuffer(drawFB->Attachment[BUFFER_STENCIL].Renderbuffer); struct pipe_surface *dstStencilSurf = dstStencilRb ? dstStencilRb->surface : NULL; - if (st_is_depth_stencil_combined(srcDepth, srcStencil) && - st_is_depth_stencil_combined(dstDepth, dstStencil)) { + if (_mesa_has_depthstencil_combined(readFB) && + _mesa_has_depthstencil_combined(drawFB)) { blit.mask = 0; if (mask & GL_DEPTH_BUFFER_BIT) blit.mask |= PIPE_MASK_Z; diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.c b/mesalib/src/mesa/state_tracker/st_cb_fbo.c index 87c5b048c..4452e523b 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_fbo.c +++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.c @@ -547,30 +547,6 @@ st_validate_attachment(struct gl_context *ctx, return valid; } - - -/** - * Check if two renderbuffer attachments name a combined depth/stencil - * renderbuffer. - */ -GLboolean -st_is_depth_stencil_combined(const struct gl_renderbuffer_attachment *depth, - const struct gl_renderbuffer_attachment *stencil) -{ - assert(depth && stencil); - - if (depth->Type == stencil->Type) { - if (depth->Type == GL_RENDERBUFFER_EXT && - depth->Renderbuffer == stencil->Renderbuffer) - return GL_TRUE; - - if (depth->Type == GL_TEXTURE && - depth->Texture == stencil->Texture) - return GL_TRUE; - } - - return GL_FALSE; -} /** diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.h b/mesalib/src/mesa/state_tracker/st_cb_fbo.h index 506fd06d6..461dbe985 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_fbo.h +++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.h @@ -76,9 +76,4 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw); extern void st_init_fbo_functions(struct dd_function_table *functions); -extern GLboolean -st_is_depth_stencil_combined(const struct gl_renderbuffer_attachment *depth, - const struct gl_renderbuffer_attachment *stencil); - - #endif /* ST_CB_FBO_H */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c index 6b824b161..bfed98870 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c @@ -25,35 +25,209 @@ * **************************************************************************/ - +#include "main/image.h" +#include "main/pbo.h" #include "main/imports.h" #include "main/readpix.h" +#include "main/enums.h" +#include "main/framebuffer.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "st_cb_fbo.h" #include "st_atom.h" #include "st_context.h" #include "st_cb_bitmap.h" #include "st_cb_readpixels.h" +#include "state_tracker/st_cb_texture.h" +#include "state_tracker/st_format.h" +#include "state_tracker/st_texture.h" /** - * The only special thing we need to do for the state tracker's - * glReadPixels is to validate state (to be sure we have up-to-date - * framebuffer surfaces) and flush the bitmap cache prior to reading. + * This uses a blit to copy the read buffer to a texture format which matches + * the format and type combo and then a fast read-back is done using memcpy. + * We can do arbitrary X/Y/Z/W/0/1 swizzling here as long as there is + * a format which matches the swizzling. + * + * If such a format isn't available, we fall back to _mesa_readpixels. + * + * NOTE: Some drivers use a blit to convert between tiled and linear + * texture layouts during texture uploads/downloads, so the blit + * we do here should be free in such cases. */ static void st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *pack, - GLvoid *dest) + GLvoid *pixels) { struct st_context *st = st_context(ctx); + struct gl_renderbuffer *rb = + _mesa_get_read_renderbuffer_for_format(ctx, format); + struct st_renderbuffer *strb = st_renderbuffer(rb); + struct pipe_context *pipe = st->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_resource *src; + struct pipe_resource *dst = NULL; + struct pipe_resource dst_templ; + enum pipe_format dst_format, src_format; + struct pipe_blit_info blit; + unsigned bind = PIPE_BIND_TRANSFER_READ; + struct pipe_transfer *tex_xfer; + ubyte *map = NULL; + /* Validate state (to be sure we have up-to-date framebuffer surfaces) + * and flush the bitmap cache prior to reading. */ st_validate_state(st); st_flush_bitmap_cache(st); - _mesa_readpixels(ctx, x, y, width, height, format, type, pack, dest); -} + if (!st->prefer_blit_based_texture_transfer) { + goto fallback; + } + + /* This must be done after state validation. */ + src = strb->texture; + + /* XXX Fallback for depth-stencil formats due to an incomplete + * stencil blit implementation in some drivers. */ + if (format == GL_DEPTH_STENCIL) { + goto fallback; + } + + /* We are creating a texture of the size of the region being read back. + * Need to check for NPOT texture support. */ + if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES) && + (!util_is_power_of_two(width) || + !util_is_power_of_two(height))) { + goto fallback; + } + + /* If the base internal format and the texture format don't match, we have + * to use the slow path. */ + if (rb->_BaseFormat != + _mesa_get_format_base_format(rb->Format)) { + goto fallback; + } + + /* See if the texture format already matches the format and type, + * in which case the memcpy-based fast path will likely be used and + * we don't have to blit. */ + if (_mesa_format_matches_format_and_type(rb->Format, format, + type, pack->SwapBytes)) { + goto fallback; + } + + if (_mesa_readpixels_needs_slow_path(ctx, format, type, GL_TRUE)) { + goto fallback; + } + + /* Convert the source format to what is expected by ReadPixels + * and see if it's supported. */ + src_format = util_format_linear(src->format); + src_format = util_format_luminance_to_red(src_format); + src_format = util_format_intensity_to_red(src_format); + + if (!src_format || + !screen->is_format_supported(screen, src_format, src->target, + src->nr_samples, + PIPE_BIND_SAMPLER_VIEW)) { + printf("fallback: src format unsupported %s\n", util_format_short_name(src_format)); + goto fallback; + } + + if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL) + bind |= PIPE_BIND_DEPTH_STENCIL; + else + bind |= PIPE_BIND_RENDER_TARGET; + + /* Choose the destination format by finding the best match + * for the format+type combo. */ + dst_format = st_choose_matching_format(screen, bind, format, type, + pack->SwapBytes); + if (dst_format == PIPE_FORMAT_NONE) { + printf("fallback: no matching format for %s, %s\n", + _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type)); + goto fallback; + } + + /* create the destination texture */ + memset(&dst_templ, 0, sizeof(dst_templ)); + dst_templ.target = PIPE_TEXTURE_2D; + dst_templ.format = dst_format; + dst_templ.bind = bind; + dst_templ.usage = PIPE_USAGE_STAGING; + + st_gl_texture_dims_to_pipe_dims(GL_TEXTURE_2D, width, height, 1, + &dst_templ.width0, &dst_templ.height0, + &dst_templ.depth0, &dst_templ.array_size); + + dst = screen->resource_create(screen, &dst_templ); + if (!dst) { + goto fallback; + } + + blit.src.resource = src; + blit.src.level = strb->rtt_level; + blit.src.format = src_format; + blit.dst.resource = dst; + blit.dst.level = 0; + blit.dst.format = dst->format; + blit.src.box.x = x; + blit.dst.box.x = 0; + blit.src.box.y = y; + blit.dst.box.y = 0; + blit.src.box.z = strb->rtt_face + strb->rtt_slice; + blit.dst.box.z = 0; + blit.src.box.width = blit.dst.box.width = width; + blit.src.box.height = blit.dst.box.height = height; + blit.src.box.depth = blit.dst.box.depth = 1; + blit.mask = st_get_blit_mask(rb->_BaseFormat, format); + blit.filter = PIPE_TEX_FILTER_NEAREST; + blit.scissor_enable = FALSE; + + if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { + blit.src.box.y = rb->Height - blit.src.box.y; + blit.src.box.height = -blit.src.box.height; + } + + /* blit */ + st->pipe->blit(st->pipe, &blit); + + /* map resources */ + pixels = _mesa_map_pbo_dest(ctx, pack, pixels); + + map = pipe_transfer_map_3d(pipe, dst, 0, PIPE_TRANSFER_READ, + 0, 0, 0, width, height, 1, &tex_xfer); + if (!map) { + _mesa_unmap_pbo_dest(ctx, pack); + pipe_resource_reference(&dst, NULL); + goto fallback; + } + + /* memcpy data into a user buffer */ + { + const uint bytesPerRow = width * util_format_get_blocksize(dst_format); + GLuint row; + + for (row = 0; row < height; row++) { + GLvoid *dest = _mesa_image_address3d(pack, pixels, + width, height, format, + type, 0, row, 0); + memcpy(dest, map, bytesPerRow); + map += tex_xfer->stride; + } + } + + pipe_transfer_unmap(pipe, tex_xfer); + _mesa_unmap_pbo_dest(ctx, pack); + pipe_resource_reference(&dst, NULL); + return; + +fallback: + _mesa_readpixels(ctx, x, y, width, height, format, type, pack, pixels); +} void st_init_readpixels_functions(struct dd_function_table *functions) { diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index c922a3164..94fbbf7be 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -68,7 +68,7 @@ #define DBG if (0) printf -static enum pipe_texture_target +enum pipe_texture_target gl_target_to_pipe(GLenum target) { switch (target) { @@ -542,8 +542,8 @@ prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage, * Return a writemask for the gallium blit. The parameters can be base * formats or "format" from glDrawPixels/glTexImage/glGetTexImage. */ -static unsigned -get_blit_mask(GLenum srcFormat, GLenum dstFormat) +unsigned +st_get_blit_mask(GLenum srcFormat, GLenum dstFormat) { switch (dstFormat) { case GL_DEPTH_STENCIL: @@ -608,6 +608,10 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims, unsigned bind; GLubyte *map; + if (!st->prefer_blit_based_texture_transfer) { + goto fallback; + } + if (!dst) { goto fallback; } @@ -769,7 +773,7 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims, blit.src.box.width = blit.dst.box.width = width; blit.src.box.height = blit.dst.box.height = height; blit.src.box.depth = blit.dst.box.depth = depth; - blit.mask = get_blit_mask(format, texImage->_BaseFormat); + blit.mask = st_get_blit_mask(format, texImage->_BaseFormat); blit.filter = PIPE_TEX_FILTER_NEAREST; blit.scissor_enable = FALSE; @@ -860,6 +864,10 @@ st_GetTexImage(struct gl_context * ctx, ubyte *map = NULL; boolean done = FALSE; + if (!st->prefer_blit_based_texture_transfer) { + goto fallback; + } + if (!stImage->pt) { goto fallback; } @@ -996,7 +1004,7 @@ st_GetTexImage(struct gl_context * ctx, blit.src.box.width = blit.dst.box.width = width; blit.src.box.height = blit.dst.box.height = height; blit.src.box.depth = blit.dst.box.depth = depth; - blit.mask = get_blit_mask(texImage->_BaseFormat, format); + blit.mask = st_get_blit_mask(texImage->_BaseFormat, format); blit.filter = PIPE_TEX_FILTER_NEAREST; blit.scissor_enable = FALSE; @@ -1370,7 +1378,7 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims, blit.dst.box.width = width; blit.dst.box.height = height; blit.dst.box.depth = 1; - blit.mask = get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat); + blit.mask = st_get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat); blit.filter = PIPE_TEX_FILTER_NEAREST; /* 1D array textures need special treatment. diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.h b/mesalib/src/mesa/state_tracker/st_cb_texture.h index 27956bcc2..7f70d0b25 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.h +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.h @@ -38,6 +38,12 @@ struct gl_texture_object; struct pipe_context; struct st_context; +extern enum pipe_texture_target +gl_target_to_pipe(GLenum target); + +unsigned +st_get_blit_mask(GLenum srcFormat, GLenum dstFormat); + extern GLboolean st_finalize_texture(struct gl_context *ctx, struct pipe_context *pipe, diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c index f9a584ba0..cc87f2bb3 100644 --- a/mesalib/src/mesa/state_tracker/st_context.c +++ b/mesalib/src/mesa/state_tracker/st_context.c @@ -182,6 +182,11 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe, st->has_stencil_export = screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT); st->has_shader_model3 = screen->get_param(screen, PIPE_CAP_SM3); + st->prefer_blit_based_texture_transfer = screen->get_param(screen, + PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER); + + st->needs_texcoord_semantic = + screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD); /* GL limits and extensions */ st_init_limits(st); diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index b9a98cd05..8786a036f 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -84,6 +84,9 @@ struct st_context boolean has_stencil_export; /**< can do shader stencil export? */ boolean has_time_elapsed; boolean has_shader_model3; + boolean prefer_blit_based_texture_transfer; + + boolean needs_texcoord_semantic; /* On old libGL's for linux we need to invalidate the drawables * on glViewpport calls, this is set via a option. diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c index 5fd44e76d..a15706a03 100644 --- a/mesalib/src/mesa/state_tracker/st_format.c +++ b/mesalib/src/mesa/state_tracker/st_format.c @@ -1769,13 +1769,15 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target, * Called via ctx->Driver.ChooseTextureFormat(). */ size_t -st_QuerySamplesForFormat(struct gl_context *ctx, GLenum internalFormat, - int samples[16]) +st_QuerySamplesForFormat(struct gl_context *ctx, GLenum target, + GLenum internalFormat, int samples[16]) { struct st_context *st = st_context(ctx); enum pipe_format format; unsigned i, bind, num_sample_counts = 0; + (void) target; + if (_mesa_is_depth_or_stencil_format(internalFormat)) bind = PIPE_BIND_DEPTH_STENCIL; else diff --git a/mesalib/src/mesa/state_tracker/st_format.h b/mesalib/src/mesa/state_tracker/st_format.h index 3db409b74..0a1c18d92 100644 --- a/mesalib/src/mesa/state_tracker/st_format.h +++ b/mesalib/src/mesa/state_tracker/st_format.h @@ -67,8 +67,8 @@ st_ChooseTextureFormat(struct gl_context * ctx, GLenum target, GLenum format, GLenum type); size_t -st_QuerySamplesForFormat(struct gl_context *ctx, GLenum internalFormat, - int samples[16]); +st_QuerySamplesForFormat(struct gl_context *ctx, GLenum target, + GLenum internalFormat, int samples[16]); /* can we use a sampler view to translate these formats only used to make TFP so far */ diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 0cef092d3..e3718eeda 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -85,6 +85,11 @@ extern "C" { */ #define MAX_TEMPS 4096 +/** + * Maximum number of arrays + */ +#define MAX_ARRAYS 256 + /* will be 4 for GLSL 4.00 */ #define MAX_GLSL_TEXTURE_OFFSET 1 @@ -315,9 +320,11 @@ public: int next_temp; + unsigned array_sizes[MAX_ARRAYS]; + unsigned next_array; + int num_address_regs; int samplers_used; - bool indirect_addr_temps; bool indirect_addr_consts; int glsl_version; @@ -549,9 +556,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, /* Update indirect addressing status used by TGSI */ if (dst.reladdr) { switch(dst.file) { - case PROGRAM_TEMPORARY: - this->indirect_addr_temps = true; - break; case PROGRAM_LOCAL_PARAM: case PROGRAM_ENV_PARAM: case PROGRAM_STATE_VAR: @@ -570,9 +574,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, for (i=0; i<3; i++) { if(inst->src[i].reladdr) { switch(inst->src[i].file) { - case PROGRAM_TEMPORARY: - this->indirect_addr_temps = true; - break; case PROGRAM_LOCAL_PARAM: case PROGRAM_ENV_PARAM: case PROGRAM_STATE_VAR: @@ -1005,17 +1006,26 @@ glsl_to_tgsi_visitor::get_temp(const glsl_type *type) st_src_reg src; src.type = native_integers ? type->base_type : GLSL_TYPE_FLOAT; - src.file = PROGRAM_TEMPORARY; - src.index = next_temp; src.reladdr = NULL; - next_temp += type_size(type); + src.negate = 0; + + if (type->is_array() || type->is_matrix()) { + src.file = PROGRAM_ARRAY; + src.index = next_array << 16 | 0x8000; + array_sizes[next_array] = type_size(type); + ++next_array; + + } else { + src.file = PROGRAM_TEMPORARY; + src.index = next_temp; + next_temp += type_size(type); + } if (type->is_array() || type->is_record()) { src.swizzle = SWIZZLE_NOOP; } else { src.swizzle = swizzle_for_size(type->vector_elements); } - src.negate = 0; return src; } @@ -1078,13 +1088,11 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir) */ assert((int) ir->num_state_slots == type_size(ir->type)); - storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY, - this->next_temp); - this->variables.push_tail(storage); - this->next_temp += type_size(ir->type); + dst = st_dst_reg(get_temp(ir->type)); + + storage = new(mem_ctx) variable_storage(ir, dst.file, dst.index); - dst = st_dst_reg(st_src_reg(PROGRAM_TEMPORARY, storage->index, - native_integers ? ir->type->base_type : GLSL_TYPE_FLOAT)); + this->variables.push_tail(storage); } @@ -2052,11 +2060,11 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir) break; case ir_var_auto: case ir_var_temporary: - entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY, - this->next_temp); + st_src_reg src = get_temp(var->type); + + entry = new(mem_ctx) variable_storage(var, src.file, src.index); this->variables.push_tail(entry); - next_temp += type_size(var->type); break; } @@ -2574,11 +2582,10 @@ glsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig) storage = find_variable_storage(param); assert(!storage); - storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, - this->next_temp); - this->variables.push_tail(storage); + st_src_reg src = get_temp(param->type); - this->next_temp += type_size(param->type); + storage = new(mem_ctx) variable_storage(param, src.file, src.index); + this->variables.push_tail(storage); } if (!sig->return_type->is_void()) { @@ -2978,12 +2985,12 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor() { result.file = PROGRAM_UNDEFINED; next_temp = 1; + next_array = 0; next_signature_id = 1; num_immediates = 0; current_function = NULL; num_address_regs = 0; samplers_used = 0; - indirect_addr_temps = false; indirect_addr_consts = false; glsl_version = 0; native_integers = false; @@ -3183,7 +3190,8 @@ glsl_to_tgsi_visitor::simplify_cmp(void) assert(inst->dst.index < MAX_TEMPS); prevWriteMask = tempWrites[inst->dst.index]; tempWrites[inst->dst.index] |= inst->dst.writemask; - } + } else + break; /* For a CMP to be considered a conditional write, the destination * register and source register two must be the same. */ @@ -3821,7 +3829,6 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp, v->next_temp = original->next_temp; v->num_address_regs = original->num_address_regs; v->samplers_used = prog->SamplersUsed = original->samplers_used; - v->indirect_addr_temps = original->indirect_addr_temps; v->indirect_addr_consts = original->indirect_addr_consts; memcpy(&v->immediates, &original->immediates, sizeof(v->immediates)); v->num_immediates = original->num_immediates; @@ -3952,7 +3959,6 @@ get_bitmap_visitor(struct st_fragment_program *fp, v->next_temp = original->next_temp; v->num_address_regs = original->num_address_regs; v->samplers_used = prog->SamplersUsed = original->samplers_used; - v->indirect_addr_temps = original->indirect_addr_temps; v->indirect_addr_consts = original->indirect_addr_consts; memcpy(&v->immediates, &original->immediates, sizeof(v->immediates)); v->num_immediates = original->num_immediates; @@ -4014,6 +4020,7 @@ struct st_translate { struct ureg_program *ureg; struct ureg_dst temps[MAX_TEMPS]; + struct ureg_dst arrays[MAX_ARRAYS]; struct ureg_src *constants; struct ureg_src *immediates; struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS]; @@ -4022,6 +4029,8 @@ struct st_translate { struct ureg_src samplers[PIPE_MAX_SAMPLERS]; struct ureg_src systemValues[SYSTEM_VALUE_MAX]; + unsigned array_sizes[MAX_ARRAYS]; + const GLuint *inputMapping; const GLuint *outputMapping; @@ -4132,16 +4141,34 @@ dst_register(struct st_translate *t, gl_register_file file, GLuint index) { + unsigned array; + switch(file) { case PROGRAM_UNDEFINED: return ureg_dst_undef(); case PROGRAM_TEMPORARY: + assert(index >= 0); + assert(index < (int) Elements(t->temps)); + if (ureg_dst_is_undef(t->temps[index])) t->temps[index] = ureg_DECL_local_temporary(t->ureg); return t->temps[index]; + case PROGRAM_ARRAY: + array = index >> 16; + + assert(array >= 0); + assert(array < (int) Elements(t->arrays)); + + if (ureg_dst_is_undef(t->arrays[array])) + t->arrays[array] = ureg_DECL_array_temporary( + t->ureg, t->array_sizes[array], TRUE); + + return ureg_dst_array_offset(t->arrays[array], + (int)(index & 0xFFFF) - 0x8000); + case PROGRAM_OUTPUT: if (t->procType == TGSI_PROCESSOR_VERTEX) assert(index < VARYING_SLOT_MAX); @@ -4176,11 +4203,8 @@ src_register(struct st_translate *t, return ureg_src_undef(); case PROGRAM_TEMPORARY: - assert(index >= 0); - assert(index < (int) Elements(t->temps)); - if (ureg_dst_is_undef(t->temps[index])) - t->temps[index] = ureg_DECL_local_temporary(t->ureg); - return ureg_src(t->temps[index]); + case PROGRAM_ARRAY: + return ureg_src(dst_register(t, file, index)); case PROGRAM_ENV_PARAM: case PROGRAM_LOCAL_PARAM: @@ -4262,8 +4286,10 @@ translate_dst(struct st_translate *t, } } - if (dst_reg->reladdr != NULL) + if (dst_reg->reladdr != NULL) { + assert(dst_reg->file != PROGRAM_TEMPORARY); dst = ureg_dst_indirect(dst, ureg_src(t->address[0])); + } return dst; } @@ -4286,26 +4312,8 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg) src = ureg_negate(src); if (src_reg->reladdr != NULL) { - /* Normally ureg_src_indirect() would be used here, but a stupid compiler - * bug in g++ makes ureg_src_indirect (an inline C function) erroneously - * set the bit for src.Negate. So we have to do the operation manually - * here to work around the compiler's problems. */ - /*src = ureg_src_indirect(src, ureg_src(t->address[0]));*/ - struct ureg_src addr = ureg_src(t->address[0]); - src.Indirect = 1; - src.IndirectFile = addr.File; - src.IndirectIndex = addr.Index; - src.IndirectSwizzle = addr.SwizzleX; - - if (src_reg->file != PROGRAM_INPUT && - src_reg->file != PROGRAM_OUTPUT) { - /* If src_reg->index was negative, it was set to zero in - * src_register(). Reassign it now. But don't do this - * for input/output regs since they get remapped while - * const buffers don't. - */ - src.Index = src_reg->index; - } + assert(src_reg->file != PROGRAM_TEMPORARY); + src = ureg_src_indirect(src, ureg_src(t->address[0])); } return src; @@ -4820,16 +4828,9 @@ st_translate_program( } } - if (program->indirect_addr_temps) { - /* If temps are accessed with indirect addressing, declare temporaries - * in sequential order. Else, we declare them on demand elsewhere. - * (Note: the number of temporaries is equal to program->next_temp) - */ - for (i = 0; i < (unsigned)program->next_temp; i++) { - /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */ - t->temps[i] = ureg_DECL_local_temporary(t->ureg); - } - } + /* Copy over array sizes + */ + memcpy(t->array_sizes, program->array_sizes, sizeof(unsigned) * program->next_array); /* Emit constants and uniforms. TGSI uses a single index space for these, * so we put all the translated regs in t->constants. @@ -5064,16 +5065,9 @@ get_mesa_program(struct gl_context *ctx, v->copy_propagate(); while (v->eliminate_dead_code_advanced()); - /* FIXME: These passes to optimize temporary registers don't work when there - * is indirect addressing of the temporary register space. We need proper - * array support so that we don't have to give up these passes in every - * shader that uses arrays. - */ - if (!v->indirect_addr_temps) { - v->eliminate_dead_code(); - v->merge_registers(); - v->renumber_registers(); - } + v->eliminate_dead_code(); + v->merge_registers(); + v->renumber_registers(); /* Write the END instruction. */ v->emit(NULL, TGSI_OPCODE_END); diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c index 6af8df316..7a38da84f 100644 --- a/mesalib/src/mesa/state_tracker/st_program.c +++ b/mesalib/src/mesa/state_tracker/st_program.c @@ -177,6 +177,7 @@ void st_prepare_vertex_program(struct gl_context *ctx, struct st_vertex_program *stvp) { + struct st_context *st = st_context(ctx); GLuint attr; stvp->num_inputs = 0; @@ -267,7 +268,8 @@ st_prepare_vertex_program(struct gl_context *ctx, case VARYING_SLOT_TEX5: case VARYING_SLOT_TEX6: case VARYING_SLOT_TEX7: - stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + stvp->output_semantic_name[slot] = st->needs_texcoord_semantic ? + TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC; stvp->output_semantic_index[slot] = attr - VARYING_SLOT_TEX0; break; @@ -275,10 +277,8 @@ st_prepare_vertex_program(struct gl_context *ctx, default: assert(attr < VARYING_SLOT_MAX); stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stvp->output_semantic_index[slot] = (VARYING_SLOT_VAR0 - - VARYING_SLOT_TEX0 + - attr - - VARYING_SLOT_VAR0); + stvp->output_semantic_index[slot] = st->needs_texcoord_semantic ? + (attr - VARYING_SLOT_VAR0) : (attr - VARYING_SLOT_TEX0); break; } } @@ -585,11 +585,18 @@ st_translate_fragment_program(struct st_context *st, * fragment shader plus fixed-function hardware (such as * BFC). * - * There is no requirement that semantic indexes start at - * zero or be restricted to a particular range -- nobody - * should be building tables based on semantic index. + * However, some drivers may need us to identify the PNTC and TEXi + * varyings if, for example, their capability to replace them with + * sprite coordinates is limited. */ case VARYING_SLOT_PNTC: + if (st->needs_texcoord_semantic) { + input_semantic_name[slot] = TGSI_SEMANTIC_PCOORD; + input_semantic_index[slot] = 0; + interpMode[slot] = TGSI_INTERPOLATE_LINEAR; + break; + } + /* fall through */ case VARYING_SLOT_TEX0: case VARYING_SLOT_TEX1: case VARYING_SLOT_TEX2: @@ -598,13 +605,29 @@ st_translate_fragment_program(struct st_context *st, case VARYING_SLOT_TEX5: case VARYING_SLOT_TEX6: case VARYING_SLOT_TEX7: + if (st->needs_texcoord_semantic) { + input_semantic_name[slot] = TGSI_SEMANTIC_TEXCOORD; + input_semantic_index[slot] = attr - VARYING_SLOT_TEX0; + interpMode[slot] = + st_translate_interp(stfp->Base.InterpQualifier[attr], FALSE); + break; + } + /* fall through */ case VARYING_SLOT_VAR0: default: - /* Actually, let's try and zero-base this just for - * readability of the generated TGSI. + /* Semantic indices should be zero-based because drivers may choose + * to assign a fixed slot determined by that index. + * This is useful because ARB_separate_shader_objects uses location + * qualifiers for linkage, and if the semantic index corresponds to + * these locations, linkage passes in the driver become unecessary. + * + * If needs_texcoord_semantic is true, no semantic indices will be + * consumed for the TEXi varyings, and we can base the locations of + * the user varyings on VAR0. Otherwise, we use TEX0 as base index. */ assert(attr >= VARYING_SLOT_TEX0); - input_semantic_index[slot] = (attr - VARYING_SLOT_TEX0); + input_semantic_index[slot] = st->needs_texcoord_semantic ? + (attr - VARYING_SLOT_VAR0) : (attr - VARYING_SLOT_TEX0); input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; if (attr == VARYING_SLOT_PNTC) interpMode[slot] = TGSI_INTERPOLATE_LINEAR; diff --git a/pixman/.gitignore b/pixman/.gitignore index 648699bf2..0f114966c 100644 --- a/pixman/.gitignore +++ b/pixman/.gitignore @@ -34,6 +34,7 @@ demos/composite-test demos/conical-test demos/convolution-test demos/gradient-test +demos/linear-gradient demos/quad2quad demos/radial-test demos/scale @@ -66,6 +67,7 @@ test/lowlevel-blt-bench test/oob-test test/pdf-op-test test/prng-test +test/radial-perf-test test/region-contains-test test/region-test test/region-translate diff --git a/pixman/demos/Makefile.am b/pixman/demos/Makefile.am index 5f53407b0..9be9ab670 100644 --- a/pixman/demos/Makefile.am +++ b/pixman/demos/Makefile.am @@ -15,6 +15,7 @@ DEMOS = \ composite-test \ gradient-test \ radial-test \ + linear-gradient \ conical-test \ alpha-test \ screen-test \ @@ -38,6 +39,7 @@ trap_test_SOURCES = trap-test.c $(GTK_UTILS) screen_test_SOURCES = screen-test.c $(GTK_UTILS) convolution_test_SOURCES = convolution-test.c $(GTK_UTILS) radial_test_SOURCES = radial-test.c $(GTK_UTILS) +linear_gradient_SOURCES = linear-gradient.c $(GTK_UTILS) conical_test_SOURCES = conical-test.c $(GTK_UTILS) tri_test_SOURCES = tri-test.c $(GTK_UTILS) checkerboard_SOURCES = checkerboard.c $(GTK_UTILS) diff --git a/pixman/demos/linear-gradient.c b/pixman/demos/linear-gradient.c new file mode 100644 index 000000000..46433a6e5 --- /dev/null +++ b/pixman/demos/linear-gradient.c @@ -0,0 +1,50 @@ +#include "../test/utils.h" +#include "gtk-utils.h" + +#define WIDTH 1024 +#define HEIGHT 640 + +int +main (int argc, char **argv) +{ + pixman_image_t *src_img, *dest_img; + pixman_gradient_stop_t stops[] = { + { 0x00000, { 0x0000, 0x0000, 0x4444, 0xdddd } }, + { 0x10000, { 0xeeee, 0xeeee, 0x8888, 0xdddd } }, +#if 0 + /* These colors make it very obvious that dithering + * is useful even for 8-bit gradients + */ + { 0x00000, { 0x6666, 0x3333, 0x3333, 0xffff } }, + { 0x10000, { 0x3333, 0x6666, 0x6666, 0xffff } }, +#endif + }; + pixman_point_fixed_t p1, p2; + + enable_divbyzero_exceptions (); + + dest_img = pixman_image_create_bits (PIXMAN_x8r8g8b8, + WIDTH, HEIGHT, + NULL, 0); + + p1.x = p1.y = 0x0000; + p2.x = WIDTH << 16; + p2.y = HEIGHT << 16; + + src_img = pixman_image_create_linear_gradient (&p1, &p2, stops, ARRAY_LENGTH (stops)); + + pixman_image_composite32 (PIXMAN_OP_OVER, + src_img, + NULL, + dest_img, + 0, 0, + 0, 0, + 0, 0, + WIDTH, HEIGHT); + + show_image (dest_img); + + pixman_image_unref (dest_img); + + return 0; +} diff --git a/pixman/pixman/pixman-combine-float.c b/pixman/pixman/pixman-combine-float.c index 06ce2037e..5ea739f76 100644 --- a/pixman/pixman/pixman-combine-float.c +++ b/pixman/pixman/pixman-combine-float.c @@ -42,8 +42,6 @@ #define force_inline __inline__ #endif -#define IS_ZERO(f) (-FLT_MIN < (f) && (f) < FLT_MIN) - typedef float (* combine_channel_t) (float sa, float s, float da, float d); static force_inline void @@ -203,56 +201,56 @@ get_factor (combine_factor_t factor, float sa, float da) break; case SA_OVER_DA: - if (IS_ZERO (da)) + if (FLOAT_IS_ZERO (da)) f = 1.0f; else f = CLAMP (sa / da); break; case DA_OVER_SA: - if (IS_ZERO (sa)) + if (FLOAT_IS_ZERO (sa)) f = 1.0f; else f = CLAMP (da / sa); break; case INV_SA_OVER_DA: - if (IS_ZERO (da)) + if (FLOAT_IS_ZERO (da)) f = 1.0f; else f = CLAMP ((1.0f - sa) / da); break; case INV_DA_OVER_SA: - if (IS_ZERO (sa)) + if (FLOAT_IS_ZERO (sa)) f = 1.0f; else f = CLAMP ((1.0f - da) / sa); break; case ONE_MINUS_SA_OVER_DA: - if (IS_ZERO (da)) + if (FLOAT_IS_ZERO (da)) f = 0.0f; else f = CLAMP (1.0f - sa / da); break; case ONE_MINUS_DA_OVER_SA: - if (IS_ZERO (sa)) + if (FLOAT_IS_ZERO (sa)) f = 0.0f; else f = CLAMP (1.0f - da / sa); break; case ONE_MINUS_INV_DA_OVER_SA: - if (IS_ZERO (sa)) + if (FLOAT_IS_ZERO (sa)) f = 0.0f; else f = CLAMP (1.0f - (1.0f - da) / sa); break; case ONE_MINUS_INV_SA_OVER_DA: - if (IS_ZERO (da)) + if (FLOAT_IS_ZERO (da)) f = 0.0f; else f = CLAMP (1.0f - (1.0f - sa) / da); @@ -405,11 +403,11 @@ blend_lighten (float sa, float s, float da, float d) static force_inline float blend_color_dodge (float sa, float s, float da, float d) { - if (IS_ZERO (d)) + if (FLOAT_IS_ZERO (d)) return 0.0f; else if (d * sa >= sa * da - s * da) return sa * da; - else if (IS_ZERO (sa - s)) + else if (FLOAT_IS_ZERO (sa - s)) return sa * da; else return sa * sa * d / (sa - s); @@ -422,7 +420,7 @@ blend_color_burn (float sa, float s, float da, float d) return sa * da; else if (sa * (da - d) >= s * da) return 0.0f; - else if (IS_ZERO (s)) + else if (FLOAT_IS_ZERO (s)) return 0.0f; else return sa * (da - sa * (da - d) / s); @@ -442,14 +440,14 @@ blend_soft_light (float sa, float s, float da, float d) { if (2 * s < sa) { - if (IS_ZERO (da)) + if (FLOAT_IS_ZERO (da)) return d * sa; else return d * sa - d * (da - d) * (sa - 2 * s) / da; } else { - if (IS_ZERO (da)) + if (FLOAT_IS_ZERO (da)) { return 0.0f; } @@ -658,7 +656,7 @@ clip_color (rgb_t *color, float a) if (n < 0.0f) { t = l - n; - if (IS_ZERO (t)) + if (FLOAT_IS_ZERO (t)) { color->r = 0.0f; color->g = 0.0f; @@ -674,7 +672,7 @@ clip_color (rgb_t *color, float a) if (x > a) { t = x - l; - if (IS_ZERO (t)) + if (FLOAT_IS_ZERO (t)) { color->r = a; color->g = a; @@ -758,7 +756,7 @@ set_sat (rgb_t *src, float sat) t = *max - *min; - if (IS_ZERO (t)) + if (FLOAT_IS_ZERO (t)) { *mid = *max = 0.0f; } diff --git a/pixman/pixman/pixman-gradient-walker.c b/pixman/pixman/pixman-gradient-walker.c index e7e724fa6..5944a559a 100644 --- a/pixman/pixman/pixman-gradient-walker.c +++ b/pixman/pixman/pixman-gradient-walker.c @@ -37,11 +37,14 @@ _pixman_gradient_walker_init (pixman_gradient_walker_t *walker, walker->stops = gradient->stops; walker->left_x = 0; walker->right_x = 0x10000; - walker->stepper = 0; - walker->left_ag = 0; - walker->left_rb = 0; - walker->right_ag = 0; - walker->right_rb = 0; + walker->a_s = 0.0f; + walker->a_b = 0.0f; + walker->r_s = 0.0f; + walker->r_b = 0.0f; + walker->g_s = 0.0f; + walker->g_b = 0.0f; + walker->b_s = 0.0f; + walker->b_b = 0.0f; walker->repeat = repeat; walker->need_reset = TRUE; @@ -55,6 +58,9 @@ gradient_walker_reset (pixman_gradient_walker_t *walker, pixman_color_t *left_c, *right_c; int n, count = walker->num_stops; pixman_gradient_stop_t *stops = walker->stops; + float la, lr, lg, lb; + float ra, rr, rg, rb; + float lx, rx; if (walker->repeat == PIXMAN_REPEAT_NORMAL) { @@ -116,24 +122,49 @@ gradient_walker_reset (pixman_gradient_walker_t *walker, left_c = right_c; } - walker->left_x = left_x; - walker->right_x = right_x; - walker->left_ag = ((left_c->alpha >> 8) << 16) | (left_c->green >> 8); - walker->left_rb = ((left_c->red & 0xff00) << 8) | (left_c->blue >> 8); - walker->right_ag = ((right_c->alpha >> 8) << 16) | (right_c->green >> 8); - walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8); - - if (walker->left_x == walker->right_x || - (walker->left_ag == walker->right_ag && - walker->left_rb == walker->right_rb)) + /* The alpha channel is scaled to be in the [0, 255] interval, + * and the red/green/blue channels are scaled to be in [0, 1]. + * This ensures that after premultiplication all channels will + * be in the [0, 255] interval. + */ + la = (left_c->alpha * (1.0f/257.0f)); + lr = (left_c->red * (1.0f/257.0f)); + lg = (left_c->green * (1.0f/257.0f)); + lb = (left_c->blue * (1.0f/257.0f)); + + ra = (right_c->alpha * (1.0f/257.0f)); + rr = (right_c->red * (1.0f/257.0f)); + rg = (right_c->green * (1.0f/257.0f)); + rb = (right_c->blue * (1.0f/257.0f)); + + lx = left_x * (1.0f/65536.0f); + rx = right_x * (1.0f/65536.0f); + + if (FLOAT_IS_ZERO (rx - lx) || left_x == INT32_MIN || right_x == INT32_MAX) { - walker->stepper = 0; + walker->a_s = walker->r_s = walker->g_s = walker->b_s = 0.0f; + walker->a_b = (la + ra) / 2.0f; + walker->r_b = (lr + rr) / 510.0f; + walker->g_b = (lg + rg) / 510.0f; + walker->b_b = (lb + rb) / 510.0f; } else { - int32_t width = right_x - left_x; - walker->stepper = ((1 << 24) + width / 2) / width; + float w_rec = 1.0f / (rx - lx); + + walker->a_b = (la * rx - ra * lx) * w_rec; + walker->r_b = (lr * rx - rr * lx) * w_rec * (1.0f/255.0f); + walker->g_b = (lg * rx - rg * lx) * w_rec * (1.0f/255.0f); + walker->b_b = (lb * rx - rb * lx) * w_rec * (1.0f/255.0f); + + walker->a_s = (ra - la) * w_rec; + walker->r_s = (rr - lr) * w_rec * (1.0f/255.0f); + walker->g_s = (rg - lg) * w_rec * (1.0f/255.0f); + walker->b_s = (rb - lb) * w_rec * (1.0f/255.0f); } + + walker->left_x = left_x; + walker->right_x = right_x; walker->need_reset = FALSE; } @@ -142,31 +173,30 @@ uint32_t _pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker, pixman_fixed_48_16_t x) { - int dist, idist; - uint32_t t1, t2, a, color; + float a, r, g, b; + uint8_t a8, r8, g8, b8; + uint32_t v; + float y; if (walker->need_reset || x < walker->left_x || x >= walker->right_x) - gradient_walker_reset (walker, x); - - dist = ((int)(x - walker->left_x) * walker->stepper) >> 16; - idist = 256 - dist; + gradient_walker_reset (walker, x); - /* combined INTERPOLATE and premultiply */ - t1 = walker->left_rb * idist + walker->right_rb * dist; - t1 = (t1 >> 8) & 0xff00ff; + y = x * (1.0f / 65536.0f); - t2 = walker->left_ag * idist + walker->right_ag * dist; - t2 &= 0xff00ff00; + a = walker->a_s * y + walker->a_b; + r = a * (walker->r_s * y + walker->r_b); + g = a * (walker->g_s * y + walker->g_b); + b = a * (walker->b_s * y + walker->b_b); - color = t2 & 0xff000000; - a = t2 >> 24; + a8 = a + 0.5f; + r8 = r + 0.5f; + g8 = g + 0.5f; + b8 = b + 0.5f; - t1 = t1 * a + 0x800080; - t1 = (t1 + ((t1 >> 8) & 0xff00ff)) >> 8; + v = ((a8 << 24) & 0xff000000) | + ((r8 << 16) & 0x00ff0000) | + ((g8 << 8) & 0x0000ff00) | + ((b8 >> 0) & 0x000000ff); - t2 = (t2 >> 8) * a + 0x800080; - t2 = (t2 + ((t2 >> 8) & 0xff00ff)); - - return (color | (t1 & 0xff00ff) | (t2 & 0xff00)); + return v; } - diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h index 181ab5c35..6d9c05321 100644 --- a/pixman/pixman/pixman-private.h +++ b/pixman/pixman/pixman-private.h @@ -1,3 +1,5 @@ +#include + #ifndef PIXMAN_PRIVATE_H #define PIXMAN_PRIVATE_H @@ -317,13 +319,12 @@ _pixman_image_validate (pixman_image_t *image); */ typedef struct { - uint32_t left_ag; - uint32_t left_rb; - uint32_t right_ag; - uint32_t right_rb; + float a_s, a_b; + float r_s, r_b; + float g_s, g_b; + float b_s, b_b; pixman_fixed_t left_x; pixman_fixed_t right_x; - pixman_fixed_t stepper; pixman_gradient_stop_t *stops; int num_stops; @@ -879,6 +880,8 @@ pixman_list_move_to_front (pixman_list_t *list, pixman_link_t *link) #define CLIP(v, low, high) ((v) < (low) ? (low) : ((v) > (high) ? (high) : (v))) +#define FLOAT_IS_ZERO(f) (-FLT_MIN < (f) && (f) < FLT_MIN) + /* Conversion between 8888 and 0565 */ static force_inline uint16_t diff --git a/pixman/test/Makefile.sources b/pixman/test/Makefile.sources index 5b30970b9..b5fc740f3 100644 --- a/pixman/test/Makefile.sources +++ b/pixman/test/Makefile.sources @@ -28,9 +28,10 @@ TESTPROGRAMS = \ composite \ $(NULL) -# Benchmarks +# Other programs OTHERPROGRAMS = \ lowlevel-blt-bench \ + radial-perf-test \ check-formats \ $(NULL) diff --git a/pixman/test/radial-perf-test.c b/pixman/test/radial-perf-test.c new file mode 100644 index 000000000..71092e27b --- /dev/null +++ b/pixman/test/radial-perf-test.c @@ -0,0 +1,58 @@ +#include "utils.h" +#include + +int +main () +{ + static const pixman_point_fixed_t inner = { 0x0000, 0x0000 }; + static const pixman_point_fixed_t outer = { 0x0000, 0x0000 }; + static const pixman_fixed_t r_inner = 0; + static const pixman_fixed_t r_outer = 64 << 16; + static const pixman_gradient_stop_t stops[] = { + { 0x00000, { 0x6666, 0x6666, 0x6666, 0xffff } }, + { 0x10000, { 0x0000, 0x0000, 0x0000, 0xffff } } + }; + static const pixman_transform_t transform = { + { { 0x0, 0x26ee, 0x0}, + { 0xffffeeef, 0x0, 0x0}, + { 0x0, 0x0, 0x10000} + } + }; + static const pixman_color_t z = { 0x0000, 0x0000, 0x0000, 0x0000 }; + pixman_image_t *dest, *radial, *zero; + int i; + double before, after; + + dest = pixman_image_create_bits ( + PIXMAN_x8r8g8b8, 640, 429, NULL, -1); + zero = pixman_image_create_solid_fill (&z); + radial = pixman_image_create_radial_gradient ( + &inner, &outer, r_inner, r_outer, stops, ARRAY_LENGTH (stops)); + pixman_image_set_transform (radial, &transform); + pixman_image_set_repeat (radial, PIXMAN_REPEAT_PAD); + +#define N_COMPOSITE 500 + + before = gettime(); + for (i = 0; i < N_COMPOSITE; ++i) + { + before -= gettime(); + + pixman_image_composite ( + PIXMAN_OP_SRC, zero, NULL, dest, + 0, 0, 0, 0, 0, 0, 640, 429); + + before += gettime(); + + pixman_image_composite32 ( + PIXMAN_OP_OVER, radial, NULL, dest, + - 150, -158, 0, 0, 0, 0, 640, 361); + } + + after = gettime(); + + write_png (dest, "radial.png"); + + printf ("Average time to composite: %f\n", (after - before) / N_COMPOSITE); + return 0; +} diff --git a/xorg-server/Xext/panoramiX.c b/xorg-server/Xext/panoramiX.c index be475f7f4..7f888e38d 100644 --- a/xorg-server/Xext/panoramiX.c +++ b/xorg-server/Xext/panoramiX.c @@ -596,7 +596,7 @@ Bool PanoramiXCreateConnectionBlock(void) { int i, j, length; - Bool disableBackingStore = FALSE; + Bool disable_backing_store = FALSE; int old_width, old_height; float width_mult, height_mult; xWindowRoot *root; @@ -622,10 +622,10 @@ PanoramiXCreateConnectionBlock(void) } if (pScreen->backingStoreSupport != screenInfo.screens[0]->backingStoreSupport) - disableBackingStore = TRUE; + disable_backing_store = TRUE; } - if (disableBackingStore) { + if (disable_backing_store) { for (i = 0; i < screenInfo.numScreens; i++) { pScreen = screenInfo.screens[i]; pScreen->backingStoreSupport = NotUseful; @@ -831,15 +831,15 @@ PanoramiXConsolidate(void) saver->type = XRT_WINDOW; FOR_NSCREENS(i) { - ScreenPtr pScreen = screenInfo.screens[i]; + ScreenPtr scr = screenInfo.screens[i]; - root->info[i].id = pScreen->root->drawable.id; + root->info[i].id = scr->root->drawable.id; root->u.win.class = InputOutput; root->u.win.root = TRUE; - saver->info[i].id = pScreen->screensaver.wid; + saver->info[i].id = scr->screensaver.wid; saver->u.win.class = InputOutput; saver->u.win.root = TRUE; - defmap->info[i].id = pScreen->defColormap; + defmap->info[i].id = scr->defColormap; } AddResource(root->info[0].id, XRT_WINDOW, root); diff --git a/xorg-server/Xext/sync.c b/xorg-server/Xext/sync.c index 4d11992bb..9ae5b3981 100644 --- a/xorg-server/Xext/sync.c +++ b/xorg-server/Xext/sync.c @@ -2747,7 +2747,6 @@ init_system_idle_counter(const char *name, int deviceid) { CARD64 resolution; XSyncValue idle; - IdleCounterPriv *priv = malloc(sizeof(IdleCounterPriv)); SyncCounter *idle_time_counter; IdleTimeQueryValue(NULL, &idle); @@ -2758,10 +2757,14 @@ init_system_idle_counter(const char *name, int deviceid) IdleTimeQueryValue, IdleTimeBracketValues); - priv->deviceid = deviceid; - priv->value_less = priv->value_greater = NULL; + if (idle_time_counter != NULL) { + IdleCounterPriv *priv = malloc(sizeof(IdleCounterPriv)); - idle_time_counter->pSysCounterInfo->private = priv; + priv->value_less = priv->value_greater = NULL; + priv->deviceid = deviceid; + + idle_time_counter->pSysCounterInfo->private = priv; + } return idle_time_counter; } @@ -2786,6 +2789,6 @@ void SyncRemoveDeviceIdleTime(SyncCounter *counter) /* FreeAllResources() frees all system counters before the devices are shut down, check if there are any left before freeing the device's counter */ - if (!xorg_list_is_empty(&SysCounterList)) + if (counter && !xorg_list_is_empty(&SysCounterList)) xorg_list_del(&counter->pSysCounterInfo->entry); } diff --git a/xorg-server/Xext/xvdisp.c b/xorg-server/Xext/xvdisp.c index 31b77839f..787729387 100644 --- a/xorg-server/Xext/xvdisp.c +++ b/xorg-server/Xext/xvdisp.c @@ -702,7 +702,7 @@ ProcXvUngrabPort(ClientPtr client) static int ProcXvStopVideo(ClientPtr client) { - int status, rc; + int status, ret; DrawablePtr pDraw; XvPortPtr pPort; @@ -716,9 +716,9 @@ ProcXvStopVideo(ClientPtr client) return status; } - rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess); - if (rc != Success) - return rc; + ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess); + if (ret != Success) + return ret; return XvdiStopVideo(client, pPort, pDraw); } diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c index 609b1268f..6779139b5 100644 --- a/xorg-server/Xi/exevents.c +++ b/xorg-server/Xi/exevents.c @@ -1126,20 +1126,22 @@ static void TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti, TouchOwnershipEvent *ev) { + TouchListener *listener = &ti->listeners[0]; /* new owner */ + /* Deliver the ownership */ - if (ti->listeners[0].state == LISTENER_AWAITING_OWNER || - ti->listeners[0].state == LISTENER_EARLY_ACCEPT) + if (listener->state == LISTENER_AWAITING_OWNER || + listener->state == LISTENER_EARLY_ACCEPT) DeliverTouchEvents(dev, ti, (InternalEvent *) ev, - ti->listeners[0].listener); - else if (ti->listeners[0].state == LISTENER_AWAITING_BEGIN) { + listener->listener); + else if (listener->state == LISTENER_AWAITING_BEGIN) { /* We can't punt to a pointer listener unless all older pointer * emulated touches have been seen already. */ - if ((ti->listeners[0].type == LISTENER_POINTER_GRAB || - ti->listeners[0].type == LISTENER_POINTER_REGULAR) && + if ((listener->type == LISTENER_POINTER_GRAB || + listener->type == LISTENER_POINTER_REGULAR) && ti != FindOldestPointerEmulatedTouch(dev)) return; - TouchEventHistoryReplay(ti, dev, ti->listeners[0].listener); + TouchEventHistoryReplay(ti, dev, listener->listener); } /* If we've just removed the last grab and the touch has physically @@ -1150,7 +1152,7 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti, return; } - if (ti->listeners[0].state == LISTENER_EARLY_ACCEPT) + if (listener->state == LISTENER_EARLY_ACCEPT) ActivateEarlyAccept(dev, ti); } @@ -1376,7 +1378,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, /* We don't deliver pointer events to non-owners */ if (!TouchResourceIsOwner(ti, listener->listener)) - return Success; + return !Success; nevents = TouchConvertToPointerEvent(ev, &motion, &button); BUG_RETURN_VAL(nevents == 0, BadValue); @@ -1398,7 +1400,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, /* 'grab' is the passive grab, but if the grab isn't active, * don't deliver */ if (!dev->deviceGrab.grab) - return Success; + return !Success; if (grab->ownerEvents) { WindowPtr focus = NullWindow; @@ -1896,13 +1898,16 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev, goto out; } + /* A client is waiting for the begin, don't give it a TouchEnd */ if (listener->state == LISTENER_AWAITING_BEGIN) { listener->state = LISTENER_HAS_END; goto out; } /* Event in response to reject */ - if (ev->device_event.flags & TOUCH_REJECT) { + if (ev->device_event.flags & TOUCH_REJECT || + (ev->device_event.flags & TOUCH_ACCEPT && !TouchResourceIsOwner(ti, listener->listener))) { + /* Touch has been rejected, or accepted by its owner which is not this listener */ if (listener->state != LISTENER_HAS_END) rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev); listener->state = LISTENER_HAS_END; @@ -1925,12 +1930,6 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev, if (normal_end) listener->state = LISTENER_HAS_END; } - else if (ev->device_event.flags & TOUCH_ACCEPT) { - /* Touch has been accepted by its owner, which is not this listener */ - if (listener->state != LISTENER_HAS_END) - rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev); - listener->state = LISTENER_HAS_END; - } out: return rc; diff --git a/xorg-server/composite/compext.c b/xorg-server/composite/compext.c index 8641eff5e..e4821c5fc 100644 --- a/xorg-server/composite/compext.c +++ b/xorg-server/composite/compext.c @@ -803,6 +803,7 @@ PanoramiXCompositeGetOverlayWindow(ClientPtr client) RT_WINDOW, client, DixGetAttrAccess); if (rc != Success) { client->errorValue = stuff->window; + free(overlayWin); return rc; } pScreen = pWin->drawable.pScreen; @@ -812,8 +813,10 @@ PanoramiXCompositeGetOverlayWindow(ClientPtr client) * interest in the overlay window */ pOc = compCreateOverlayClient(pScreen, client); - if (pOc == NULL) + if (pOc == NULL) { + free(overlayWin); return BadAlloc; + } /* * Make sure the overlay window exists @@ -822,6 +825,7 @@ PanoramiXCompositeGetOverlayWindow(ClientPtr client) if (cs->pOverlayWin == NULL) if (!compCreateOverlayWindow(pScreen)) { FreeResource(pOc->resource, RT_NONE); + free(overlayWin); return BadAlloc; } @@ -831,6 +835,7 @@ PanoramiXCompositeGetOverlayWindow(ClientPtr client) DixGetAttrAccess); if (rc != Success) { FreeResource(pOc->resource, RT_NONE); + free(overlayWin); return rc; } } diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 6e1ff65c4..e0750bbcc 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -26,9 +26,9 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.60) -AC_INIT([xorg-server], 1.14.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) -RELEASE_DATE="2013-03-05" -RELEASE_NAME="Keemun Mao Feng" +AC_INIT([xorg-server], 1.14.99.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) +RELEASE_DATE="2013-03-18" +RELEASE_NAME="Pok Pok Meyer Lemon" AC_CONFIG_SRCDIR([Makefile.am]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) @@ -308,6 +308,13 @@ AC_CHECK_HEADER([execinfo.h],[ ])] ) +PKG_CHECK_MODULES(LIBUNWIND, libunwind, [HAVE_LIBUNWIND=yes], [HAVE_LIBUNWIND=no]) +if test "x$HAVE_LIBUNWIND" = xyes; then + AC_DEFINE(HAVE_LIBUNWIND, 1, [Have libunwind support]) +fi +AM_CONDITIONAL(HAVE_LIBUNWIND, [test "x$HAVE_LIBUNWIND" = xyes]) + + dnl --------------------------------------------------------------------------- dnl Bus options and CPU capabilities. Replaces logic in dnl hw/xfree86/os-support/bus/Makefile.am, among others. @@ -788,7 +795,7 @@ XPROTO="xproto >= 7.0.22" RANDRPROTO="randrproto >= 1.4.0" RENDERPROTO="renderproto >= 0.11" XEXTPROTO="xextproto >= 7.1.99" -INPUTPROTO="inputproto >= 2.2.99.1" +INPUTPROTO="inputproto >= 2.3" KBPROTO="kbproto >= 1.0.3" FONTSPROTO="fontsproto" FIXESPROTO="fixesproto >= 5.0" @@ -1336,7 +1343,7 @@ AC_DEFINE(BIGREQS, 1, [Support BigRequests extension]) if test "x$SPECIAL_DTRACE_OBJECTS" = "xyes" ; then DIX_LIB='$(top_builddir)/dix/dix.O' - OS_LIB='$(top_builddir)/os/os.O $(SHA1_LIBS) $(DLOPEN_LIBS)' + OS_LIB='$(top_builddir)/os/os.O $(SHA1_LIBS) $(DLOPEN_LIBS) $(LIBUNWIND_LIBS)' else DIX_LIB='$(top_builddir)/dix/libdix.la' OS_LIB='$(top_builddir)/os/libos.la' diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c index 2682ecd46..051205233 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -1200,6 +1200,9 @@ PlayReleasedEvents(void) case ET_KeyRelease: case ET_ProximityIn: case ET_ProximityOut: + case ET_TouchBegin: + case ET_TouchUpdate: + case ET_TouchEnd: ev->root_x += screenInfo.screens[0]->x - pDev->spriteInfo->sprite->screen->x; ev->root_y += screenInfo.screens[0]->y - diff --git a/xorg-server/dix/main.c b/xorg-server/dix/main.c index fb935c969..bea1a8d5a 100644 --- a/xorg-server/dix/main.c +++ b/xorg-server/dix/main.c @@ -357,6 +357,8 @@ main(int argc, char *argv[], char *envp[]) FreeFonts(); + FreeAllAtoms(); + FreeAuditTimer(); if (dispatchException & DE_TERMINATE) { diff --git a/xorg-server/dix/touch.c b/xorg-server/dix/touch.c index 0db842c65..891cc7803 100644 --- a/xorg-server/dix/touch.c +++ b/xorg-server/dix/touch.c @@ -902,7 +902,8 @@ TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev) } /** - * Remove the touch pointer grab from the device. Called from AllowSome() + * Remove the touch pointer grab from the device. Called from + * DeactivatePointerGrab() */ void TouchRemovePointerGrab(DeviceIntPtr dev) diff --git a/xorg-server/dix/window.c b/xorg-server/dix/window.c index a5b28a630..a9297f3c8 100644 --- a/xorg-server/dix/window.c +++ b/xorg-server/dix/window.c @@ -1431,6 +1431,8 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) } } + CursorVisible = TRUE; + if (pWin->realized) WindowHasNewCursor(pWin); @@ -3430,6 +3432,8 @@ ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor) } out: + CursorVisible = TRUE; + if (pWin->realized) WindowHasNewCursor(pWin); diff --git a/xorg-server/fb/fbpict.c b/xorg-server/fb/fbpict.c index 2804ff481..b50385805 100644 --- a/xorg-server/fb/fbpict.c +++ b/xorg-server/fb/fbpict.c @@ -185,19 +185,15 @@ fbGlyphs(CARD8 op, if (maskFormat) { pixman_format_code_t format; pixman_box32_t extents; - int x, y; format = maskFormat->format | (maskFormat->depth << 24); pixman_glyph_get_extents(glyphCache, n_glyphs, pglyphs, &extents); - x = extents.x1; - y = extents.y1; - pixman_composite_glyphs(op, srcImage, dstImage, format, xSrc + srcXoff + xDst, ySrc + srcYoff + yDst, - x, y, - x + dstXoff, y + dstYoff, + extents.x1, extents.y1, + extents.x1 + dstXoff, extents.y1 + dstYoff, extents.x2 - extents.x1, extents.y2 - extents.y1, glyphCache, n_glyphs, pglyphs); diff --git a/xorg-server/glx/extension_string.c b/xorg-server/glx/extension_string.c index 544ca1f5e..58f930f75 100644 --- a/xorg-server/glx/extension_string.c +++ b/xorg-server/glx/extension_string.c @@ -71,9 +71,11 @@ static const struct extension_info known_glx_extensions[] = { { GLX(ARB_create_context), VER(0,0), N, }, { GLX(ARB_create_context_profile), VER(0,0), N, }, { GLX(ARB_create_context_robustness), VER(0,0), N, }, + { GLX(ARB_framebuffer_sRGB), VER(0,0), N, }, { GLX(ARB_multisample), VER(1,4), Y, }, { GLX(EXT_create_context_es2_profile), VER(0,0), N, }, + { GLX(EXT_framebuffer_sRGB), VER(0,0), N, }, { GLX(EXT_import_context), VER(0,0), Y, }, { GLX(EXT_texture_from_pixmap), VER(0,0), Y, }, { GLX(EXT_visual_info), VER(0,0), Y, }, diff --git a/xorg-server/glx/extension_string.h b/xorg-server/glx/extension_string.h index 7a4a8b1c2..81b7de372 100644 --- a/xorg-server/glx/extension_string.h +++ b/xorg-server/glx/extension_string.h @@ -39,6 +39,7 @@ enum { ARB_create_context_bit = 0, ARB_create_context_profile_bit, ARB_create_context_robustness_bit, + ARB_framebuffer_sRGB_bit, ARB_multisample_bit, EXT_create_context_es2_profile_bit, EXT_import_context_bit, @@ -58,6 +59,10 @@ enum { __NUM_GLX_EXTS, }; +/* For extensions which have identical ARB and EXT implementation + * in GLX area, use one enabling bit for both. */ +#define EXT_framebuffer_sRGB_bit ARB_framebuffer_sRGB_bit + #define __GLX_EXT_BYTES ((__NUM_GLX_EXTS + 7) / 8) extern int __glXGetExtensionString(const unsigned char *enable_bits, diff --git a/xorg-server/glx/glxcmds.c b/xorg-server/glx/glxcmds.c index c1f4e22f8..5b7a628cc 100644 --- a/xorg-server/glx/glxcmds.c +++ b/xorg-server/glx/glxcmds.c @@ -913,7 +913,7 @@ __glXDisp_CopyContext(__GLXclientState * cl, GLbyte * pc) enum { GLX_VIS_CONFIG_UNPAIRED = 18, - GLX_VIS_CONFIG_PAIRED = 20 + GLX_VIS_CONFIG_PAIRED = 22 }; enum { @@ -1005,8 +1005,17 @@ __glXDisp_GetVisualConfigs(__GLXclientState * cl, GLbyte * pc) buf[p++] = modes->samples; buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; buf[p++] = modes->sampleBuffers; - buf[p++] = 0; /* copy over visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)? */ - buf[p++] = 0; + /* Add attribute only if its value is not default. */ + if (modes->sRGBCapable != GL_FALSE) { + buf[p++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT; + buf[p++] = modes->sRGBCapable; + } + /* Don't add visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)? + * Pad the remaining place with zeroes, so that attributes count is constant. */ + while (p < GLX_VIS_CONFIG_TOTAL) { + buf[p++] = 0; + buf[p++] = 0; + } assert(p == GLX_VIS_CONFIG_TOTAL); if (client->swapped) { @@ -1017,7 +1026,7 @@ __glXDisp_GetVisualConfigs(__GLXclientState * cl, GLbyte * pc) return Success; } -#define __GLX_TOTAL_FBCONFIG_ATTRIBS (36) +#define __GLX_TOTAL_FBCONFIG_ATTRIBS (37) #define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2) /** * Send the set of GLXFBConfigs to the client. There is not currently @@ -1109,6 +1118,15 @@ DoGetFBConfigs(__GLXclientState * cl, unsigned screen) WRITE_PAIR(GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture); WRITE_PAIR(GLX_BIND_TO_TEXTURE_TARGETS_EXT, modes->bindToTextureTargets); + /* Add attribute only if its value is not default. */ + if (modes->sRGBCapable != GL_FALSE) { + WRITE_PAIR(GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, modes->sRGBCapable); + } + /* Pad the remaining place with zeroes, so that attributes count is constant. */ + while (p < __GLX_FBCONFIG_ATTRIBS_LENGTH) { + WRITE_PAIR(0, 0); + } + assert(p == __GLX_FBCONFIG_ATTRIBS_LENGTH); if (client->swapped) { __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH); diff --git a/xorg-server/glx/glxdri.c b/xorg-server/glx/glxdri.c index da4646845..a997e2f8a 100644 --- a/xorg-server/glx/glxdri.c +++ b/xorg-server/glx/glxdri.c @@ -971,6 +971,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen) size_t buffer_size; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + framebuffer.base = NULL; + if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") || !DRIQueryDirectRenderingCapable(pScreen, &isCapable) || !isCapable) { LogMessage(X_INFO, diff --git a/xorg-server/glx/glxdri2.c b/xorg-server/glx/glxdri2.c index b26e501dc..e07cb5632 100644 --- a/xorg-server/glx/glxdri2.c +++ b/xorg-server/glx/glxdri2.c @@ -857,8 +857,6 @@ initializeExtensions(__GLXDRIscreen * screen) __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer"); LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n"); - __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event"); - LogMessage(X_INFO, "AIGLX: enabled GLX_INTEL_swap_event\n"); #if __DRI_DRI2_VERSION >= 3 if (screen->dri2->base.version >= 3) { @@ -876,12 +874,21 @@ initializeExtensions(__GLXDRIscreen * screen) #endif if (DRI2HasSwapControl(pScreen)) { + __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event"); __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_swap_control"); __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_swap_control"); + LogMessage(X_INFO, "AIGLX: enabled GLX_INTEL_swap_event\n"); LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n"); } + /* enable EXT_framebuffer_sRGB extension (even if there are no sRGB capable fbconfigs) */ + { + __glXEnableExtension(screen->glx_enable_bits, + "GLX_EXT_framebuffer_sRGB"); + LogMessage(X_INFO, "AIGLX: enabled GLX_EXT_framebuffer_sRGB\n"); + } + for (i = 0; extensions[i]; i++) { #ifdef __DRI_READ_DRAWABLE if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { diff --git a/xorg-server/glx/glxdricommon.c b/xorg-server/glx/glxdricommon.c index c90f38098..b027f2498 100644 --- a/xorg-server/glx/glxdricommon.c +++ b/xorg-server/glx/glxdricommon.c @@ -105,7 +105,9 @@ __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits), __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba), __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture), - __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),}; + __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), + __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable), + }; static void setScalar(__GLXconfig * config, unsigned int attrib, unsigned int value) diff --git a/xorg-server/glx/glxscreens.h b/xorg-server/glx/glxscreens.h index b29df58a5..0a7b6043e 100644 --- a/xorg-server/glx/glxscreens.h +++ b/xorg-server/glx/glxscreens.h @@ -102,6 +102,9 @@ struct __GLXconfig { GLint bindToMipmapTexture; GLint bindToTextureTargets; GLint yInverted; + + /* ARB_framebuffer_sRGB */ + GLint sRGBCapable; }; GLint glxConvertToXVisualType(int visualType); diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c index e6520d035..02d497073 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr.c +++ b/xorg-server/hw/kdrive/ephyr/ephyr.c @@ -56,6 +56,7 @@ typedef struct _EphyrInputPrivate { } EphyrKbdPrivate, EphyrPointerPrivate; Bool EphyrWantGrayScale = 0; +Bool EphyrWantResize = 0; Bool ephyrInitialize(KdCardInfo * card, EphyrPriv * priv) @@ -237,13 +238,11 @@ ephyrMapFramebuffer(KdScreenInfo * screen) KdComputePointerMatrix(&m, ephyrRandr, screen->width, screen->height); KdSetPointerMatrix(&m); - priv->bytes_per_line = - ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2; - buffer_height = ephyrBufferHeight(screen); priv->base = - hostx_screen_init(screen, screen->width, screen->height, buffer_height); + hostx_screen_init(screen, screen->width, screen->height, buffer_height, + &priv->bytes_per_line, &screen->fb.bitsPerPixel); if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All)) { scrpriv->shadow = FALSE; diff --git a/xorg-server/hw/kdrive/ephyr/ephyrinit.c b/xorg-server/hw/kdrive/ephyr/ephyrinit.c index 5e2eb672f..adacac949 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrinit.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrinit.c @@ -31,6 +31,7 @@ extern Window EphyrPreExistingHostWin; extern Bool EphyrWantGrayScale; +extern Bool EphyrWantResize; extern Bool kdHasPointer; extern Bool kdHasKbd; @@ -116,6 +117,7 @@ ddxUseMsg(void) ErrorF("-host-cursor Re-use exisiting X host server cursor\n"); ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n"); ErrorF("-grayscale Simulate 8bit grayscale\n"); + ErrorF("-resizeable Make Xephyr windows resizeable\n"); ErrorF ("-fakexa Simulate acceleration using software rendering\n"); ErrorF("-verbosity Set log verbosity level\n"); @@ -210,6 +212,10 @@ ddxProcessArgument(int argc, char **argv, int i) EphyrWantGrayScale = 1; return 1; } + else if (!strcmp(argv[i], "-resizeable")) { + EphyrWantResize = 1; + return 1; + } else if (!strcmp(argv[i], "-fakexa")) { ephyrFuncs.initAccel = ephyrDrawInit; ephyrFuncs.enableAccel = ephyrDrawEnable; diff --git a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c index 55dbd2e3a..dfc29f533 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c @@ -1006,7 +1006,6 @@ ephyrPutVideo(KdScreenInfo * a_info, EphyrPortPriv *port_priv = a_port_priv; BoxRec clipped_area, dst_box; int result = BadImplementation; - int drw_x = 0, drw_y = 0, drw_w = 0, drw_h = 0; EPHYR_RETURN_VAL_IF_FAIL(a_info->pScreen, BadValue); EPHYR_RETURN_VAL_IF_FAIL(a_drawable && port_priv, BadValue); @@ -1024,11 +1023,6 @@ ephyrPutVideo(KdScreenInfo * a_info, goto out; } - drw_x = clipped_area.x1; - drw_y = clipped_area.y1; - drw_w = clipped_area.x2 - clipped_area.x1; - drw_h = clipped_area.y2 - clipped_area.y1; - if (!ephyrHostXVPutVideo(a_info->pScreen->myNum, port_priv->port_number, a_vid_x, a_vid_y, a_vid_w, a_vid_h, @@ -1055,7 +1049,6 @@ ephyrGetVideo(KdScreenInfo * a_info, EphyrPortPriv *port_priv = a_port_priv; BoxRec clipped_area, dst_box; int result = BadImplementation; - int drw_x = 0, drw_y = 0, drw_w = 0, drw_h = 0; EPHYR_RETURN_VAL_IF_FAIL(a_info && a_info->pScreen, BadValue); EPHYR_RETURN_VAL_IF_FAIL(a_drawable && port_priv, BadValue); @@ -1073,11 +1066,6 @@ ephyrGetVideo(KdScreenInfo * a_info, goto out; } - drw_x = clipped_area.x1; - drw_y = clipped_area.y1; - drw_w = clipped_area.x2 - clipped_area.x1; - drw_h = clipped_area.y2 - clipped_area.y1; - if (!ephyrHostXVGetVideo(a_info->pScreen->myNum, port_priv->port_number, a_vid_x, a_vid_y, a_vid_w, a_vid_h, @@ -1104,7 +1092,6 @@ ephyrPutStill(KdScreenInfo * a_info, EphyrPortPriv *port_priv = a_port_priv; BoxRec clipped_area, dst_box; int result = BadImplementation; - int drw_x = 0, drw_y = 0, drw_w = 0, drw_h = 0; EPHYR_RETURN_VAL_IF_FAIL(a_info && a_info->pScreen, BadValue); EPHYR_RETURN_VAL_IF_FAIL(a_drawable && port_priv, BadValue); @@ -1122,11 +1109,6 @@ ephyrPutStill(KdScreenInfo * a_info, goto out; } - drw_x = clipped_area.x1; - drw_y = clipped_area.y1; - drw_w = clipped_area.x2 - clipped_area.x1; - drw_h = clipped_area.y2 - clipped_area.y1; - if (!ephyrHostXVPutStill(a_info->pScreen->myNum, port_priv->port_number, a_vid_x, a_vid_y, a_vid_w, a_vid_h, @@ -1153,7 +1135,6 @@ ephyrGetStill(KdScreenInfo * a_info, EphyrPortPriv *port_priv = a_port_priv; BoxRec clipped_area, dst_box; int result = BadImplementation; - int drw_x = 0, drw_y = 0, drw_w = 0, drw_h = 0; EPHYR_RETURN_VAL_IF_FAIL(a_info && a_info->pScreen, BadValue); EPHYR_RETURN_VAL_IF_FAIL(a_drawable && port_priv, BadValue); @@ -1171,11 +1152,6 @@ ephyrGetStill(KdScreenInfo * a_info, goto out; } - drw_x = clipped_area.x1; - drw_y = clipped_area.y1; - drw_w = clipped_area.x2 - clipped_area.x1; - drw_h = clipped_area.y2 - clipped_area.y1; - if (!ephyrHostXVGetStill(a_info->pScreen->myNum, port_priv->port_number, a_vid_x, a_vid_y, a_vid_w, a_vid_h, diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c index 157ac36b2..f2b458d90 100644 --- a/xorg-server/hw/kdrive/ephyr/hostx.c +++ b/xorg-server/hw/kdrive/ephyr/hostx.c @@ -117,6 +117,8 @@ extern EphyrKeySyms ephyrKeySyms; extern int monitorResolution; +extern Bool EphyrWantResize; + char *ephyrResName = NULL; int ephyrResNameFromCmd = 0; char *ephyrTitle = NULL; @@ -617,7 +619,8 @@ hostx_set_cmap_entry(unsigned char idx, */ void * hostx_screen_init(EphyrScreenInfo screen, - int width, int height, int buffer_height) + int width, int height, int buffer_height, + int *bytes_per_line, int *bits_per_pixel) { int bitmap_pad; Bool shm_success = False; @@ -694,10 +697,13 @@ hostx_screen_init(EphyrScreenInfo screen, malloc(host_screen->ximg->bytes_per_line * buffer_height); } + *bytes_per_line = host_screen->ximg->bytes_per_line; + *bits_per_pixel = host_screen->ximg->bits_per_pixel; + XResizeWindow(HostX.dpy, host_screen->win, width, height); /* Ask the WM to keep our size static */ - if (host_screen->win_pre_existing == None) { + if (host_screen->win_pre_existing == None && !EphyrWantResize) { size_hints = XAllocSizeHints(); size_hints->max_width = size_hints->min_width = width; size_hints->max_height = size_hints->min_height = height; @@ -858,7 +864,7 @@ hostx_load_keymap(void) (max_keycode - min_keycode + 1) * width); if (!ephyrKeySyms.map) - return; + goto out; for (i = 0; i < (max_keycode - min_keycode + 1); i++) for (j = 0; j < width; j++) @@ -871,6 +877,7 @@ hostx_load_keymap(void) ephyrKeySyms.maxKeyCode = max_keycode; ephyrKeySyms.mapWidth = width; + out: XFree(keymap); } @@ -1011,19 +1018,27 @@ hostx_get_event(EphyrHostXEvent * ev) case ConfigureNotify: { - struct EphyrHostScreen *host_screen = - host_screen_from_window(xev.xconfigure.window); - - if (host_screen && host_screen->win_pre_existing != None) { - ev->type = EPHYR_EV_CONFIGURE; - ev->data.configure.width = xev.xconfigure.width; - ev->data.configure.height = xev.xconfigure.height; - ev->data.configure.window = xev.xconfigure.window; - ev->data.configure.screen = host_screen->mynum; - return 1; + struct EphyrHostScreen *host_screen; + + /* event compression as for Expose events, cause + * we don't want to resize the framebuffer for + * every single change */ + while (XCheckTypedWindowEvent(HostX.dpy, xev.xconfigure.window, + ConfigureNotify, &xev)); + host_screen = host_screen_from_window(xev.xconfigure.window); + + if (!host_screen || + (host_screen->win_pre_existing == None && !EphyrWantResize)) { + return 0; } - return 0; + ev->type = EPHYR_EV_CONFIGURE; + ev->data.configure.width = xev.xconfigure.width; + ev->data.configure.height = xev.xconfigure.height; + ev->data.configure.window = xev.xconfigure.window; + ev->data.configure.screen = host_screen->mynum; + + return 1; } default: break; diff --git a/xorg-server/hw/kdrive/ephyr/hostx.h b/xorg-server/hw/kdrive/ephyr/hostx.h index 31c4053aa..38b7b3768 100644 --- a/xorg-server/hw/kdrive/ephyr/hostx.h +++ b/xorg-server/hw/kdrive/ephyr/hostx.h @@ -193,7 +193,8 @@ hostx_set_cmap_entry(unsigned char idx, unsigned char r, unsigned char g, unsigned char b); void *hostx_screen_init(EphyrScreenInfo screen, - int width, int height, int buffer_height); + int width, int height, int buffer_height, + int *bytes_per_line, int *bits_per_pixel); void diff --git a/xorg-server/hw/kdrive/fbdev/fbdev.c b/xorg-server/hw/kdrive/fbdev/fbdev.c index fd14afa92..fb6e3a292 100644 --- a/xorg-server/hw/kdrive/fbdev/fbdev.c +++ b/xorg-server/hw/kdrive/fbdev/fbdev.c @@ -465,16 +465,6 @@ fbdevRandRSetConfig(ScreenPtr pScreen, int oldheight; int oldmmwidth; int oldmmheight; - int newwidth, newheight; - - if (screen->randr & (RR_Rotate_0 | RR_Rotate_180)) { - newwidth = pSize->width; - newheight = pSize->height; - } - else { - newwidth = pSize->height; - newheight = pSize->width; - } if (wasEnabled) KdDisableScreen(pScreen); diff --git a/xorg-server/hw/kdrive/linux/mouse.c b/xorg-server/hw/kdrive/linux/mouse.c index c87507790..f4424478a 100644 --- a/xorg-server/hw/kdrive/linux/mouse.c +++ b/xorg-server/hw/kdrive/linux/mouse.c @@ -441,10 +441,8 @@ ps2SkipInit(KdPointerInfo * pi, int ninit, Bool ret_next) { Kmouse *km = pi->driverPrivate; int c = -1; - int skipping; Bool waiting; - skipping = 0; waiting = FALSE; while (ninit || ret_next) { c = MouseReadByte(&km->iob, MOUSE_TIMEOUT); @@ -469,8 +467,6 @@ static Bool ps2Init(KdPointerInfo * pi) { Kmouse *km = pi->driverPrivate; - int skipping; - Bool waiting; int id; unsigned char *init; int ninit; @@ -483,8 +479,6 @@ ps2Init(KdPointerInfo * pi) */ if (!MouseWriteByte(km->iob.fd, PSMC_SEND_DEV_ID, 100)) return FALSE; - skipping = 0; - waiting = FALSE; id = ps2SkipInit(pi, 0, TRUE); switch (id) { case 3: diff --git a/xorg-server/hw/kdrive/src/kinput.c b/xorg-server/hw/kdrive/src/kinput.c index b1068bbee..c30f1708d 100644 --- a/xorg-server/hw/kdrive/src/kinput.c +++ b/xorg-server/hw/kdrive/src/kinput.c @@ -1821,16 +1821,11 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo * ki, unsigned char scan_code, unsigned char is_up) { unsigned char key_code; - KeyClassPtr keyc = NULL; - KeybdCtrl *ctrl = NULL; int type; if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key) return; - keyc = ki->dixdev->key; - ctrl = &ki->dixdev->kbdfeed->ctrl; - if (scan_code >= ki->minScanCode && scan_code <= ki->maxScanCode) { key_code = scan_code + KD_MIN_KEYCODE - ki->minScanCode; @@ -1864,7 +1859,6 @@ void KdEnqueuePointerEvent(KdPointerInfo * pi, unsigned long flags, int rx, int ry, int rz) { - CARD32 ms; unsigned char buttons; int x, y, z; int (*matrix)[3] = kdPointerMatrix.matrix; @@ -1875,8 +1869,6 @@ KdEnqueuePointerEvent(KdPointerInfo * pi, unsigned long flags, int rx, int ry, if (!pi) return; - ms = GetTimeInMillis(); - /* we don't need to transform z, so we don't. */ if (flags & KD_MOUSE_DELTA) { if (pi->transformCoordinates) { diff --git a/xorg-server/hw/kdrive/src/kxv.c b/xorg-server/hw/kdrive/src/kxv.c index cf656363d..22639728d 100644 --- a/xorg-server/hw/kdrive/src/kxv.c +++ b/xorg-server/hw/kdrive/src/kxv.c @@ -1174,7 +1174,6 @@ void KdXVDisable(ScreenPtr pScreen) { XvScreenPtr pxvs; - KdXVScreenPtr ScreenPriv; XvAdaptorPtr pAdaptor; XvPortPtr pPort; XvPortRecPrivatePtr pPriv; @@ -1184,7 +1183,6 @@ KdXVDisable(ScreenPtr pScreen) return; pxvs = GET_XV_SCREEN(pScreen); - ScreenPriv = GET_KDXV_SCREEN(pScreen); for (i = 0; i < pxvs->nAdaptors; i++) { pAdaptor = &pxvs->pAdaptors[i]; diff --git a/xorg-server/hw/xfree86/common/xf86Events.c b/xorg-server/hw/xfree86/common/xf86Events.c index d92174edf..055223310 100644 --- a/xorg-server/hw/xfree86/common/xf86Events.c +++ b/xorg-server/hw/xfree86/common/xf86Events.c @@ -413,7 +413,6 @@ static void xf86VTSwitch(void) { int i; - static int prevSIGIO; InputInfoPtr pInfo; IHPtr ih; diff --git a/xorg-server/hw/xfree86/common/xf86Mode.c b/xorg-server/hw/xfree86/common/xf86Mode.c index d80dec892..706ab64fc 100644 --- a/xorg-server/hw/xfree86/common/xf86Mode.c +++ b/xorg-server/hw/xfree86/common/xf86Mode.c @@ -1370,7 +1370,6 @@ xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes, int saveType; PixmapFormatRec *BankFormat; ClockRangePtr cp; - ClockRangePtr storeClockRanges; int numTimings = 0; range hsync[MAX_HSYNC]; range vrefresh[MAX_VREFRESH]; @@ -1492,16 +1491,14 @@ xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes, /* * Store the clockRanges for later use by the VidMode extension. */ - storeClockRanges = scrp->clockRanges; - while (storeClockRanges != NULL) { - storeClockRanges = storeClockRanges->next; - } - for (cp = clockRanges; cp != NULL; cp = cp->next, - storeClockRanges = storeClockRanges->next) { - storeClockRanges = xnfalloc(sizeof(ClockRange)); + nt_list_for_each_entry(cp, clockRanges, next) { + ClockRangePtr newCR = xnfalloc(sizeof(ClockRange)); + memcpy(newCR, cp, sizeof(ClockRange)); + newCR->next = NULL; if (scrp->clockRanges == NULL) - scrp->clockRanges = storeClockRanges; - memcpy(storeClockRanges, cp, sizeof(ClockRange)); + scrp->clockRanges = newCR; + else + nt_list_append(newCR, scrp->clockRanges, ClockRange, next); } /* Determine which pixmap format to pass to scanLineWidth() */ diff --git a/xorg-server/hw/xfree86/common/xf86Option.c b/xorg-server/hw/xfree86/common/xf86Option.c index 40c9d15f4..607c33354 100644 --- a/xorg-server/hw/xfree86/common/xf86Option.c +++ b/xorg-server/hw/xfree86/common/xf86Option.c @@ -743,7 +743,7 @@ xf86TokenToOptName(const OptionInfoRec * table, int token) const OptionInfoRec *p; p = xf86TokenToOptinfo(table, token); - return p->name; + return p ? p->name : NULL; } Bool diff --git a/xorg-server/hw/xfree86/common/xf86fbman.c b/xorg-server/hw/xfree86/common/xf86fbman.c index c2e7bab9f..4da6af2b6 100644 --- a/xorg-server/hw/xfree86/common/xf86fbman.c +++ b/xorg-server/hw/xfree86/common/xf86fbman.c @@ -320,15 +320,17 @@ localRegisterFreeBoxCallback(ScreenPtr pScreen, newCallbacks = realloc(offman->FreeBoxesUpdateCallback, sizeof(FreeBoxCallbackProcPtr) * (offman->NumCallbacks + 1)); + if (!newCallbacks) + return FALSE; + else + offman->FreeBoxesUpdateCallback = newCallbacks; newPrivates = realloc(offman->devPrivates, sizeof(DevUnion) * (offman->NumCallbacks + 1)); - - if (!newCallbacks || !newPrivates) + if (!newPrivates) return FALSE; - - offman->FreeBoxesUpdateCallback = newCallbacks; - offman->devPrivates = newPrivates; + else + offman->devPrivates = newPrivates; offman->FreeBoxesUpdateCallback[offman->NumCallbacks] = FreeBoxCallback; offman->devPrivates[offman->NumCallbacks].ptr = devPriv; diff --git a/xorg-server/hw/xfree86/common/xf86xvmc.c b/xorg-server/hw/xfree86/common/xf86xvmc.c index 78a32bfe1..3169c054c 100644 --- a/xorg-server/hw/xfree86/common/xf86xvmc.c +++ b/xorg-server/hw/xfree86/common/xf86xvmc.c @@ -158,8 +158,10 @@ xf86XvMCScreenInit(ScreenPtr pScreen, if (!(pAdapt = malloc(sizeof(XvMCAdaptorRec) * num_adaptors))) return FALSE; - if (!dixRegisterPrivateKey(&XF86XvMCScreenKeyRec, PRIVATE_SCREEN, 0)) + if (!dixRegisterPrivateKey(&XF86XvMCScreenKeyRec, PRIVATE_SCREEN, 0)) { + free(pAdapt); return FALSE; + } if (!(pScreenPriv = malloc(sizeof(xf86XvMCScreenRec)))) { free(pAdapt); diff --git a/xorg-server/hw/xfree86/ddc/ddc.c b/xorg-server/hw/xfree86/ddc/ddc.c index 28c969646..44c1d535c 100644 --- a/xorg-server/hw/xfree86/ddc/ddc.c +++ b/xorg-server/hw/xfree86/ddc/ddc.c @@ -91,15 +91,16 @@ resort(unsigned char *s_block) unsigned char *d_new, *d_ptr, *d_end, *s_ptr, *s_end; unsigned char tmp; + s_ptr = find_header(s_block); + if (!s_ptr) + return NULL; s_end = s_block + EDID1_LEN; + d_new = malloc(EDID1_LEN); if (!d_new) return NULL; d_end = d_new + EDID1_LEN; - s_ptr = find_header(s_block); - if (!s_ptr) - return NULL; for (d_ptr = d_new; d_ptr < d_end; d_ptr++) { tmp = *(s_ptr++); *d_ptr = tmp; diff --git a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c index 8d48a7542..d32aac1cf 100644 --- a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c +++ b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c @@ -16,7 +16,6 @@ * Externing inputInfo is not the nice way to do it but it works. */ #include "inputstr.h" -extern InputInfo inputInfo; DevPrivateKeyRec xf86CursorScreenKeyRec; diff --git a/xorg-server/hw/xquartz/GL/visualConfigs.c b/xorg-server/hw/xquartz/GL/visualConfigs.c index 03486cd66..a00abf29a 100644 --- a/xorg-server/hw/xquartz/GL/visualConfigs.c +++ b/xorg-server/hw/xquartz/GL/visualConfigs.c @@ -262,6 +262,9 @@ __GLXconfig *__glXAquaCreateVisualConfigs(int *numConfigsPtr, int screenNumber) c->bindToTextureTargets = 0; c->yInverted = 0; + /* EXT_framebuffer_sRGB */ + c->sRGBCapable = GL_FALSE; + c = c->next; } } diff --git a/xorg-server/hw/xwin/glx/indirect.c b/xorg-server/hw/xwin/glx/indirect.c index 00cef3673..14a47110a 100644 --- a/xorg-server/hw/xwin/glx/indirect.c +++ b/xorg-server/hw/xwin/glx/indirect.c @@ -2025,6 +2025,7 @@ glxWinCreateConfigs(HDC hdc, glxWinScreen * screen) c->base.bindToMipmapTexture = -1; c->base.bindToTextureTargets = -1; c->base.yInverted = -1; + c->base.sRGBCapable = 0; n++; @@ -2419,6 +2420,7 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen) GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT | GLX_TEXTURE_RECTANGLE_BIT_EXT; c->base.yInverted = -1; + c->base.sRGBCapable = 0; n++; diff --git a/xorg-server/include/dix-config.h.in b/xorg-server/include/dix-config.h.in index e1cb9eb51..a643dfcc8 100644 --- a/xorg-server/include/dix-config.h.in +++ b/xorg-server/include/dix-config.h.in @@ -60,6 +60,9 @@ /* Has backtrace support */ #undef HAVE_BACKTRACE +/* Has libunwind support */ +#undef HAVE_LIBUNWIND + /* Define to 1 if you have the header file. */ #undef HAVE_BYTESWAP_H diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h index 5c65597e4..304895ffc 100644 --- a/xorg-server/include/input.h +++ b/xorg-server/include/input.h @@ -638,6 +638,11 @@ extern _X_HIDDEN void valuator_set_mode(DeviceIntPtr dev, int axis, int mode); xfixes/cursor.c uses it to determine if the cursor is enabled */ extern Bool EnableCursor; +/* Set to FALSE by default - ChangeWindowAttributes sets it to TRUE on + * CWCursor, xfixes/cursor.c uses it to determine if the cursor is enabled + */ +extern Bool CursorVisible; + extern _X_EXPORT ValuatorMask *valuator_mask_new(int num_valuators); extern _X_EXPORT void valuator_mask_free(ValuatorMask **mask); extern _X_EXPORT void valuator_mask_set_range(ValuatorMask *mask, diff --git a/xorg-server/include/list.h b/xorg-server/include/list.h index 067c6794f..11de7c561 100644 --- a/xorg-server/include/list.h +++ b/xorg-server/include/list.h @@ -119,7 +119,7 @@ struct xorg_list { * * @param The list to initialized. */ -static void +static inline void xorg_list_init(struct xorg_list *list) { list->next = list->prev = list; diff --git a/xorg-server/os/Makefile.am b/xorg-server/os/Makefile.am index 88914852f..364b6da2d 100644 --- a/xorg-server/os/Makefile.am +++ b/xorg-server/os/Makefile.am @@ -34,6 +34,11 @@ if XDMCP libos_la_SOURCES += $(XDMCP_SRCS) endif +if HAVE_LIBUNWIND +AM_CFLAGS += $(LIBUNWIND_CFLAGS) +libos_la_LIBADD += $(LIBUNWIND_LIBS) +endif + EXTRA_DIST = $(SECURERPC_SRCS) $(XDMCP_SRCS) if SPECIAL_DTRACE_OBJECTS diff --git a/xorg-server/os/backtrace.c b/xorg-server/os/backtrace.c index daac60cf6..426f9b15b 100644 --- a/xorg-server/os/backtrace.c +++ b/xorg-server/os/backtrace.c @@ -30,6 +30,80 @@ #include #include +#ifdef HAVE_LIBUNWIND + +#define UNW_LOCAL_ONLY +#include + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include + +void +xorg_backtrace(void) +{ + unw_cursor_t cursor; + unw_context_t context; + unw_word_t off; + unw_proc_info_t pip; + int ret, i = 0; + char procname[256]; + const char *filename; + Dl_info dlinfo; + + pip.unwind_info = NULL; + ret = unw_getcontext(&context); + if (ret) { + ErrorFSigSafe("unw_getcontext failed: %s [%d]\n", unw_strerror(ret), + ret); + return; + } + + ret = unw_init_local(&cursor, &context); + if (ret) { + ErrorFSigSafe("unw_init_local failed: %s [%d]\n", unw_strerror(ret), + ret); + return; + } + + ErrorFSigSafe("\n"); + ErrorFSigSafe("Backtrace:\n"); + ret = unw_step(&cursor); + while (ret > 0) { + ret = unw_get_proc_info(&cursor, &pip); + if (ret) { + ErrorFSigSafe("unw_get_proc_info failed: %s [%d]\n", + unw_strerror(ret), ret); + break; + } + + ret = unw_get_proc_name(&cursor, procname, 256, &off); + if (ret && ret != -UNW_ENOMEM) { + if (ret != -UNW_EUNSPEC) + ErrorFSigSafe("unw_get_proc_name failed: %s [%d]\n", + unw_strerror(ret), ret); + procname[0] = '?'; + procname[1] = 0; + } + + if (dladdr((void *)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname && + *dlinfo.dli_fname) + filename = dlinfo.dli_fname; + else + filename = "?"; + + ErrorFSigSafe("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname, + ret == -UNW_ENOMEM ? "..." : "", (int)off, + (void *)(pip.start_ip + off)); + + ret = unw_step(&cursor); + if (ret < 0) + ErrorFSigSafe("unw_step failed: %s [%d]\n", unw_strerror(ret), ret); + } + ErrorFSigSafe("\n"); +} +#else /* HAVE_LIBUNWIND */ #ifdef HAVE_BACKTRACE #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -246,3 +320,4 @@ xorg_backtrace(void) #endif #endif +#endif diff --git a/xorg-server/os/log.c b/xorg-server/os/log.c index 95bd8cca9..dc6e2888b 100644 --- a/xorg-server/os/log.c +++ b/xorg-server/os/log.c @@ -279,6 +279,10 @@ LogSetParameter(LogParameter param, int value) } } +/** + * Signal-safe snprintf, with some limitations over snprintf. Be careful + * which directives you use. + */ static int pnprintf(char *string, size_t size, const char *f, va_list args) { diff --git a/xorg-server/randr/rrcrtc.c b/xorg-server/randr/rrcrtc.c index 6e2eca5ad..721b05ac3 100644 --- a/xorg-server/randr/rrcrtc.c +++ b/xorg-server/randr/rrcrtc.c @@ -363,13 +363,12 @@ void RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc) { ScreenPtr master = crtc->pScreen->current_master; - int ret; PixmapPtr mscreenpix; rrScrPriv(crtc->pScreen); mscreenpix = master->GetScreenPixmap(master); - ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL); + pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL); if (crtc->scanout_pixmap) { master->StopPixmapTracking(mscreenpix, crtc->scanout_pixmap); /* @@ -442,7 +441,7 @@ rrCheckPixmapBounding(ScreenPtr pScreen, RRCrtcPtr rr_crtc, int x, int y, int w, int h) { RegionRec root_pixmap_region, total_region, new_crtc_region; - int i, c; + int c; BoxRec newbox; BoxPtr newsize; ScreenPtr slave; @@ -502,10 +501,8 @@ rrCheckPixmapBounding(ScreenPtr pScreen, new_height == screen_pixmap->drawable.height) { ErrorF("adjust shatters %d %d\n", newsize->x1, newsize->x2); } else { - int ret; rrScrPriv(pScreen); - ret = pScrPriv->rrScreenSetSize(pScreen, - new_width, new_height, 0, 0); + pScrPriv->rrScreenSetSize(pScreen, new_width, new_height, 0, 0); } /* set shatters TODO */ diff --git a/xorg-server/xfixes/cursor.c b/xorg-server/xfixes/cursor.c index 568e717fa..90a026b28 100644 --- a/xorg-server/xfixes/cursor.c +++ b/xorg-server/xfixes/cursor.c @@ -129,8 +129,7 @@ typedef struct _CursorScreen { #define Unwrap(as,s,elt,backup) (((backup) = (s)->elt), (s)->elt = (as)->elt) /* The cursor doesn't show up until the first XDefineCursor() */ -static Bool CursorVisible = FALSE; - +Bool CursorVisible = FALSE; Bool EnableCursor = TRUE; static Bool @@ -142,12 +141,7 @@ CursorDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) Unwrap(cs, pScreen, DisplayCursor, backupProc); - /* - * Have to check ConnectionInfo to distinguish client requests from - * initial root window setup. Not a great way to do it, I admit. - */ - if (ConnectionInfo) - CursorVisible = EnableCursor; + CursorVisible = CursorVisible && EnableCursor; if (cs->pCursorHideCounts != NULL || !CursorVisible) { ret = (*pScreen->DisplayCursor) (pDev, pScreen, NullCursor); diff --git a/xorg-server/xfixes/xfixesint.h b/xorg-server/xfixes/xfixesint.h index 334c71fbf..44e889040 100644 --- a/xorg-server/xfixes/xfixesint.h +++ b/xorg-server/xfixes/xfixesint.h @@ -291,8 +291,10 @@ int SProcXFixesDestroyPointerBarrier(ClientPtr client); /* Xinerama */ +#ifdef PANORAMIX extern int (*PanoramiXSaveXFixesVector[XFixesNumberRequests]) (ClientPtr); void PanoramiXFixesInit(void); void PanoramiXFixesReset(void); +#endif #endif /* _XFIXESINT_H_ */ diff --git a/xorg-server/xkb/xkb.c b/xorg-server/xkb/xkb.c index 7e51e4080..c78aceb78 100644 --- a/xorg-server/xkb/xkb.c +++ b/xorg-server/xkb/xkb.c @@ -3073,6 +3073,7 @@ XkbComputeGetIndicatorMapReplySize(XkbIndicatorPtr indicators, nIndicators++; } rep->length = (nIndicators * SIZEOF(xkbIndicatorMapWireDesc)) / 4; + rep->nIndicators = nIndicators; return Success; } @@ -3984,13 +3985,11 @@ _XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq * stuff, CARD32 *data) { XkbDescRec *xkb; - XkbNamesRec *names; CARD32 *tmp; Atom bad; tmp = data; xkb = dev->key->xkbInfo->desc; - names = xkb->names; if (stuff->which & XkbKeyTypeNamesMask) { int i; diff --git a/xorg-server/xkb/xkbActions.c b/xorg-server/xkb/xkbActions.c index 416de925d..e32005cf6 100644 --- a/xorg-server/xkb/xkbActions.c +++ b/xorg-server/xkb/xkbActions.c @@ -222,7 +222,6 @@ _XkbFilterSetState(XkbSrvInfoPtr xkbi, #define LATCH_KEY_DOWN 1 #define LATCH_PENDING 2 -#define NO_LATCH 3 static int _XkbFilterLatchState(XkbSrvInfoPtr xkbi, @@ -230,6 +229,7 @@ _XkbFilterLatchState(XkbSrvInfoPtr xkbi, { if (filter->keycode == 0) { /* initial press */ + AccessXCancelRepeatKey(xkbi,keycode); filter->keycode = keycode; filter->active = 1; filter->filterOthers = 1; @@ -250,91 +250,102 @@ _XkbFilterLatchState(XkbSrvInfoPtr xkbi, else if (pAction && (filter->priv == LATCH_PENDING)) { if (((1 << pAction->type) & XkbSA_BreakLatch) != 0) { filter->active = 0; - if (filter->upAction.type == XkbSA_LatchMods) - xkbi->state.latched_mods &= ~filter->upAction.mods.mask; - else - xkbi->state.latched_group -= - XkbSAGroup(&filter->upAction.group); - } - else if ((pAction->type == filter->upAction.type) && - (pAction->mods.flags == filter->upAction.mods.flags) && - (pAction->mods.mask == filter->upAction.mods.mask)) { - if (filter->upAction.mods.flags & XkbSA_LatchToLock) { - XkbControlsPtr ctrls = xkbi->desc->ctrls; - - if (filter->upAction.type == XkbSA_LatchMods) - pAction->mods.type = XkbSA_LockMods; - else - pAction->group.type = XkbSA_LockGroup; - if (XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask) && - (ctrls->enabled_ctrls & XkbStickyKeysMask)) { - XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK, - XkbStickyKeysMask); - } - } - else { - if (filter->upAction.type == XkbSA_LatchMods) - pAction->mods.type = XkbSA_SetMods; - else - pAction->group.type = XkbSA_SetGroup; - } - if (filter->upAction.type == XkbSA_LatchMods) - xkbi->state.latched_mods &= ~filter->upAction.mods.mask; - else - xkbi->state.latched_group -= - XkbSAGroup(&filter->upAction.group); - filter->active = 0; + /* If one latch is broken, all latches are broken, so it's no use + to find out which particular latch this filter tracks. */ + xkbi->state.latched_mods = 0; + xkbi->state.latched_group = 0; } } - else if (filter->keycode == keycode) { /* release */ + else if (filter->keycode == keycode && filter->priv != LATCH_PENDING){ + /* The test above for LATCH_PENDING skips subsequent releases of the + key after it has been released first time and the latch became + pending. */ XkbControlsPtr ctrls = xkbi->desc->ctrls; - int needBeep; - int beepType = _BEEP_NONE; + int needBeep = ((ctrls->enabled_ctrls & XkbStickyKeysMask) && + XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask)); - needBeep = ((ctrls->enabled_ctrls & XkbStickyKeysMask) && - XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask)); if (filter->upAction.type == XkbSA_LatchMods) { - xkbi->clearMods = filter->upAction.mods.mask; - if ((filter->upAction.mods.flags & XkbSA_ClearLocks) && - (xkbi->clearMods & xkbi->state.locked_mods) == - xkbi->clearMods) { - xkbi->state.locked_mods &= ~xkbi->clearMods; - filter->priv = NO_LATCH; - beepType = _BEEP_STICKY_UNLOCK; + unsigned char mask = filter->upAction.mods.mask; + unsigned char common; + + xkbi->clearMods = mask; + + /* ClearLocks */ + common = mask & xkbi->state.locked_mods; + if ((filter->upAction.mods.flags & XkbSA_ClearLocks) && common) { + mask &= ~common; + xkbi->state.locked_mods &= ~common; + if (needBeep) + XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK, + XkbStickyKeysMask); + } + /* LatchToLock */ + common = mask & xkbi->state.latched_mods; + if ((filter->upAction.mods.flags & XkbSA_LatchToLock) && common) { + unsigned char newlocked; + + mask &= ~common; + newlocked = common & ~xkbi->state.locked_mods; + if(newlocked){ + xkbi->state.locked_mods |= newlocked; + if (needBeep) + XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK, + XkbStickyKeysMask); + + } + xkbi->state.latched_mods &= ~common; + } + /* Latch remaining modifiers, if any. */ + if (mask) { + xkbi->state.latched_mods |= mask; + filter->priv = LATCH_PENDING; + if (needBeep) + XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH, + XkbStickyKeysMask); } } else { xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); + /* ClearLocks */ if ((filter->upAction.group.flags & XkbSA_ClearLocks) && (xkbi->state.locked_group)) { xkbi->state.locked_group = 0; - filter->priv = NO_LATCH; - beepType = _BEEP_STICKY_UNLOCK; + if (needBeep) + XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK, + XkbStickyKeysMask); } - } - if (filter->priv == NO_LATCH) { - filter->active = 0; - } - else { - filter->priv = LATCH_PENDING; - if (filter->upAction.type == XkbSA_LatchMods) { - xkbi->state.latched_mods |= filter->upAction.mods.mask; - needBeep = xkbi->state.latched_mods ? needBeep : 0; - xkbi->state.latched_mods |= filter->upAction.mods.mask; + /* LatchToLock */ + else if ((filter->upAction.group.flags & XkbSA_LatchToLock) + && (xkbi->state.latched_group)) { + xkbi->state.locked_group += XkbSAGroup(&filter->upAction.group); + xkbi->state.latched_group -= XkbSAGroup(&filter->upAction.group); + if(XkbSAGroup(&filter->upAction.group) && needBeep) + XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK, + XkbStickyKeysMask); } - else { - xkbi->state.latched_group += - XkbSAGroup(&filter->upAction.group); + /* Latch group */ + else if(XkbSAGroup(&filter->upAction.group)){ + xkbi->state.latched_group += XkbSAGroup(&filter->upAction.group); + filter->priv = LATCH_PENDING; + if (needBeep) + XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH, + XkbStickyKeysMask); } - if (needBeep && (beepType == _BEEP_NONE)) - beepType = _BEEP_STICKY_LATCH; } - if (needBeep && (beepType != _BEEP_NONE)) - XkbDDXAccessXBeep(xkbi->device, beepType, XkbStickyKeysMask); + + if (filter->priv != LATCH_PENDING) + filter->active = 0; } - else if (filter->priv == LATCH_KEY_DOWN) { - filter->priv = NO_LATCH; - filter->filterOthers = 0; + else if (pAction && (filter->priv == LATCH_KEY_DOWN)) { + /* Latch was broken before it became pending: degrade to a + SetMods/SetGroup. */ + if (filter->upAction.type == XkbSA_LatchMods) + filter->upAction.type = XkbSA_SetMods; + else + filter->upAction.type = XkbSA_SetGroup; + filter->filter = _XkbFilterSetState; + filter->priv = 0; + return filter->filter(xkbi, filter, keycode, pAction); } return 1; } -- cgit v1.2.3 From 59038e048c4be1e69744b087ba31386e98141a8f Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 8 Apr 2013 08:17:23 +0200 Subject: fontconfig libXau mesa xserver xkeyboard-config git update 8 Apr 2013 xserver commit 8928f8fa0bb154ce437af703ff702016f0dcf127 xkeyboard-config commit e5c6729f3679fe87a703eb1d7ec1cf0a61814ca8 libXau commit f5a57d8a21a34d7084cce294e24c0422e02ef8ef fontconfig commit 18bf57c70aafcad031c0b43756b754dcaf6a756a mesa commit eff66bc9f855fff5c4f5f57f247254a97431e8ad --- fontconfig/Makefile.am | 1 + fontconfig/README | 65 +- fontconfig/Tools.mk | 4 +- fontconfig/configure.ac | 8 +- fontconfig/fc-cache/Makefile.am | 2 +- fontconfig/fc-cat/Makefile.am | 2 +- fontconfig/fc-list/Makefile.am | 2 +- fontconfig/fc-match/Makefile.am | 2 +- fontconfig/fc-pattern/Makefile.am | 2 +- fontconfig/fc-query/Makefile.am | 2 +- fontconfig/fc-scan/Makefile.am | 2 +- fontconfig/fc-validate/Makefile.am | 2 +- fontconfig/fontconfig/fontconfig.h | 2 +- fontconfig/new-version.sh | 2 +- fontconfig/src/Makefile.am | 2 +- fontconfig/src/fcmatch.c | 23 +- libXau/AuFileName.c | 7 +- libXau/AuGetAddr.c | 15 +- libXau/AuGetBest.c | 15 +- libXau/AuLock.c | 30 +- libXau/AuUnlock.c | 10 +- libXau/configure.ac | 4 + mesalib/docs/GL3.txt | 4 +- mesalib/docs/application-issues.html | 83 ++ mesalib/docs/contents.html | 1 + mesalib/src/gallium/auxiliary/Makefile.sources | 5 + mesalib/src/gallium/auxiliary/hud/font.c | 446 ++++++++ mesalib/src/gallium/auxiliary/hud/font.h | 59 ++ mesalib/src/gallium/auxiliary/hud/hud_context.c | 1078 ++++++++++++++++++++ mesalib/src/gallium/auxiliary/hud/hud_context.h | 45 + mesalib/src/gallium/auxiliary/hud/hud_cpu.c | 166 +++ .../src/gallium/auxiliary/hud/hud_driver_query.c | 210 ++++ mesalib/src/gallium/auxiliary/hud/hud_fps.c | 81 ++ mesalib/src/gallium/auxiliary/hud/hud_private.h | 92 ++ mesalib/src/gallium/auxiliary/util/u_blitter.c | 26 +- mesalib/src/gallium/auxiliary/util/u_cpu_detect.c | 1 + mesalib/src/gallium/auxiliary/util/u_cpu_detect.h | 1 + .../src/gallium/auxiliary/util/u_debug_memory.c | 55 + mesalib/src/gallium/auxiliary/util/u_format.h | 1 + mesalib/src/gallium/auxiliary/util/u_inlines.h | 4 +- mesalib/src/gallium/auxiliary/util/u_resource.c | 119 +-- mesalib/src/gallium/auxiliary/util/u_resource.h | 34 + mesalib/src/gallium/auxiliary/util/u_transfer.c | 73 ++ mesalib/src/glsl/Makefile.sources | 1 + mesalib/src/glsl/glcpp/glcpp-parse.y | 3 + mesalib/src/glsl/glsl_parser_extras.cpp | 2 + mesalib/src/glsl/glsl_parser_extras.h | 2 + mesalib/src/glsl/glsl_types.cpp | 2 + mesalib/src/glsl/ir.cpp | 5 +- mesalib/src/glsl/ir.h | 10 +- mesalib/src/glsl/ir_clone.cpp | 1 + mesalib/src/glsl/ir_constant_expression.cpp | 2 +- mesalib/src/glsl/ir_hv_accept.cpp | 1 + mesalib/src/glsl/ir_optimization.h | 1 + mesalib/src/glsl/ir_print_visitor.cpp | 1 + mesalib/src/glsl/ir_reader.cpp | 14 +- mesalib/src/glsl/ir_rvalue_visitor.cpp | 1 + mesalib/src/glsl/ir_validate.cpp | 6 + mesalib/src/glsl/linker.cpp | 2 - mesalib/src/glsl/lower_jumps.cpp | 4 +- mesalib/src/glsl/lower_ubo_reference.cpp | 10 +- mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp | 103 ++ mesalib/src/glsl/opt_tree_grafting.cpp | 1 + mesalib/src/glsl/standalone_scaffolding.cpp | 1 + .../glapi/gen/ARB_texture_storage_multisample.xml | 31 + mesalib/src/mapi/glapi/gen/gl_API.xml | 4 + mesalib/src/mesa/drivers/common/driverfuncs.c | 3 +- mesalib/src/mesa/drivers/common/meta.c | 18 +- mesalib/src/mesa/drivers/dri/common/Android.mk | 3 +- mesalib/src/mesa/drivers/dri/common/drirc | 6 + mesalib/src/mesa/main/attrib.c | 9 +- mesalib/src/mesa/main/blend.c | 82 +- mesalib/src/mesa/main/blend.h | 14 + mesalib/src/mesa/main/compiler.h | 2 +- mesalib/src/mesa/main/extensions.c | 2 + mesalib/src/mesa/main/fbobject.c | 34 +- mesalib/src/mesa/main/formatquery.c | 15 + mesalib/src/mesa/main/formatquery.h | 4 + mesalib/src/mesa/main/framebuffer.c | 6 + mesalib/src/mesa/main/get.c | 18 +- mesalib/src/mesa/main/get_hash_params.py | 2 +- mesalib/src/mesa/main/imports.h | 6 - mesalib/src/mesa/main/light.c | 3 +- mesalib/src/mesa/main/mtypes.h | 18 +- mesalib/src/mesa/main/readpix.c | 5 +- mesalib/src/mesa/main/shaderapi.c | 6 +- mesalib/src/mesa/main/state.c | 51 +- mesalib/src/mesa/main/stencil.c | 5 + mesalib/src/mesa/main/texenv.c | 3 +- mesalib/src/mesa/main/teximage.c | 67 +- mesalib/src/mesa/main/teximage.h | 11 + mesalib/src/mesa/main/texparam.c | 91 +- mesalib/src/mesa/main/texstorage.c | 37 +- mesalib/src/mesa/main/texstorage.h | 3 + mesalib/src/mesa/main/version.c | 3 +- mesalib/src/mesa/program/ir_to_mesa.cpp | 3 + mesalib/src/mesa/program/prog_cache.c | 11 +- mesalib/src/mesa/program/prog_statevars.c | 8 +- mesalib/src/mesa/program/register_allocate.c | 31 +- mesalib/src/mesa/program/register_allocate.h | 1 + mesalib/src/mesa/state_tracker/st_atom_constbuf.c | 8 +- .../src/mesa/state_tracker/st_atom_rasterizer.c | 3 +- mesalib/src/mesa/state_tracker/st_atom_shader.c | 3 +- mesalib/src/mesa/state_tracker/st_cb_bitmap.c | 4 +- mesalib/src/mesa/state_tracker/st_cb_drawpixels.c | 11 +- mesalib/src/mesa/state_tracker/st_cb_drawtex.c | 4 +- mesalib/src/mesa/state_tracker/st_cb_readpixels.c | 3 - mesalib/src/mesa/state_tracker/st_cb_texture.c | 2 +- mesalib/src/mesa/state_tracker/st_extensions.c | 11 + mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 9 +- mesalib/src/mesa/state_tracker/st_manager.c | 5 +- mesalib/src/mesa/swrast/s_blit.c | 8 +- xorg-server/hw/kdrive/fbdev/fbdev.c | 18 + xorg-server/hw/xfree86/man/xorg.conf.man | 11 + xorg-server/hw/xfree86/modes/xf86Crtc.c | 89 ++ xorg-server/xkeyboard-config/symbols/gb | 3 +- .../xkeyboard-config/symbols/macintosh_vndr/gb | 4 +- xorg-server/xkeyboard-config/symbols/md | 2 +- 118 files changed, 3417 insertions(+), 358 deletions(-) create mode 100644 mesalib/docs/application-issues.html create mode 100644 mesalib/src/gallium/auxiliary/hud/font.c create mode 100644 mesalib/src/gallium/auxiliary/hud/font.h create mode 100644 mesalib/src/gallium/auxiliary/hud/hud_context.c create mode 100644 mesalib/src/gallium/auxiliary/hud/hud_context.h create mode 100644 mesalib/src/gallium/auxiliary/hud/hud_cpu.c create mode 100644 mesalib/src/gallium/auxiliary/hud/hud_driver_query.c create mode 100644 mesalib/src/gallium/auxiliary/hud/hud_fps.c create mode 100644 mesalib/src/gallium/auxiliary/hud/hud_private.h create mode 100644 mesalib/src/gallium/auxiliary/util/u_resource.h create mode 100644 mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp create mode 100644 mesalib/src/mapi/glapi/gen/ARB_texture_storage_multisample.xml diff --git a/fontconfig/Makefile.am b/fontconfig/Makefile.am index cc5435ea0..d310b4b62 100644 --- a/fontconfig/Makefile.am +++ b/fontconfig/Makefile.am @@ -53,6 +53,7 @@ MAINTAINERCLEANFILES = \ $(srcdir)/ltmain.sh \ $(srcdir)/missing \ $(srcdir)/mkinstalldirs \ + $(srcdir)/test-driver \ `find "$(srcdir)" -type f -name Makefile.in -print` pkgconfig_DATA = fontconfig.pc diff --git a/fontconfig/README b/fontconfig/README index fcd3ab343..a855f28ff 100644 --- a/fontconfig/README +++ b/fontconfig/README @@ -1,12 +1,73 @@ Fontconfig Font configuration and customization library - Version 2.10.91 (2.11 RC1) - 2013-01-10 + Version 2.10.92 (2.11 RC2) + 2013-03-29 Check INSTALL for compilation and installation instructions. Report bugs to https://bugs.freedesktop.org in the fontconfig module. +2.10.92 (2.11 RC2) + +Akira TAGOH (33): + Fix the build fail on MinGW + Bug 50497 - RFE: Add OpenType feature tags support + Improve FcGetPrgname() to work on BSD + Better fix for 2fe5ddfd + Add missing file descriptor to F_DUPFD_CLOEXEC + Fix mkstemp absence for some platform + Fix installation on MinGW32 + Add another approach to FC_PRGNAME for Solaris 10 or before + remove the unnecessary code + Bug 59385 - Do the right thing for intermixed edit and test elements + Bug 23757 - Add mode="delete" to + Modernize configure.ac + Use AM_MISSING_PROG instead of hardcoding missing + Revert "test: Use SH_LOG_COMPILER and AM_TESTS_ENVIRONMENT" + Use AM_MISSING_PROG instead of hardcoding missing + Bug 50733 - Add font-file hash? + Bug 60312 - DIST_SUBDIRS should never appear in a conditional + Update _FcMatchers definition logic + Bump the cache version to 4 + Add Culmus foundry to the vendor list + Bug 60748 - broken conf.d/10-autohint.conf and conf.d/10-unhinted.conf + Bug 60783 - Add Liberation Sans Narrow to 30-metric-aliases.conf + Fix a typo + Fix a crash when the object is non-builtin object + Fix broken sort order with FcFontSort() + Fix a memory leak + Bug 59456 - Adding a --sysroot like option to fc-cache + Do not copy FC_*LANG_OBJECT even if it's not available on the pattern + Fix a SIGSEGV on FcPatternGet* with NULL pattern + Bug 38737 - Wishlist: support FC_POSTSCRIPT_NAME + Minor cleanup + Bump libtool revision + Minor fix + +Behdad Esfahbod (12): + Resepct $NOCONFIGURE + Ensure we find the uninstalled fontconfig header + Copy all values from pattern to font if the font doesn't have the element + Minor + Bug 59379 - FC_PRGNAME + Remove unused checks for common functions + Minor + Fix fc-cache crash caused by looking up NULL object incorrectly + Fix FC_PRGNAME default + Fix readlink failure + Accept digits as part of OpenType script tags + Fix crash with FcConfigSetCurrent(NULL) + +Christoph J. Thompson (1): + Use the PKG_INSTALLDIR macro. + +Colin Walters (1): + build: Only use PKG_INSTALLDIR if available + +Quentin Glidic (2): + test: Use SH_LOG_COMPILER and AM_TESTS_ENVIRONMENT + Use LOG_COMPILER and AM_TESTS_ENVIRONMENT + 2.10.91 (2.11 RC1) Akira TAGOH (19): diff --git a/fontconfig/Tools.mk b/fontconfig/Tools.mk index 56766da0e..f0fa0ec50 100644 --- a/fontconfig/Tools.mk +++ b/fontconfig/Tools.mk @@ -32,7 +32,7 @@ TOOL=./$(DIR)$(EXEEXT_FOR_BUILD) EXTRA_DIST = $(TARG) $(TMPL) $(TSRC) $(DIST) -INCLUDES = \ +AM_CPPFLAGS = \ -I$(builddir) \ -I$(srcdir) \ -I$(top_builddir)/src \ @@ -43,7 +43,7 @@ INCLUDES = \ $(WARN_CFLAGS) $(TOOL): $(TSRC) $(ALIAS_FILES) - $(AM_V_GEN) $(CC_FOR_BUILD) -o $(TOOL) $< $(INCLUDES) + $(AM_V_GEN) $(CC_FOR_BUILD) -o $(TOOL) $< $(AM_CPPFLAGS) $(TARG): $(TMPL) $(TSRC) $(DEPS) $(AM_V_GEN) $(MAKE) $(TOOL) && \ diff --git a/fontconfig/configure.ac b/fontconfig/configure.ac index 81e02ee1e..791937226 100644 --- a/fontconfig/configure.ac +++ b/fontconfig/configure.ac @@ -33,7 +33,7 @@ dnl This is the package version number, not the shared library dnl version. This same version number must appear in fontconfig/fontconfig.h dnl Yes, it is a pain to synchronize version numbers. Unfortunately, it's dnl not possible to extract the version number here from fontconfig.h -AC_INIT([fontconfig], [2.10.91], [https://bugs.freedesktop.org/enger_bug.cgi?product=fontconfig]) +AC_INIT([fontconfig], [2.10.92], [https://bugs.freedesktop.org/enger_bug.cgi?product=fontconfig]) AM_INIT_AUTOMAKE([1.11 parallel-tests dist-bzip2]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) @@ -42,11 +42,11 @@ dnl libtool versioning dnl bump revision when fixing bugs dnl bump current and age, reset revision to zero when adding APIs dnl bump current, leave age, reset revision to zero when changing/removing APIS -LIBT_CURRENT=7 -LIBT_REVISION=2 +LIBT_CURRENT=8 +LIBT_REVISION=0 AC_SUBST(LIBT_CURRENT) AC_SUBST(LIBT_REVISION) -LIBT_AGE=6 +LIBT_AGE=7 LIBT_VERSION_INFO="$LIBT_CURRENT:$LIBT_REVISION:$LIBT_AGE" AC_SUBST(LIBT_VERSION_INFO) diff --git a/fontconfig/fc-cache/Makefile.am b/fontconfig/fc-cache/Makefile.am index 7f7d1b1a0..0e1078629 100644 --- a/fontconfig/fc-cache/Makefile.am +++ b/fontconfig/fc-cache/Makefile.am @@ -36,7 +36,7 @@ uninstall-local: -$(RM) -rf "$(DESTDIR)$(fc_cachedir)" endif -INCLUDES=-I${top_srcdir} -I${top_srcdir}/src $(WARN_CFLAGS) +AM_CPPFLAGS=-I${top_srcdir} -I${top_srcdir}/src $(WARN_CFLAGS) bin_PROGRAMS=fc-cache diff --git a/fontconfig/fc-cat/Makefile.am b/fontconfig/fc-cat/Makefile.am index b426723ba..04c1cc48c 100644 --- a/fontconfig/fc-cat/Makefile.am +++ b/fontconfig/fc-cat/Makefile.am @@ -27,7 +27,7 @@ FC_CAT_SRC=${top_srcdir}/fc-cat SGML = ${FC_CAT_SRC}/fc-cat.sgml -INCLUDES=-I${top_srcdir} $(WARN_CFLAGS) +AM_CPPFLAGS=-I${top_srcdir} $(WARN_CFLAGS) bin_PROGRAMS=fc-cat diff --git a/fontconfig/fc-list/Makefile.am b/fontconfig/fc-list/Makefile.am index b2c499d23..c58540ec6 100644 --- a/fontconfig/fc-list/Makefile.am +++ b/fontconfig/fc-list/Makefile.am @@ -29,7 +29,7 @@ SGML = ${FC_LIST_SRC}/fc-list.sgml bin_PROGRAMS=fc-list -INCLUDES=-I${top_srcdir} $(WARN_CFLAGS) +AM_CPPFLAGS=-I${top_srcdir} $(WARN_CFLAGS) BUILT_MANS=fc-list.1 diff --git a/fontconfig/fc-match/Makefile.am b/fontconfig/fc-match/Makefile.am index 0e9e8fd0e..84afb8b26 100644 --- a/fontconfig/fc-match/Makefile.am +++ b/fontconfig/fc-match/Makefile.am @@ -29,7 +29,7 @@ FC_MATCH_SRC=${top_srcdir}/fc-match SGML = ${FC_MATCH_SRC}/fc-match.sgml -INCLUDES=-I${top_srcdir} $(WARN_CFLAGS) +AM_CPPFLAGS=-I${top_srcdir} $(WARN_CFLAGS) BUILT_MANS=fc-match.1 diff --git a/fontconfig/fc-pattern/Makefile.am b/fontconfig/fc-pattern/Makefile.am index 92b043398..c45624799 100644 --- a/fontconfig/fc-pattern/Makefile.am +++ b/fontconfig/fc-pattern/Makefile.am @@ -29,7 +29,7 @@ FC_PATTERN_SRC=${top_srcdir}/fc-pattern SGML = ${FC_PATTERN_SRC}/fc-pattern.sgml -INCLUDES=-I${top_srcdir} $(WARN_CFLAGS) +AM_CPPFLAGS=-I${top_srcdir} $(WARN_CFLAGS) BUILT_MANS=fc-pattern.1 diff --git a/fontconfig/fc-query/Makefile.am b/fontconfig/fc-query/Makefile.am index b3ea1e61d..73b3f11ee 100644 --- a/fontconfig/fc-query/Makefile.am +++ b/fontconfig/fc-query/Makefile.am @@ -29,7 +29,7 @@ FC_QUERY_SRC=${top_srcdir}/fc-query SGML = ${FC_QUERY_SRC}/fc-query.sgml -INCLUDES=-I${top_srcdir} $(FREETYPE_CFLAGS) $(WARN_CFLAGS) +AM_CPPFLAGS=-I${top_srcdir} $(FREETYPE_CFLAGS) $(WARN_CFLAGS) BUILT_MANS=fc-query.1 diff --git a/fontconfig/fc-scan/Makefile.am b/fontconfig/fc-scan/Makefile.am index 206340506..471a42fb6 100644 --- a/fontconfig/fc-scan/Makefile.am +++ b/fontconfig/fc-scan/Makefile.am @@ -29,7 +29,7 @@ FC_SCAN_SRC=${top_srcdir}/fc-scan SGML = ${FC_SCAN_SRC}/fc-scan.sgml -INCLUDES=-I${top_srcdir} $(FREETYPE_CFLAGS) $(WARN_CFLAGS) +AM_CPPFLAGS=-I${top_srcdir} $(FREETYPE_CFLAGS) $(WARN_CFLAGS) BUILT_MANS=fc-scan.1 diff --git a/fontconfig/fc-validate/Makefile.am b/fontconfig/fc-validate/Makefile.am index 54edec295..782ceadb8 100644 --- a/fontconfig/fc-validate/Makefile.am +++ b/fontconfig/fc-validate/Makefile.am @@ -29,7 +29,7 @@ FC_VALIDATE_SRC=${top_srcdir}/fc-validate SGML = ${FC_VALIDATE_SRC}/fc-validate.sgml -INCLUDES=-I${top_srcdir} $(FREETYPE_CFLAGS) $(WARN_CFLAGS) +AM_CPPFLAGS=-I${top_srcdir} $(FREETYPE_CFLAGS) $(WARN_CFLAGS) BUILT_MANS=fc-validate.1 diff --git a/fontconfig/fontconfig/fontconfig.h b/fontconfig/fontconfig/fontconfig.h index 194996587..361ca4f9e 100644 --- a/fontconfig/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig/fontconfig.h @@ -52,7 +52,7 @@ typedef int FcBool; #define FC_MAJOR 2 #define FC_MINOR 10 -#define FC_REVISION 91 +#define FC_REVISION 92 #define FC_VERSION ((FC_MAJOR * 10000) + (FC_MINOR * 100) + (FC_REVISION)) diff --git a/fontconfig/new-version.sh b/fontconfig/new-version.sh index 39514302e..36e46f593 100644 --- a/fontconfig/new-version.sh +++ b/fontconfig/new-version.sh @@ -21,7 +21,7 @@ eval `echo $version | # Update the version numbers -sed -i configure.ac -e "/^AM_INIT_AUTOMAKE/s/2\.[0-9.]*/$version/" +sed -i configure.ac -e "/^AC_INIT(/s/2\.[0-9.]*/$version/" sed -i fontconfig/fontconfig.h \ -e "/^#define FC_MAJOR/s/[0-9][0-9]*/$major/" \ diff --git a/fontconfig/src/Makefile.am b/fontconfig/src/Makefile.am index 9fd7dd81a..066cc03e7 100644 --- a/fontconfig/src/Makefile.am +++ b/fontconfig/src/Makefile.am @@ -70,7 +70,7 @@ uninstall-ms-import-lib: endif -INCLUDES = \ +AM_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/src \ $(FREETYPE_CFLAGS) \ diff --git a/fontconfig/src/fcmatch.c b/fontconfig/src/fcmatch.c index 68f39aef5..2d7b79840 100644 --- a/fontconfig/src/fcmatch.c +++ b/fontconfig/src/fcmatch.c @@ -227,9 +227,10 @@ typedef enum _FcMatcherPriorityDummy { #undef FC_OBJECT #undef PRI1 -#define PRI1(n) \ - PRI_ ## n ## _STRONG, \ - PRI_ ## n ## _WEAK +#define PRI1(n) \ + PRI_ ## n, \ + PRI_ ## n ## _STRONG = PRI_ ## n, \ + PRI_ ## n ## _WEAK = PRI_ ## n typedef enum _FcMatcherPriority { PRI1(HASH), @@ -237,9 +238,8 @@ typedef enum _FcMatcherPriority { PRI1(FOUNDRY), PRI1(CHARSET), PRI_FAMILY_STRONG, - PRI_LANG_STRONG, PRI_POSTSCRIPT_NAME_STRONG, - PRI_LANG_WEAK, + PRI1(LANG), PRI_FAMILY_WEAK, PRI_POSTSCRIPT_NAME_WEAK, PRI1(SPACING), @@ -910,8 +910,7 @@ FcFontSetSort (FcConfig *config FC_UNUSED, * If this node matches any language, go check * which ones and satisfy those entries */ - if (nodeps[f]->score[PRI_LANG_STRONG] < 2000 || - nodeps[f]->score[PRI_LANG_WEAK] < 2000) + if (nodeps[f]->score[PRI_LANG] < 2000) { for (i = 0; i < nPatternLang; i++) { @@ -935,13 +934,6 @@ FcFontSetSort (FcConfig *config FC_UNUSED, } patternLangSat[i] = FcTrue; satisfies = FcTrue; - /* adjust score to ensure it's not more than 10000.0 - * which would means the lang didn't satisfy the requirements - */ - if (nodeps[f]->score[PRI_LANG_STRONG] > 10000.0) - nodeps[f]->score[PRI_LANG_STRONG] = 10000.0; - if (nodeps[f]->score[PRI_LANG_WEAK] > 10000.0) - nodeps[f]->score[PRI_LANG_WEAK] = 10000.0; break; } } @@ -949,8 +941,7 @@ FcFontSetSort (FcConfig *config FC_UNUSED, } if (!satisfies) { - nodeps[f]->score[PRI_LANG_STRONG] = 10000.0; - nodeps[f]->score[PRI_LANG_WEAK] = 10000.0; + nodeps[f]->score[PRI_LANG] = 10000.0; } } diff --git a/libXau/AuFileName.c b/libXau/AuFileName.c index 473fad110..090427387 100644 --- a/libXau/AuFileName.c +++ b/libXau/AuFileName.c @@ -57,9 +57,8 @@ XauFileName (void) name = getenv ("HOME"); if (!name) { #ifdef WIN32 - (void) strcpy (dir, "/users/"); if ((name = getenv("USERNAME"))) { - (void) strcat (dir, name); + snprintf(dir, sizeof(dir), "/users/%s", name); name = dir; } if (!name) @@ -81,7 +80,7 @@ XauFileName (void) bsize = size; } - strcpy (buf, name); - strcat (buf, slashDotXauthority + (name[1] == '\0' ? 1 : 0)); + snprintf (buf, bsize, "%s%s", name, + slashDotXauthority + (name[1] == '\0' ? 1 : 0)); return buf; } diff --git a/libXau/AuGetAddr.c b/libXau/AuGetAddr.c index 897d8b565..6f5fe16e4 100644 --- a/libXau/AuGetAddr.c +++ b/libXau/AuGetAddr.c @@ -30,14 +30,7 @@ in this Software without prior written authorization from The Open Group. #include #include -static int -binaryEqual (_Xconst char *a, _Xconst char *b, int len) -{ - while (len--) - if (*a++ != *b++) - return 0; - return 1; -} +#define binaryEqual(a, b, len) (memcmp(a, b, len) == 0) Xauth * XauGetAuthByAddr ( @@ -94,13 +87,13 @@ _Xconst char* name) if ((family == FamilyWild || entry->family == FamilyWild || (entry->family == family && address_length == entry->address_length && - binaryEqual (entry->address, address, (int)address_length))) && + binaryEqual (entry->address, address, address_length))) && (number_length == 0 || entry->number_length == 0 || (number_length == entry->number_length && - binaryEqual (entry->number, number, (int)number_length))) && + binaryEqual (entry->number, number, number_length))) && (name_length == 0 || entry->name_length == 0 || (entry->name_length == name_length && - binaryEqual (entry->name, name, (int)name_length)))) + binaryEqual (entry->name, name, name_length)))) break; XauDisposeAuth (entry); } diff --git a/libXau/AuGetBest.c b/libXau/AuGetBest.c index 673ee406a..5556559ca 100644 --- a/libXau/AuGetBest.c +++ b/libXau/AuGetBest.c @@ -38,14 +38,7 @@ in this Software without prior written authorization from The Open Group. #include #endif -static int -binaryEqual (_Xconst char *a, _Xconst char *b, int len) -{ - while (len--) - if (*a++ != *b++) - return 0; - return 1; -} +#define binaryEqual(a, b, len) (memcmp(a, b, len) == 0) Xauth * XauGetBestAuthByAddr ( @@ -129,17 +122,17 @@ XauGetBestAuthByAddr ( if ((family == FamilyWild || entry->family == FamilyWild || (entry->family == family && ((address_length == entry->address_length && - binaryEqual (entry->address, address, (int)address_length)) + binaryEqual (entry->address, address, address_length)) #ifdef hpux || (family == FamilyLocal && fully_qual_address_length == entry->address_length && binaryEqual (entry->address, fully_qual_address, - (int) fully_qual_address_length)) + fully_qual_address_length)) #endif ))) && (number_length == 0 || entry->number_length == 0 || (number_length == entry->number_length && - binaryEqual (entry->number, number, (int)number_length)))) + binaryEqual (entry->number, number, number_length)))) { if (best_type == 0) { diff --git a/libXau/AuLock.c b/libXau/AuLock.c index 7bf9e5d30..5dfc1747e 100644 --- a/libXau/AuLock.c +++ b/libXau/AuLock.c @@ -33,15 +33,12 @@ in this Software without prior written authorization from The Open Group. #include #include #define Time_t time_t -#ifndef X_NOT_POSIX -#include -#else -#ifndef WIN32 -extern unsigned sleep (); -#else -#include -#define link rename +#ifdef HAVE_UNISTD_H +# include #endif +#ifdef WIN32 +# include +# define link rename #endif int @@ -58,10 +55,8 @@ long dead) if (strlen (file_name) > 1022) return LOCK_ERROR; - (void) strcpy (creat_name, file_name); - (void) strcat (creat_name, "-c"); - (void) strcpy (link_name, file_name); - (void) strcat (link_name, "-l"); + snprintf (creat_name, sizeof(creat_name), "%s-c", file_name); + snprintf (link_name, sizeof(link_name), "%s-l", file_name); if (stat (creat_name, &statb) != -1) { now = time ((Time_t *) 0); /* @@ -69,8 +64,8 @@ long dead) * case a 0 deadtime to force lock removal */ if (dead == 0 || now - statb.st_ctime > dead) { - (void) unlink (creat_name); - (void) unlink (link_name); + (void) remove (creat_name); + (void) remove (link_name); } } @@ -84,7 +79,7 @@ long dead) (void) close (creat_fd); } if (creat_fd != -1) { -#ifndef X_NOT_POSIX +#ifdef HAVE_PATHCONF /* The file system may not support hard links, and pathconf should tell us that. */ if (1 == pathconf(creat_name, _PC_LINK_MAX)) { if (-1 == rename(creat_name, link_name)) { @@ -93,8 +88,9 @@ long dead) } else { return LOCK_SUCCESS; } - } else { + } else #endif + { if (link (creat_name, link_name) != -1) return LOCK_SUCCESS; if (errno == ENOENT) { @@ -103,9 +99,7 @@ long dead) } if (errno != EEXIST) return LOCK_ERROR; -#ifndef X_NOT_POSIX } -#endif } (void) sleep ((unsigned) timeout); --retries; diff --git a/libXau/AuUnlock.c b/libXau/AuUnlock.c index ddbe7db9e..b81724600 100644 --- a/libXau/AuUnlock.c +++ b/libXau/AuUnlock.c @@ -42,18 +42,16 @@ _Xconst char *file_name) if (strlen (file_name) > 1022) return 0; #ifndef WIN32 - (void) strcpy (creat_name, file_name); - (void) strcat (creat_name, "-c"); + snprintf (creat_name, sizeof(creat_name), "%s-c", file_name); #endif - (void) strcpy (link_name, file_name); - (void) strcat (link_name, "-l"); + snprintf (link_name, sizeof(link_name), "%s-l", file_name); /* * I think this is the correct order */ #ifndef WIN32 - (void) unlink (creat_name); + (void) remove (creat_name); #endif - (void) unlink (link_name); + (void) remove (link_name); return 1; } diff --git a/libXau/configure.ac b/libXau/configure.ac index 62a4717f5..e55cfceb6 100644 --- a/libXau/configure.ac +++ b/libXau/configure.ac @@ -26,6 +26,7 @@ AC_INIT([libXau], [1.0.7], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXau]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([config.h]) +AC_USE_SYSTEM_EXTENSIONS # Initialize Automake AM_INIT_AUTOMAKE([foreign dist-bzip2]) @@ -43,6 +44,9 @@ XORG_DEFAULT_OPTIONS # Checks for programs. AC_PROG_LN_S +# Checks for library functions. +AC_CHECK_FUNCS([pathconf]) + # Obtain compiler/linker options for depedencies PKG_CHECK_MODULES(XAU, xproto) diff --git a/mesalib/docs/GL3.txt b/mesalib/docs/GL3.txt index 640dec24c..d150b0874 100644 --- a/mesalib/docs/GL3.txt +++ b/mesalib/docs/GL3.txt @@ -87,7 +87,7 @@ GL_ARB_vertex_type_2_10_10_10_rev DONE (i965, r600) GL 4.0: GLSL 4.0 not started -GL_ARB_texture_query_lod not started +GL_ARB_texture_query_lod DONE (i965) GL_ARB_draw_buffers_blend DONE (i965, r600, softpipe) GL_ARB_draw_indirect not started GL_ARB_gpu_shader5 not started @@ -151,7 +151,7 @@ ARB_shader_storage_buffer_object not started ARB_stencil_texturing not started ARB_texture_buffer_range DONE (nv50, nvc0) ARB_texture_query_levels not started -ARB_texture_storage_multisample not started +ARB_texture_storage_multisample DONE (i965) ARB_texture_view not started ARB_vertex_attrib_binding not started diff --git a/mesalib/docs/application-issues.html b/mesalib/docs/application-issues.html new file mode 100644 index 000000000..6db086585 --- /dev/null +++ b/mesalib/docs/application-issues.html @@ -0,0 +1,83 @@ + + + + + Application Issues + + + + +
+

The Mesa 3D Graphics Library

+
+ + +
+ +

Application Issues

+ +

+This page documents known issues with some OpenGL applications. +

+ + +

Topogun

+ +

+Topogun for Linux (version 2, at least) +creates a GLX visual without requesting a depth buffer. +This causes bad rendering if the OpenGL driver happens to choose a visual +without a depth buffer. +

+ +

+Mesa 9.1.2 and later (will) support a DRI configuration option to work around +this issue. +Using the driconf tool, +set the "Create all visuals with a depth buffer" option before running Topogun. +Then, all GLX visuals will be created with a depth buffer. +

+ + +

Old OpenGL games

+ +

+Some old OpenGL games (approx. ten years or older) may crash during +start-up because of an extension string buffer-overflow problem. +

+ +

+The problem is a modern OpenGL driver will return a very long string +for the glGetString(GL_EXTENSIONS) query and if the application +naively copies the string into a fixed-size buffer it can overflow the +buffer and crash the application. +

+ +

+The work-around is to set the MESA_EXTENSION_MAX_YEAR environment variable +to the approximate release year of the game. +This will cause the glGetString(GL_EXTENSIONS) query to only report extensions +older than the given year. +

+ +

+For example, if the game was released in 2001, do +

+export MESA_EXTENSION_MAX_YEAR=2001
+
+before running the game. +

+ + + +

Viewperf

+ +

+See the Viewperf issues page for a detailed list +of Viewperf issues. +

+ + +
+ + diff --git a/mesalib/docs/contents.html b/mesalib/docs/contents.html index 57522992c..50c0d5913 100644 --- a/mesalib/docs/contents.html +++ b/mesalib/docs/contents.html @@ -71,6 +71,7 @@
  • Gallium llvmpipe driver
  • VMware SVGA3D guest driver
  • Gallium post-processing +
  • Application Issues
  • Viewperf Issues diff --git a/mesalib/src/gallium/auxiliary/Makefile.sources b/mesalib/src/gallium/auxiliary/Makefile.sources index 898abe024..79def2177 100644 --- a/mesalib/src/gallium/auxiliary/Makefile.sources +++ b/mesalib/src/gallium/auxiliary/Makefile.sources @@ -37,6 +37,11 @@ C_SOURCES := \ draw/draw_vs.c \ draw/draw_vs_exec.c \ draw/draw_vs_variant.c \ + hud/font.c \ + hud/hud_context.c \ + hud/hud_cpu.c \ + hud/hud_fps.c \ + hud/hud_driver_query.c \ os/os_misc.c \ os/os_time.c \ pipebuffer/pb_buffer_fenced.c \ diff --git a/mesalib/src/gallium/auxiliary/hud/font.c b/mesalib/src/gallium/auxiliary/hud/font.c new file mode 100644 index 000000000..6747874ee --- /dev/null +++ b/mesalib/src/gallium/auxiliary/hud/font.c @@ -0,0 +1,446 @@ +/************************************************************************** + * + * Copyright 2013 Marek Olšák + * 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 THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* This is the "8_BY_13" font extracted from freeglut. */ + +/* + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 16 1999 + * + * 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 + * PAWEL W. OLSZTA 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 "hud/font.h" + +#include "pipe/p_compiler.h" +#include "pipe/p_screen.h" +#include "pipe/p_state.h" +#include "pipe/p_context.h" +#include "util/u_inlines.h" + +typedef unsigned char GLubyte; /* 1-byte unsigned */ +typedef struct tagSFG_Font SFG_Font; + +struct tagSFG_Font +{ + char* Name; /* The source font name */ + int Quantity; /* Number of chars in font */ + int Height; /* Height of the characters */ + const GLubyte** Characters; /* The characters mapping */ + + float xorig, yorig; /* Relative origin of the character */ +}; + +static const GLubyte Fixed8x13_Character_000[] = { 8, 0, 0, 0,170, 0,130, 0,130, 0,130, 0,170, 0, 0}; +static const GLubyte Fixed8x13_Character_001[] = { 8, 0, 0, 0, 0, 16, 56,124,254,124, 56, 16, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_002[] = { 8, 0,170, 85,170, 85,170, 85,170, 85,170, 85,170, 85,170}; +static const GLubyte Fixed8x13_Character_003[] = { 8, 0, 0, 0, 4, 4, 4, 4,174,160,224,160,160, 0, 0}; +static const GLubyte Fixed8x13_Character_004[] = { 8, 0, 0, 0, 8, 8, 12, 8,142,128,192,128,224, 0, 0}; +static const GLubyte Fixed8x13_Character_005[] = { 8, 0, 0, 0, 10, 10, 12, 10,108,128,128,128, 96, 0, 0}; +static const GLubyte Fixed8x13_Character_006[] = { 8, 0, 0, 0, 8, 8, 12, 8,238,128,128,128,128, 0, 0}; +static const GLubyte Fixed8x13_Character_007[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 24, 36, 36, 24, 0, 0}; +static const GLubyte Fixed8x13_Character_008[] = { 8, 0, 0, 0, 0,124, 0, 16, 16,124, 16, 16, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_009[] = { 8, 0, 0, 0, 14, 8, 8, 8,168,160,160,160,192, 0, 0}; +static const GLubyte Fixed8x13_Character_010[] = { 8, 0, 0, 0, 4, 4, 4, 4, 46, 80, 80,136,136, 0, 0}; +static const GLubyte Fixed8x13_Character_011[] = { 8, 0, 0, 0, 0, 0, 0, 0,240, 16, 16, 16, 16, 16, 16}; +static const GLubyte Fixed8x13_Character_012[] = { 8, 0, 16, 16, 16, 16, 16, 16,240, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_013[] = { 8, 0, 16, 16, 16, 16, 16, 16, 31, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_014[] = { 8, 0, 0, 0, 0, 0, 0, 0, 31, 16, 16, 16, 16, 16, 16}; +static const GLubyte Fixed8x13_Character_015[] = { 8, 0, 16, 16, 16, 16, 16, 16,255, 16, 16, 16, 16, 16, 16}; +static const GLubyte Fixed8x13_Character_016[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255}; +static const GLubyte Fixed8x13_Character_017[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_018[] = { 8, 0, 0, 0, 0, 0, 0, 0,255, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_019[] = { 8, 0, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_020[] = { 8, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_021[] = { 8, 0, 16, 16, 16, 16, 16, 16, 31, 16, 16, 16, 16, 16, 16}; +static const GLubyte Fixed8x13_Character_022[] = { 8, 0, 16, 16, 16, 16, 16, 16,240, 16, 16, 16, 16, 16, 16}; +static const GLubyte Fixed8x13_Character_023[] = { 8, 0, 0, 0, 0, 0, 0, 0,255, 16, 16, 16, 16, 16, 16}; +static const GLubyte Fixed8x13_Character_024[] = { 8, 0, 16, 16, 16, 16, 16, 16,255, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_025[] = { 8, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; +static const GLubyte Fixed8x13_Character_026[] = { 8, 0, 0, 0,254, 0, 14, 48,192, 48, 14, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_027[] = { 8, 0, 0, 0,254, 0,224, 24, 6, 24,224, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_028[] = { 8, 0, 0, 0, 68, 68, 68, 68, 68,254, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_029[] = { 8, 0, 0, 0, 32, 32,126, 16, 8,126, 4, 4, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_030[] = { 8, 0, 0, 0,220, 98, 32, 32, 32,112, 32, 34, 28, 0, 0}; +static const GLubyte Fixed8x13_Character_031[] = { 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_032[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_033[] = { 8, 0, 0, 0, 16, 0, 16, 16, 16, 16, 16, 16, 16, 0, 0}; +static const GLubyte Fixed8x13_Character_034[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 36, 36, 0, 0}; +static const GLubyte Fixed8x13_Character_035[] = { 8, 0, 0, 0, 0, 36, 36,126, 36,126, 36, 36, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_036[] = { 8, 0, 0, 0, 16,120, 20, 20, 56, 80, 80, 60, 16, 0, 0}; +static const GLubyte Fixed8x13_Character_037[] = { 8, 0, 0, 0, 68, 42, 36, 16, 8, 8, 36, 82, 34, 0, 0}; +static const GLubyte Fixed8x13_Character_038[] = { 8, 0, 0, 0, 58, 68, 74, 48, 72, 72, 48, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_039[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 48, 56, 0, 0}; +static const GLubyte Fixed8x13_Character_040[] = { 8, 0, 0, 0, 4, 8, 8, 16, 16, 16, 8, 8, 4, 0, 0}; +static const GLubyte Fixed8x13_Character_041[] = { 8, 0, 0, 0, 32, 16, 16, 8, 8, 8, 16, 16, 32, 0, 0}; +static const GLubyte Fixed8x13_Character_042[] = { 8, 0, 0, 0, 0, 0, 36, 24,126, 24, 36, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_043[] = { 8, 0, 0, 0, 0, 0, 16, 16,124, 16, 16, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_044[] = { 8, 0, 0, 64, 48, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_045[] = { 8, 0, 0, 0, 0, 0, 0, 0,126, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_046[] = { 8, 0, 0, 16, 56, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_047[] = { 8, 0, 0, 0,128,128, 64, 32, 16, 8, 4, 2, 2, 0, 0}; +static const GLubyte Fixed8x13_Character_048[] = { 8, 0, 0, 0, 24, 36, 66, 66, 66, 66, 66, 36, 24, 0, 0}; +static const GLubyte Fixed8x13_Character_049[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16, 80, 48, 16, 0, 0}; +static const GLubyte Fixed8x13_Character_050[] = { 8, 0, 0, 0,126, 64, 32, 24, 4, 2, 66, 66, 60, 0, 0}; +static const GLubyte Fixed8x13_Character_051[] = { 8, 0, 0, 0, 60, 66, 2, 2, 28, 8, 4, 2,126, 0, 0}; +static const GLubyte Fixed8x13_Character_052[] = { 8, 0, 0, 0, 4, 4,126, 68, 68, 36, 20, 12, 4, 0, 0}; +static const GLubyte Fixed8x13_Character_053[] = { 8, 0, 0, 0, 60, 66, 2, 2, 98, 92, 64, 64,126, 0, 0}; +static const GLubyte Fixed8x13_Character_054[] = { 8, 0, 0, 0, 60, 66, 66, 98, 92, 64, 64, 32, 28, 0, 0}; +static const GLubyte Fixed8x13_Character_055[] = { 8, 0, 0, 0, 32, 32, 16, 16, 8, 8, 4, 2,126, 0, 0}; +static const GLubyte Fixed8x13_Character_056[] = { 8, 0, 0, 0, 60, 66, 66, 66, 60, 66, 66, 66, 60, 0, 0}; +static const GLubyte Fixed8x13_Character_057[] = { 8, 0, 0, 0, 56, 4, 2, 2, 58, 70, 66, 66, 60, 0, 0}; +static const GLubyte Fixed8x13_Character_058[] = { 8, 0, 0, 16, 56, 16, 0, 0, 16, 56, 16, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_059[] = { 8, 0, 0, 64, 48, 56, 0, 0, 16, 56, 16, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_060[] = { 8, 0, 0, 0, 2, 4, 8, 16, 32, 16, 8, 4, 2, 0, 0}; +static const GLubyte Fixed8x13_Character_061[] = { 8, 0, 0, 0, 0, 0,126, 0, 0,126, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_062[] = { 8, 0, 0, 0, 64, 32, 16, 8, 4, 8, 16, 32, 64, 0, 0}; +static const GLubyte Fixed8x13_Character_063[] = { 8, 0, 0, 0, 8, 0, 8, 8, 4, 2, 66, 66, 60, 0, 0}; +static const GLubyte Fixed8x13_Character_064[] = { 8, 0, 0, 0, 60, 64, 74, 86, 82, 78, 66, 66, 60, 0, 0}; +static const GLubyte Fixed8x13_Character_065[] = { 8, 0, 0, 0, 66, 66, 66,126, 66, 66, 66, 36, 24, 0, 0}; +static const GLubyte Fixed8x13_Character_066[] = { 8, 0, 0, 0,252, 66, 66, 66,124, 66, 66, 66,252, 0, 0}; +static const GLubyte Fixed8x13_Character_067[] = { 8, 0, 0, 0, 60, 66, 64, 64, 64, 64, 64, 66, 60, 0, 0}; +static const GLubyte Fixed8x13_Character_068[] = { 8, 0, 0, 0,252, 66, 66, 66, 66, 66, 66, 66,252, 0, 0}; +static const GLubyte Fixed8x13_Character_069[] = { 8, 0, 0, 0,126, 64, 64, 64,120, 64, 64, 64,126, 0, 0}; +static const GLubyte Fixed8x13_Character_070[] = { 8, 0, 0, 0, 64, 64, 64, 64,120, 64, 64, 64,126, 0, 0}; +static const GLubyte Fixed8x13_Character_071[] = { 8, 0, 0, 0, 58, 70, 66, 78, 64, 64, 64, 66, 60, 0, 0}; +static const GLubyte Fixed8x13_Character_072[] = { 8, 0, 0, 0, 66, 66, 66, 66,126, 66, 66, 66, 66, 0, 0}; +static const GLubyte Fixed8x13_Character_073[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16, 16, 16,124, 0, 0}; +static const GLubyte Fixed8x13_Character_074[] = { 8, 0, 0, 0, 56, 68, 4, 4, 4, 4, 4, 4, 31, 0, 0}; +static const GLubyte Fixed8x13_Character_075[] = { 8, 0, 0, 0, 66, 68, 72, 80, 96, 80, 72, 68, 66, 0, 0}; +static const GLubyte Fixed8x13_Character_076[] = { 8, 0, 0, 0,126, 64, 64, 64, 64, 64, 64, 64, 64, 0, 0}; +static const GLubyte Fixed8x13_Character_077[] = { 8, 0, 0, 0,130,130,130,146,146,170,198,130,130, 0, 0}; +static const GLubyte Fixed8x13_Character_078[] = { 8, 0, 0, 0, 66, 66, 66, 70, 74, 82, 98, 66, 66, 0, 0}; +static const GLubyte Fixed8x13_Character_079[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0}; +static const GLubyte Fixed8x13_Character_080[] = { 8, 0, 0, 0, 64, 64, 64, 64,124, 66, 66, 66,124, 0, 0}; +static const GLubyte Fixed8x13_Character_081[] = { 8, 0, 0, 2, 60, 74, 82, 66, 66, 66, 66, 66, 60, 0, 0}; +static const GLubyte Fixed8x13_Character_082[] = { 8, 0, 0, 0, 66, 68, 72, 80,124, 66, 66, 66,124, 0, 0}; +static const GLubyte Fixed8x13_Character_083[] = { 8, 0, 0, 0, 60, 66, 2, 2, 60, 64, 64, 66, 60, 0, 0}; +static const GLubyte Fixed8x13_Character_084[] = { 8, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16,254, 0, 0}; +static const GLubyte Fixed8x13_Character_085[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 66, 0, 0}; +static const GLubyte Fixed8x13_Character_086[] = { 8, 0, 0, 0, 16, 40, 40, 40, 68, 68, 68,130,130, 0, 0}; +static const GLubyte Fixed8x13_Character_087[] = { 8, 0, 0, 0, 68,170,146,146,146,130,130,130,130, 0, 0}; +static const GLubyte Fixed8x13_Character_088[] = { 8, 0, 0, 0,130,130, 68, 40, 16, 40, 68,130,130, 0, 0}; +static const GLubyte Fixed8x13_Character_089[] = { 8, 0, 0, 0, 16, 16, 16, 16, 16, 40, 68,130,130, 0, 0}; +static const GLubyte Fixed8x13_Character_090[] = { 8, 0, 0, 0,126, 64, 64, 32, 16, 8, 4, 2,126, 0, 0}; +static const GLubyte Fixed8x13_Character_091[] = { 8, 0, 0, 0, 60, 32, 32, 32, 32, 32, 32, 32, 60, 0, 0}; +static const GLubyte Fixed8x13_Character_092[] = { 8, 0, 0, 0, 2, 2, 4, 8, 16, 32, 64,128,128, 0, 0}; +static const GLubyte Fixed8x13_Character_093[] = { 8, 0, 0, 0,120, 8, 8, 8, 8, 8, 8, 8,120, 0, 0}; +static const GLubyte Fixed8x13_Character_094[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 40, 16, 0, 0}; +static const GLubyte Fixed8x13_Character_095[] = { 8, 0, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_096[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 56, 0, 0}; +static const GLubyte Fixed8x13_Character_097[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_098[] = { 8, 0, 0, 0, 92, 98, 66, 66, 98, 92, 64, 64, 64, 0, 0}; +static const GLubyte Fixed8x13_Character_099[] = { 8, 0, 0, 0, 60, 66, 64, 64, 66, 60, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_100[] = { 8, 0, 0, 0, 58, 70, 66, 66, 70, 58, 2, 2, 2, 0, 0}; +static const GLubyte Fixed8x13_Character_101[] = { 8, 0, 0, 0, 60, 66, 64,126, 66, 60, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_102[] = { 8, 0, 0, 0, 32, 32, 32, 32,124, 32, 32, 34, 28, 0, 0}; +static const GLubyte Fixed8x13_Character_103[] = { 8, 0, 60, 66, 60, 64, 56, 68, 68, 58, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_104[] = { 8, 0, 0, 0, 66, 66, 66, 66, 98, 92, 64, 64, 64, 0, 0}; +static const GLubyte Fixed8x13_Character_105[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 48, 0, 16, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_106[] = { 8, 0, 56, 68, 68, 4, 4, 4, 4, 12, 0, 4, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_107[] = { 8, 0, 0, 0, 66, 68, 72,112, 72, 68, 64, 64, 64, 0, 0}; +static const GLubyte Fixed8x13_Character_108[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16, 16, 16, 48, 0, 0}; +static const GLubyte Fixed8x13_Character_109[] = { 8, 0, 0, 0,130,146,146,146,146,236, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_110[] = { 8, 0, 0, 0, 66, 66, 66, 66, 98, 92, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_111[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_112[] = { 8, 0, 64, 64, 64, 92, 98, 66, 98, 92, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_113[] = { 8, 0, 2, 2, 2, 58, 70, 66, 70, 58, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_114[] = { 8, 0, 0, 0, 32, 32, 32, 32, 34, 92, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_115[] = { 8, 0, 0, 0, 60, 66, 12, 48, 66, 60, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_116[] = { 8, 0, 0, 0, 28, 34, 32, 32, 32,124, 32, 32, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_117[] = { 8, 0, 0, 0, 58, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_118[] = { 8, 0, 0, 0, 16, 40, 40, 68, 68, 68, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_119[] = { 8, 0, 0, 0, 68,170,146,146,130,130, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_120[] = { 8, 0, 0, 0, 66, 36, 24, 24, 36, 66, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_121[] = { 8, 0, 60, 66, 2, 58, 70, 66, 66, 66, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_122[] = { 8, 0, 0, 0,126, 32, 16, 8, 4,126, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_123[] = { 8, 0, 0, 0, 14, 16, 16, 8, 48, 8, 16, 16, 14, 0, 0}; +static const GLubyte Fixed8x13_Character_124[] = { 8, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0}; +static const GLubyte Fixed8x13_Character_125[] = { 8, 0, 0, 0,112, 8, 8, 16, 12, 16, 8, 8,112, 0, 0}; +static const GLubyte Fixed8x13_Character_126[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 84, 36, 0, 0}; +static const GLubyte Fixed8x13_Character_127[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_128[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_129[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_130[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_131[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_132[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_133[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_134[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_135[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_136[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_137[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_138[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_139[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_140[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_141[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_142[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_143[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_144[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_145[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_146[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_147[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_148[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_149[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_150[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_151[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_152[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_153[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_154[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_155[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_156[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_157[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_158[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_159[] = { 9, 0, 0, 0, 0, 0, 0,170, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,130, 0, 0, 0,170, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_160[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_161[] = { 8, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 0, 16, 0, 0}; +static const GLubyte Fixed8x13_Character_162[] = { 8, 0, 0, 0, 0, 16, 56, 84, 80, 80, 84, 56, 16, 0, 0}; +static const GLubyte Fixed8x13_Character_163[] = { 8, 0, 0, 0,220, 98, 32, 32, 32,112, 32, 34, 28, 0, 0}; +static const GLubyte Fixed8x13_Character_164[] = { 8, 0, 0, 0, 0, 66, 60, 36, 36, 60, 66, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_165[] = { 8, 0, 0, 0, 16, 16,124, 16,124, 40, 68,130,130, 0, 0}; +static const GLubyte Fixed8x13_Character_166[] = { 8, 0, 0, 0, 16, 16, 16, 16, 0, 16, 16, 16, 16, 0, 0}; +static const GLubyte Fixed8x13_Character_167[] = { 8, 0, 0, 0, 24, 36, 4, 24, 36, 36, 24, 32, 36, 24, 0}; +static const GLubyte Fixed8x13_Character_168[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,108, 0, 0}; +static const GLubyte Fixed8x13_Character_169[] = { 8, 0, 0, 0, 0, 56, 68,146,170,162,170,146, 68, 56, 0}; +static const GLubyte Fixed8x13_Character_170[] = { 8, 0, 0, 0, 0, 0,124, 0, 60, 68, 60, 4, 56, 0, 0}; +static const GLubyte Fixed8x13_Character_171[] = { 8, 0, 0, 0, 0, 18, 36, 72,144, 72, 36, 18, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_172[] = { 8, 0, 0, 0, 0, 2, 2, 2,126, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_173[] = { 8, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_174[] = { 8, 0, 0, 0, 0, 56, 68,170,178,170,170,146, 68, 56, 0}; +static const GLubyte Fixed8x13_Character_175[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 0, 0}; +static const GLubyte Fixed8x13_Character_176[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 24, 36, 36, 24, 0, 0}; +static const GLubyte Fixed8x13_Character_177[] = { 8, 0, 0, 0, 0,124, 0, 16, 16,124, 16, 16, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_178[] = { 8, 0, 0, 0, 0, 0, 0, 0,120, 64, 48, 8, 72, 48, 0}; +static const GLubyte Fixed8x13_Character_179[] = { 8, 0, 0, 0, 0, 0, 0, 0, 48, 72, 8, 16, 72, 48, 0}; +static const GLubyte Fixed8x13_Character_180[] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 8, 0}; +static const GLubyte Fixed8x13_Character_181[] = { 8, 0, 0, 64, 90,102, 66, 66, 66, 66, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_182[] = { 8, 0, 0, 0, 20, 20, 20, 20, 52,116,116,116, 62, 0, 0}; +static const GLubyte Fixed8x13_Character_183[] = { 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_184[] = { 8, 0, 24, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_185[] = { 8, 0, 0, 0, 0, 0, 0, 0,112, 32, 32, 32, 96, 32, 0}; +static const GLubyte Fixed8x13_Character_186[] = { 8, 0, 0, 0, 0, 0, 0,120, 0, 48, 72, 72, 48, 0, 0}; +static const GLubyte Fixed8x13_Character_187[] = { 8, 0, 0, 0, 0,144, 72, 36, 18, 36, 72,144, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_188[] = { 8, 0, 0, 0, 6, 26, 18, 10,230, 66, 64, 64,192, 64, 0}; +static const GLubyte Fixed8x13_Character_189[] = { 8, 0, 0, 0, 30, 16, 12, 2,242, 76, 64, 64,192, 64, 0}; +static const GLubyte Fixed8x13_Character_190[] = { 8, 0, 0, 0, 6, 26, 18, 10,102,146, 16, 32,144, 96, 0}; +static const GLubyte Fixed8x13_Character_191[] = { 8, 0, 0, 0, 60, 66, 66, 64, 32, 16, 16, 0, 16, 0, 0}; +static const GLubyte Fixed8x13_Character_192[] = { 8, 0, 0, 0, 66, 66,126, 66, 66, 36, 24, 0, 8, 16, 0}; +static const GLubyte Fixed8x13_Character_193[] = { 8, 0, 0, 0, 66, 66,126, 66, 66, 36, 24, 0, 16, 8, 0}; +static const GLubyte Fixed8x13_Character_194[] = { 8, 0, 0, 0, 66, 66,126, 66, 66, 36, 24, 0, 36, 24, 0}; +static const GLubyte Fixed8x13_Character_195[] = { 8, 0, 0, 0, 66, 66,126, 66, 66, 36, 24, 0, 76, 50, 0}; +static const GLubyte Fixed8x13_Character_196[] = { 8, 0, 0, 0, 66, 66,126, 66, 66, 36, 24, 0, 36, 36, 0}; +static const GLubyte Fixed8x13_Character_197[] = { 8, 0, 0, 0, 66, 66,126, 66, 66, 36, 24, 24, 36, 24, 0}; +static const GLubyte Fixed8x13_Character_198[] = { 8, 0, 0, 0,158,144,144,240,156,144,144,144,110, 0, 0}; +static const GLubyte Fixed8x13_Character_199[] = { 8, 0, 16, 8, 60, 66, 64, 64, 64, 64, 64, 66, 60, 0, 0}; +static const GLubyte Fixed8x13_Character_200[] = { 8, 0, 0, 0,126, 64, 64,120, 64, 64,126, 0, 8, 16, 0}; +static const GLubyte Fixed8x13_Character_201[] = { 8, 0, 0, 0,126, 64, 64,120, 64, 64,126, 0, 16, 8, 0}; +static const GLubyte Fixed8x13_Character_202[] = { 8, 0, 0, 0,126, 64, 64,120, 64, 64,126, 0, 36, 24, 0}; +static const GLubyte Fixed8x13_Character_203[] = { 8, 0, 0, 0,126, 64, 64,120, 64, 64,126, 0, 36, 36, 0}; +static const GLubyte Fixed8x13_Character_204[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16,124, 0, 16, 32, 0}; +static const GLubyte Fixed8x13_Character_205[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16,124, 0, 16, 8, 0}; +static const GLubyte Fixed8x13_Character_206[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16,124, 0, 36, 24, 0}; +static const GLubyte Fixed8x13_Character_207[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 16,124, 0, 40, 40, 0}; +static const GLubyte Fixed8x13_Character_208[] = { 8, 0, 0, 0,120, 68, 66, 66,226, 66, 66, 68,120, 0, 0}; +static const GLubyte Fixed8x13_Character_209[] = { 8, 0, 0, 0,130,134,138,146,162,194,130, 0,152,100, 0}; +static const GLubyte Fixed8x13_Character_210[] = { 8, 0, 0, 0,124,130,130,130,130,130,124, 0, 16, 32, 0}; +static const GLubyte Fixed8x13_Character_211[] = { 8, 0, 0, 0,124,130,130,130,130,130,124, 0, 16, 8, 0}; +static const GLubyte Fixed8x13_Character_212[] = { 8, 0, 0, 0,124,130,130,130,130,130,124, 0, 36, 24, 0}; +static const GLubyte Fixed8x13_Character_213[] = { 8, 0, 0, 0,124,130,130,130,130,130,124, 0,152,100, 0}; +static const GLubyte Fixed8x13_Character_214[] = { 8, 0, 0, 0,124,130,130,130,130,130,124, 0, 40, 40, 0}; +static const GLubyte Fixed8x13_Character_215[] = { 8, 0, 0, 0, 0, 66, 36, 24, 24, 36, 66, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_216[] = { 8, 0, 0, 64, 60, 98, 82, 82, 82, 74, 74, 70, 60, 2, 0}; +static const GLubyte Fixed8x13_Character_217[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 0, 8, 16, 0}; +static const GLubyte Fixed8x13_Character_218[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 0, 16, 8, 0}; +static const GLubyte Fixed8x13_Character_219[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 0, 36, 24, 0}; +static const GLubyte Fixed8x13_Character_220[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 66, 66, 0, 36, 36, 0}; +static const GLubyte Fixed8x13_Character_221[] = { 8, 0, 0, 0, 16, 16, 16, 16, 40, 68, 68, 0, 16, 8, 0}; +static const GLubyte Fixed8x13_Character_222[] = { 8, 0, 0, 0, 64, 64, 64,124, 66, 66, 66,124, 64, 0, 0}; +static const GLubyte Fixed8x13_Character_223[] = { 8, 0, 0, 0, 92, 66, 66, 76, 80, 72, 68, 68, 56, 0, 0}; +static const GLubyte Fixed8x13_Character_224[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 0, 8, 16, 0}; +static const GLubyte Fixed8x13_Character_225[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 0, 8, 4, 0}; +static const GLubyte Fixed8x13_Character_226[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 0, 36, 24, 0}; +static const GLubyte Fixed8x13_Character_227[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 0, 76, 50, 0}; +static const GLubyte Fixed8x13_Character_228[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 0, 36, 36, 0}; +static const GLubyte Fixed8x13_Character_229[] = { 8, 0, 0, 0, 58, 70, 66, 62, 2, 60, 0, 24, 36, 24, 0}; +static const GLubyte Fixed8x13_Character_230[] = { 8, 0, 0, 0,108,146,144,124, 18,108, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_231[] = { 8, 0, 16, 8, 60, 66, 64, 64, 66, 60, 0, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_232[] = { 8, 0, 0, 0, 60, 66, 64,126, 66, 60, 0, 0, 8, 16, 0}; +static const GLubyte Fixed8x13_Character_233[] = { 8, 0, 0, 0, 60, 66, 64,126, 66, 60, 0, 0, 16, 8, 0}; +static const GLubyte Fixed8x13_Character_234[] = { 8, 0, 0, 0, 60, 66, 64,126, 66, 60, 0, 0, 36, 24, 0}; +static const GLubyte Fixed8x13_Character_235[] = { 8, 0, 0, 0, 60, 66, 64,126, 66, 60, 0, 0, 36, 36, 0}; +static const GLubyte Fixed8x13_Character_236[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 48, 0, 0, 16, 32, 0}; +static const GLubyte Fixed8x13_Character_237[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 48, 0, 0, 32, 16, 0}; +static const GLubyte Fixed8x13_Character_238[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 48, 0, 0, 72, 48, 0}; +static const GLubyte Fixed8x13_Character_239[] = { 8, 0, 0, 0,124, 16, 16, 16, 16, 48, 0, 0, 40, 40, 0}; +static const GLubyte Fixed8x13_Character_240[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 4, 40, 24, 36, 0}; +static const GLubyte Fixed8x13_Character_241[] = { 8, 0, 0, 0, 66, 66, 66, 66, 98, 92, 0, 0, 76, 50, 0}; +static const GLubyte Fixed8x13_Character_242[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0, 16, 32, 0}; +static const GLubyte Fixed8x13_Character_243[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0, 16, 8, 0}; +static const GLubyte Fixed8x13_Character_244[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0, 36, 24, 0}; +static const GLubyte Fixed8x13_Character_245[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0, 76, 50, 0}; +static const GLubyte Fixed8x13_Character_246[] = { 8, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0, 36, 36, 0}; +static const GLubyte Fixed8x13_Character_247[] = { 8, 0, 0, 0, 0, 16, 16, 0,124, 0, 16, 16, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_248[] = { 8, 0, 0, 64, 60, 98, 82, 74, 70, 60, 2, 0, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_249[] = { 8, 0, 0, 0, 58, 68, 68, 68, 68, 68, 0, 0, 16, 32, 0}; +static const GLubyte Fixed8x13_Character_250[] = { 8, 0, 0, 0, 58, 68, 68, 68, 68, 68, 0, 0, 16, 8, 0}; +static const GLubyte Fixed8x13_Character_251[] = { 8, 0, 0, 0, 58, 68, 68, 68, 68, 68, 0, 0, 36, 24, 0}; +static const GLubyte Fixed8x13_Character_252[] = { 8, 0, 0, 0, 58, 68, 68, 68, 68, 68, 0, 0, 40, 40, 0}; +static const GLubyte Fixed8x13_Character_253[] = { 8, 0, 60, 66, 2, 58, 70, 66, 66, 66, 0, 0, 16, 8, 0}; +static const GLubyte Fixed8x13_Character_254[] = { 8, 0, 64, 64, 92, 98, 66, 66, 98, 92, 64, 64, 0, 0, 0}; +static const GLubyte Fixed8x13_Character_255[] = { 8, 0, 60, 66, 2, 58, 70, 66, 66, 66, 0, 0, 36, 36, 0}; + +/* The font characters mapping: */ +static const GLubyte* Fixed8x13_Character_Map[] = {Fixed8x13_Character_000,Fixed8x13_Character_001,Fixed8x13_Character_002,Fixed8x13_Character_003,Fixed8x13_Character_004,Fixed8x13_Character_005,Fixed8x13_Character_006,Fixed8x13_Character_007,Fixed8x13_Character_008,Fixed8x13_Character_009,Fixed8x13_Character_010,Fixed8x13_Character_011,Fixed8x13_Character_012,Fixed8x13_Character_013,Fixed8x13_Character_014,Fixed8x13_Character_015, + Fixed8x13_Character_016,Fixed8x13_Character_017,Fixed8x13_Character_018,Fixed8x13_Character_019,Fixed8x13_Character_020,Fixed8x13_Character_021,Fixed8x13_Character_022,Fixed8x13_Character_023,Fixed8x13_Character_024,Fixed8x13_Character_025,Fixed8x13_Character_026,Fixed8x13_Character_027,Fixed8x13_Character_028,Fixed8x13_Character_029,Fixed8x13_Character_030,Fixed8x13_Character_031, + Fixed8x13_Character_032,Fixed8x13_Character_033,Fixed8x13_Character_034,Fixed8x13_Character_035,Fixed8x13_Character_036,Fixed8x13_Character_037,Fixed8x13_Character_038,Fixed8x13_Character_039,Fixed8x13_Character_040,Fixed8x13_Character_041,Fixed8x13_Character_042,Fixed8x13_Character_043,Fixed8x13_Character_044,Fixed8x13_Character_045,Fixed8x13_Character_046,Fixed8x13_Character_047, + Fixed8x13_Character_048,Fixed8x13_Character_049,Fixed8x13_Character_050,Fixed8x13_Character_051,Fixed8x13_Character_052,Fixed8x13_Character_053,Fixed8x13_Character_054,Fixed8x13_Character_055,Fixed8x13_Character_056,Fixed8x13_Character_057,Fixed8x13_Character_058,Fixed8x13_Character_059,Fixed8x13_Character_060,Fixed8x13_Character_061,Fixed8x13_Character_062,Fixed8x13_Character_063, + Fixed8x13_Character_064,Fixed8x13_Character_065,Fixed8x13_Character_066,Fixed8x13_Character_067,Fixed8x13_Character_068,Fixed8x13_Character_069,Fixed8x13_Character_070,Fixed8x13_Character_071,Fixed8x13_Character_072,Fixed8x13_Character_073,Fixed8x13_Character_074,Fixed8x13_Character_075,Fixed8x13_Character_076,Fixed8x13_Character_077,Fixed8x13_Character_078,Fixed8x13_Character_079, + Fixed8x13_Character_080,Fixed8x13_Character_081,Fixed8x13_Character_082,Fixed8x13_Character_083,Fixed8x13_Character_084,Fixed8x13_Character_085,Fixed8x13_Character_086,Fixed8x13_Character_087,Fixed8x13_Character_088,Fixed8x13_Character_089,Fixed8x13_Character_090,Fixed8x13_Character_091,Fixed8x13_Character_092,Fixed8x13_Character_093,Fixed8x13_Character_094,Fixed8x13_Character_095, + Fixed8x13_Character_096,Fixed8x13_Character_097,Fixed8x13_Character_098,Fixed8x13_Character_099,Fixed8x13_Character_100,Fixed8x13_Character_101,Fixed8x13_Character_102,Fixed8x13_Character_103,Fixed8x13_Character_104,Fixed8x13_Character_105,Fixed8x13_Character_106,Fixed8x13_Character_107,Fixed8x13_Character_108,Fixed8x13_Character_109,Fixed8x13_Character_110,Fixed8x13_Character_111, + Fixed8x13_Character_112,Fixed8x13_Character_113,Fixed8x13_Character_114,Fixed8x13_Character_115,Fixed8x13_Character_116,Fixed8x13_Character_117,Fixed8x13_Character_118,Fixed8x13_Character_119,Fixed8x13_Character_120,Fixed8x13_Character_121,Fixed8x13_Character_122,Fixed8x13_Character_123,Fixed8x13_Character_124,Fixed8x13_Character_125,Fixed8x13_Character_126,Fixed8x13_Character_032, + Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032, + Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032,Fixed8x13_Character_032, + Fixed8x13_Character_160,Fixed8x13_Character_161,Fixed8x13_Character_162,Fixed8x13_Character_163,Fixed8x13_Character_164,Fixed8x13_Character_165,Fixed8x13_Character_166,Fixed8x13_Character_167,Fixed8x13_Character_168,Fixed8x13_Character_169,Fixed8x13_Character_170,Fixed8x13_Character_171,Fixed8x13_Character_172,Fixed8x13_Character_173,Fixed8x13_Character_174,Fixed8x13_Character_175, + Fixed8x13_Character_176,Fixed8x13_Character_177,Fixed8x13_Character_178,Fixed8x13_Character_179,Fixed8x13_Character_180,Fixed8x13_Character_181,Fixed8x13_Character_182,Fixed8x13_Character_183,Fixed8x13_Character_184,Fixed8x13_Character_185,Fixed8x13_Character_186,Fixed8x13_Character_187,Fixed8x13_Character_188,Fixed8x13_Character_189,Fixed8x13_Character_190,Fixed8x13_Character_191, + Fixed8x13_Character_192,Fixed8x13_Character_193,Fixed8x13_Character_194,Fixed8x13_Character_195,Fixed8x13_Character_196,Fixed8x13_Character_197,Fixed8x13_Character_198,Fixed8x13_Character_199,Fixed8x13_Character_200,Fixed8x13_Character_201,Fixed8x13_Character_202,Fixed8x13_Character_203,Fixed8x13_Character_204,Fixed8x13_Character_205,Fixed8x13_Character_206,Fixed8x13_Character_207, + Fixed8x13_Character_208,Fixed8x13_Character_209,Fixed8x13_Character_210,Fixed8x13_Character_211,Fixed8x13_Character_212,Fixed8x13_Character_213,Fixed8x13_Character_214,Fixed8x13_Character_215,Fixed8x13_Character_216,Fixed8x13_Character_217,Fixed8x13_Character_218,Fixed8x13_Character_219,Fixed8x13_Character_220,Fixed8x13_Character_221,Fixed8x13_Character_222,Fixed8x13_Character_223, + Fixed8x13_Character_224,Fixed8x13_Character_225,Fixed8x13_Character_226,Fixed8x13_Character_227,Fixed8x13_Character_228,Fixed8x13_Character_229,Fixed8x13_Character_230,Fixed8x13_Character_231,Fixed8x13_Character_232,Fixed8x13_Character_233,Fixed8x13_Character_234,Fixed8x13_Character_235,Fixed8x13_Character_236,Fixed8x13_Character_237,Fixed8x13_Character_238,Fixed8x13_Character_239, + Fixed8x13_Character_240,Fixed8x13_Character_241,Fixed8x13_Character_242,Fixed8x13_Character_243,Fixed8x13_Character_244,Fixed8x13_Character_245,Fixed8x13_Character_246,Fixed8x13_Character_247,Fixed8x13_Character_248,Fixed8x13_Character_249,Fixed8x13_Character_250,Fixed8x13_Character_251,Fixed8x13_Character_252,Fixed8x13_Character_253,Fixed8x13_Character_254,Fixed8x13_Character_255,NULL}; + +/* The font structure: */ +static const SFG_Font fgFontFixed8x13 = { "-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1", 256, 14, Fixed8x13_Character_Map, 0, 3 }; + + +static void +util_font_draw_character(void *dst_mem, unsigned dst_stride, unsigned character) +{ + unsigned char *dst = (unsigned char*)dst_mem; + const SFG_Font *font = &fgFontFixed8x13; + unsigned width = font->Characters[character][0]; + unsigned bitmap_stride = (width + 7) / 8; + unsigned j,i; + const GLubyte *bitmap = font->Characters[character]+1 + bitmap_stride * (font->Height - 1); + + for (j = 0; j < font->Height; j++) { + for (i = 0; i < width; i++) { + dst[i] = bitmap[i/8] & (128 >> (i%8)) ? 0xff : 0; + } + dst += dst_stride; + bitmap -= bitmap_stride; + } +} + +static boolean +util_font_create_fixed_8x13(struct pipe_context *pipe, + struct util_font *out_font) +{ + struct pipe_screen *screen = pipe->screen; + struct pipe_resource tex_templ, *tex; + struct pipe_transfer *transfer = NULL; + char *map; + enum pipe_format tex_format; + int i; + + if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM, + PIPE_TEXTURE_RECT, 0, + PIPE_BIND_SAMPLER_VIEW)) { + tex_format = PIPE_FORMAT_I8_UNORM; + } + else if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM, + PIPE_TEXTURE_RECT, 0, + PIPE_BIND_SAMPLER_VIEW)) { + tex_format = PIPE_FORMAT_L8_UNORM; + } + else { + return FALSE; + } + + memset(&tex_templ, 0, sizeof(tex_templ)); + tex_templ.target = PIPE_TEXTURE_RECT; + tex_templ.format = tex_format; + tex_templ.width0 = 128; + tex_templ.height0 = 256; + tex_templ.depth0 = 1; + tex_templ.array_size = 1; + tex_templ.usage = PIPE_USAGE_STATIC; + tex_templ.bind = PIPE_BIND_SAMPLER_VIEW; + + tex = screen->resource_create(screen, &tex_templ); + if (!tex) { + return FALSE; + } + + map = pipe_transfer_map(pipe, tex, 0, 0, PIPE_TRANSFER_WRITE, 0, 0, + tex->width0, tex->height0, &transfer); + if (!map) { + pipe_resource_reference(&tex, NULL); + return FALSE; + } + + for (i = 0; i < 256; i++) { + int x = (i % 16) * 8; + int y = (i / 16) * 14; + + util_font_draw_character(map + y * transfer->stride + x, + transfer->stride, i); + } + + pipe_transfer_unmap(pipe, transfer); + + pipe_resource_reference(&out_font->texture, NULL); + out_font->texture = tex; + out_font->glyph_width = 8; + out_font->glyph_height = 14; + return TRUE; +} + + +boolean +util_font_create(struct pipe_context *pipe, enum util_font_name name, + struct util_font *out_font) +{ + switch (name) { + case UTIL_FONT_FIXED_8X13: + return util_font_create_fixed_8x13(pipe, out_font); + } + return FALSE; +} diff --git a/mesalib/src/gallium/auxiliary/hud/font.h b/mesalib/src/gallium/auxiliary/hud/font.h new file mode 100644 index 000000000..cf1c87984 --- /dev/null +++ b/mesalib/src/gallium/auxiliary/hud/font.h @@ -0,0 +1,59 @@ +/************************************************************************** + * + * Copyright 2013 Marek Olšák + * 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 THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef FONT_H +#define FONT_H + +#include "pipe/p_compiler.h" + +struct pipe_resource; +struct pipe_context; + +enum util_font_name { + UTIL_FONT_FIXED_8X13 +}; + +/* The font is stored in a RECT texture. There are 256 glyphs + * drawn in a 16x16 matrix. The texture coordinates of a glyph + * within the matrix should be calculated as follows: + * + * x1 = (glyph % 16) * glyph_width; + * y1 = (glyph / 16) * glyph_height; + * x2 = x1 + glyph_width; + * y2 = y1 + glyph_height; + */ +struct util_font { + struct pipe_resource *texture; + unsigned glyph_width; + unsigned glyph_height; +}; + +boolean +util_font_create(struct pipe_context *pipe, enum util_font_name name, + struct util_font *out_font); + +#endif diff --git a/mesalib/src/gallium/auxiliary/hud/hud_context.c b/mesalib/src/gallium/auxiliary/hud/hud_context.c new file mode 100644 index 000000000..983f05756 --- /dev/null +++ b/mesalib/src/gallium/auxiliary/hud/hud_context.c @@ -0,0 +1,1078 @@ +/************************************************************************** + * + * Copyright 2013 Marek Olšák + * 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 THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* This head-up display module can draw transparent graphs on top of what + * the app is rendering, visualizing various data like framerate, cpu load, + * performance counters, etc. It can be hook up into any state tracker. + * + * The HUD is controlled with the GALLIUM_HUD environment variable. + * Set GALLIUM_HUD=help for more info. + */ + +#include "hud/hud_context.h" +#include "hud/hud_private.h" +#include "hud/font.h" + +#include "cso_cache/cso_context.h" +#include "util/u_draw_quad.h" +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_math.h" +#include "util/u_simple_shaders.h" +#include "util/u_string.h" +#include "util/u_upload_mgr.h" +#include "tgsi/tgsi_text.h" +#include "tgsi/tgsi_dump.h" + + +struct hud_context { + struct pipe_context *pipe; + struct cso_context *cso; + struct u_upload_mgr *uploader; + + struct list_head pane_list; + + /* states */ + struct pipe_blend_state alpha_blend; + struct pipe_depth_stencil_alpha_state dsa; + void *fs_color, *fs_text; + struct pipe_rasterizer_state rasterizer; + void *vs; + struct pipe_vertex_element velems[2]; + + /* font */ + struct util_font font; + struct pipe_sampler_view *font_sampler_view; + struct pipe_sampler_state font_sampler_state; + + /* VS constant buffer */ + struct { + float color[4]; + float two_div_fb_width; + float two_div_fb_height; + float translate[2]; + float scale[2]; + float padding[2]; + } constants; + struct pipe_constant_buffer constbuf; + + unsigned fb_width, fb_height; + + /* vertices for text and background drawing are accumulated here and then + * drawn all at once */ + struct vertex_queue { + float *vertices; + struct pipe_vertex_buffer vbuf; + unsigned max_num_vertices; + unsigned num_vertices; + } text, bg, whitelines; + + struct { + boolean query_pipeline_statistics; + } cap; +}; + + +static void +hud_draw_colored_prims(struct hud_context *hud, unsigned prim, + float *buffer, unsigned num_vertices, + float r, float g, float b, float a, + int xoffset, int yoffset, float yscale) +{ + struct cso_context *cso = hud->cso; + struct pipe_vertex_buffer vbuffer = {0}; + + hud->constants.color[0] = r; + hud->constants.color[1] = g; + hud->constants.color[2] = b; + hud->constants.color[3] = a; + hud->constants.translate[0] = xoffset; + hud->constants.translate[1] = yoffset; + hud->constants.scale[0] = 1; + hud->constants.scale[1] = yscale; + cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf); + + vbuffer.user_buffer = buffer; + vbuffer.stride = 2 * sizeof(float); + + cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), + 1, &vbuffer); + cso_set_fragment_shader_handle(hud->cso, hud->fs_color); + cso_draw_arrays(cso, prim, 0, num_vertices); +} + +static void +hud_draw_colored_quad(struct hud_context *hud, unsigned prim, + unsigned x1, unsigned y1, unsigned x2, unsigned y2, + float r, float g, float b, float a) +{ + float buffer[] = { + x1, y1, + x1, y2, + x2, y2, + x2, y1, + }; + + hud_draw_colored_prims(hud, prim, buffer, 4, r, g, b, a, 0, 0, 1); +} + +static void +hud_draw_background_quad(struct hud_context *hud, + unsigned x1, unsigned y1, unsigned x2, unsigned y2) +{ + float *vertices = hud->bg.vertices + hud->bg.num_vertices*2; + unsigned num = 0; + + assert(hud->bg.num_vertices + 4 <= hud->bg.max_num_vertices); + + vertices[num++] = x1; + vertices[num++] = y1; + + vertices[num++] = x1; + vertices[num++] = y2; + + vertices[num++] = x2; + vertices[num++] = y2; + + vertices[num++] = x2; + vertices[num++] = y1; + + hud->bg.num_vertices += num/2; +} + +static void +hud_draw_string(struct hud_context *hud, unsigned x, unsigned y, + const char *str, ...) +{ + char buf[256]; + char *s = buf; + float *vertices = hud->text.vertices + hud->text.num_vertices*4; + unsigned num = 0; + + va_list ap; + va_start(ap, str); + util_vsnprintf(buf, sizeof(buf), str, ap); + va_end(ap); + + if (!*s) + return; + + hud_draw_background_quad(hud, + x, y, + x + strlen(buf)*hud->font.glyph_width, + y + hud->font.glyph_height); + + while (*s) { + unsigned x1 = x; + unsigned y1 = y; + unsigned x2 = x + hud->font.glyph_width; + unsigned y2 = y + hud->font.glyph_height; + unsigned tx1 = (*s % 16) * hud->font.glyph_width; + unsigned ty1 = (*s / 16) * hud->font.glyph_height; + unsigned tx2 = tx1 + hud->font.glyph_width; + unsigned ty2 = ty1 + hud->font.glyph_height; + + if (*s == ' ') { + x += hud->font.glyph_width; + s++; + continue; + } + + assert(hud->text.num_vertices + num/4 + 4 <= hud->text.max_num_vertices); + + vertices[num++] = x1; + vertices[num++] = y1; + vertices[num++] = tx1; + vertices[num++] = ty1; + + vertices[num++] = x1; + vertices[num++] = y2; + vertices[num++] = tx1; + vertices[num++] = ty2; + + vertices[num++] = x2; + vertices[num++] = y2; + vertices[num++] = tx2; + vertices[num++] = ty2; + + vertices[num++] = x2; + vertices[num++] = y1; + vertices[num++] = tx2; + vertices[num++] = ty1; + + x += hud->font.glyph_width; + s++; + } + + hud->text.num_vertices += num/4; +} + +static void +number_to_human_readable(uint64_t num, boolean is_in_bytes, char *out) +{ + static const char *byte_units[] = + {"", " KB", " MB", " GB", " TB", " PB", " EB"}; + static const char *metric_units[] = + {"", " k", " M", " G", " T", " P", " E"}; + const char **units = is_in_bytes ? byte_units : metric_units; + double divisor = is_in_bytes ? 1024 : 1000; + int unit = 0; + double d = num; + + while (d > divisor) { + d /= divisor; + unit++; + } + + if (d >= 100 || d == (int)d) + sprintf(out, "%.0f%s", d, units[unit]); + else if (d >= 10 || d*10 == (int)(d*10)) + sprintf(out, "%.1f%s", d, units[unit]); + else + sprintf(out, "%.2f%s", d, units[unit]); +} + +static void +hud_draw_graph_line_strip(struct hud_context *hud, const struct hud_graph *gr, + unsigned xoffset, unsigned yoffset, float yscale) +{ + if (gr->num_vertices <= 1) + return; + + assert(gr->index <= gr->num_vertices); + + hud_draw_colored_prims(hud, PIPE_PRIM_LINE_STRIP, + gr->vertices, gr->index, + gr->color[0], gr->color[1], gr->color[2], 1, + xoffset + (gr->pane->max_num_vertices - gr->index - 1) * 2 - 1, + yoffset, yscale); + + if (gr->num_vertices <= gr->index) + return; + + hud_draw_colored_prims(hud, PIPE_PRIM_LINE_STRIP, + gr->vertices + gr->index*2, + gr->num_vertices - gr->index, + gr->color[0], gr->color[1], gr->color[2], 1, + xoffset - gr->index*2 - 1, yoffset, yscale); +} + +static void +hud_pane_accumulate_vertices(struct hud_context *hud, + const struct hud_pane *pane) +{ + struct hud_graph *gr; + float *line_verts = hud->whitelines.vertices + hud->whitelines.num_vertices*2; + unsigned i, num = 0; + char str[32]; + + /* draw background */ + hud_draw_background_quad(hud, + pane->x1, pane->y1, + pane->x2, pane->y2); + + /* draw numbers on the right-hand side */ + for (i = 0; i < 6; i++) { + unsigned x = pane->x2 + 2; + unsigned y = pane->inner_y1 + pane->inner_height * (5 - i) / 5 - + hud->font.glyph_height / 2; + + number_to_human_readable(pane->max_value * i / 5, + pane->uses_byte_units, str); + hud_draw_string(hud, x, y, str); + } + + /* draw info below the pane */ + i = 0; + LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) { + unsigned x = pane->x1 + 2; + unsigned y = pane->y2 + 2 + i*hud->font.glyph_height; + + number_to_human_readable(gr->current_value, + pane->uses_byte_units, str); + hud_draw_string(hud, x, y, " %s: %s", gr->name, str); + i++; + } + + /* draw border */ + assert(hud->whitelines.num_vertices + num/2 + 8 <= hud->whitelines.max_num_vertices); + line_verts[num++] = pane->x1; + line_verts[num++] = pane->y1; + line_verts[num++] = pane->x2; + line_verts[num++] = pane->y1; + + line_verts[num++] = pane->x2; + line_verts[num++] = pane->y1; + line_verts[num++] = pane->x2; + line_verts[num++] = pane->y2; + + line_verts[num++] = pane->x1; + line_verts[num++] = pane->y2; + line_verts[num++] = pane->x2; + line_verts[num++] = pane->y2; + + line_verts[num++] = pane->x1; + line_verts[num++] = pane->y1; + line_verts[num++] = pane->x1; + line_verts[num++] = pane->y2; + + /* draw horizontal lines inside the graph */ + for (i = 0; i <= 5; i++) { + float y = round((pane->max_value * i / 5.0) * pane->yscale + pane->inner_y2); + + assert(hud->whitelines.num_vertices + num/2 + 2 <= hud->whitelines.max_num_vertices); + line_verts[num++] = pane->x1; + line_verts[num++] = y; + line_verts[num++] = pane->x2; + line_verts[num++] = y; + } + + hud->whitelines.num_vertices += num/2; +} + +static void +hud_pane_draw_colored_objects(struct hud_context *hud, + const struct hud_pane *pane) +{ + struct hud_graph *gr; + unsigned i; + + /* draw colored quads below the pane */ + i = 0; + LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) { + unsigned x = pane->x1 + 2; + unsigned y = pane->y2 + 2 + i*hud->font.glyph_height; + + hud_draw_colored_quad(hud, PIPE_PRIM_QUADS, x + 1, y + 1, x + 12, y + 13, + gr->color[0], gr->color[1], gr->color[2], 1); + i++; + } + + /* draw the line strips */ + LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) { + hud_draw_graph_line_strip(hud, gr, pane->inner_x1, pane->inner_y2, pane->yscale); + } +} + +static void +hud_alloc_vertices(struct hud_context *hud, struct vertex_queue *v, + unsigned num_vertices, unsigned stride) +{ + v->num_vertices = 0; + v->max_num_vertices = num_vertices; + v->vbuf.stride = stride; + u_upload_alloc(hud->uploader, 0, v->vbuf.stride * v->max_num_vertices, + &v->vbuf.buffer_offset, &v->vbuf.buffer, + (void**)&v->vertices); +} + +/** + * Draw the HUD to the texture \p tex. + * The texture is usually the back buffer being displayed. + */ +void +hud_draw(struct hud_context *hud, struct pipe_resource *tex) +{ + struct cso_context *cso = hud->cso; + struct pipe_context *pipe = hud->pipe; + struct pipe_framebuffer_state fb; + struct pipe_surface surf_templ, *surf; + struct pipe_viewport_state viewport; + const struct pipe_sampler_state *sampler_states[] = + { &hud->font_sampler_state }; + struct hud_pane *pane; + struct hud_graph *gr; + + hud->fb_width = tex->width0; + hud->fb_height = tex->height0; + hud->constants.two_div_fb_width = 2.0 / hud->fb_width; + hud->constants.two_div_fb_height = 2.0 / hud->fb_height; + + cso_save_framebuffer(cso); + cso_save_sample_mask(cso); + cso_save_blend(cso); + cso_save_depth_stencil_alpha(cso); + cso_save_fragment_shader(cso); + cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT); + cso_save_samplers(cso, PIPE_SHADER_FRAGMENT); + cso_save_rasterizer(cso); + cso_save_viewport(cso); + cso_save_stream_outputs(cso); + cso_save_geometry_shader(cso); + cso_save_vertex_shader(cso); + cso_save_vertex_elements(cso); + cso_save_aux_vertex_buffer_slot(cso); + cso_save_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX); + cso_save_render_condition(cso); + + /* set states */ + memset(&surf_templ, 0, sizeof(surf_templ)); + surf_templ.format = tex->format; + surf = pipe->create_surface(pipe, tex, &surf_templ); + + memset(&fb, 0, sizeof(fb)); + fb.nr_cbufs = 1; + fb.cbufs[0] = surf; + fb.zsbuf = NULL; + fb.width = hud->fb_width; + fb.height = hud->fb_height; + + viewport.scale[0] = 0.5f * hud->fb_width; + viewport.scale[1] = 0.5f * hud->fb_height; + viewport.scale[2] = 1.0f; + viewport.scale[3] = 1.0f; + viewport.translate[0] = 0.5f * hud->fb_width; + viewport.translate[1] = 0.5f * hud->fb_height; + viewport.translate[2] = 0.0f; + viewport.translate[3] = 0.0f; + + cso_set_framebuffer(cso, &fb); + cso_set_sample_mask(cso, ~0); + cso_set_blend(cso, &hud->alpha_blend); + cso_set_depth_stencil_alpha(cso, &hud->dsa); + cso_set_rasterizer(cso, &hud->rasterizer); + cso_set_viewport(cso, &viewport); + cso_set_stream_outputs(cso, 0, NULL, 0); + cso_set_geometry_shader_handle(cso, NULL); + cso_set_vertex_shader_handle(cso, hud->vs); + cso_set_vertex_elements(cso, 2, hud->velems); + cso_set_render_condition(cso, NULL, 0); + cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, 1, + &hud->font_sampler_view); + cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, 1, sampler_states); + cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf); + + /* prepare vertex buffers */ + hud_alloc_vertices(hud, &hud->bg, 4 * 64, 2 * sizeof(float)); + hud_alloc_vertices(hud, &hud->whitelines, 4 * 256, 2 * sizeof(float)); + hud_alloc_vertices(hud, &hud->text, 4 * 512, 4 * sizeof(float)); + + /* prepare all graphs */ + LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) { + LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) { + gr->query_new_value(gr); + } + + hud_pane_accumulate_vertices(hud, pane); + } + + /* unmap the uploader's vertex buffer before drawing */ + u_upload_flush(hud->uploader); + + /* draw accumulated vertices for background quads */ + cso_set_fragment_shader_handle(hud->cso, hud->fs_color); + + if (hud->bg.num_vertices) { + hud->constants.color[0] = 0; + hud->constants.color[1] = 0; + hud->constants.color[2] = 0; + hud->constants.color[3] = 0.666; + hud->constants.translate[0] = 0; + hud->constants.translate[1] = 0; + hud->constants.scale[0] = 1; + hud->constants.scale[1] = 1; + + cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf); + cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1, + &hud->bg.vbuf); + cso_draw_arrays(cso, PIPE_PRIM_QUADS, 0, hud->bg.num_vertices); + } + pipe_resource_reference(&hud->bg.vbuf.buffer, NULL); + + /* draw accumulated vertices for white lines */ + hud->constants.color[0] = 1; + hud->constants.color[1] = 1; + hud->constants.color[2] = 1; + hud->constants.color[3] = 1; + hud->constants.translate[0] = 0; + hud->constants.translate[1] = 0; + hud->constants.scale[0] = 1; + hud->constants.scale[1] = 1; + cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf); + + if (hud->whitelines.num_vertices) { + cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1, + &hud->whitelines.vbuf); + cso_set_fragment_shader_handle(hud->cso, hud->fs_color); + cso_draw_arrays(cso, PIPE_PRIM_LINES, 0, hud->whitelines.num_vertices); + } + pipe_resource_reference(&hud->whitelines.vbuf.buffer, NULL); + + /* draw accumulated vertices for text */ + if (hud->text.num_vertices) { + cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1, + &hud->text.vbuf); + cso_set_fragment_shader_handle(hud->cso, hud->fs_text); + cso_draw_arrays(cso, PIPE_PRIM_QUADS, 0, hud->text.num_vertices); + } + pipe_resource_reference(&hud->text.vbuf.buffer, NULL); + + /* draw the rest */ + LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) { + if (pane) + hud_pane_draw_colored_objects(hud, pane); + } + + /* restore states */ + cso_restore_framebuffer(cso); + cso_restore_sample_mask(cso); + cso_restore_blend(cso); + cso_restore_depth_stencil_alpha(cso); + cso_restore_fragment_shader(cso); + cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT); + cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT); + cso_restore_rasterizer(cso); + cso_restore_viewport(cso); + cso_restore_stream_outputs(cso); + cso_restore_geometry_shader(cso); + cso_restore_vertex_shader(cso); + cso_restore_vertex_elements(cso); + cso_restore_aux_vertex_buffer_slot(cso); + cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX); + cso_restore_render_condition(cso); + + pipe_surface_reference(&surf, NULL); +} + +/** + * Set the maximum value for the Y axis of the graph. + * This scales the graph accordingly. + */ +void +hud_pane_set_max_value(struct hud_pane *pane, uint64_t value) +{ + pane->max_value = value; + pane->yscale = -(int)pane->inner_height / (double)pane->max_value; +} + +static struct hud_pane * +hud_pane_create(unsigned x1, unsigned y1, unsigned x2, unsigned y2, + unsigned period, uint64_t max_value) +{ + struct hud_pane *pane = CALLOC_STRUCT(hud_pane); + + if (!pane) + return NULL; + + pane->x1 = x1; + pane->y1 = y1; + pane->x2 = x2; + pane->y2 = y2; + pane->inner_x1 = x1 + 1; + pane->inner_x2 = x2 - 1; + pane->inner_y1 = y1 + 1; + pane->inner_y2 = y2 - 1; + pane->inner_width = pane->inner_x2 - pane->inner_x1; + pane->inner_height = pane->inner_y2 - pane->inner_y1; + pane->period = period; + pane->max_num_vertices = (x2 - x1 + 2) / 2; + hud_pane_set_max_value(pane, max_value); + LIST_INITHEAD(&pane->graph_list); + return pane; +} + +/** + * Add a graph to an existing pane. + * One pane can contain multiple graphs over each other. + */ +void +hud_pane_add_graph(struct hud_pane *pane, struct hud_graph *gr) +{ + static const float colors[][3] = { + {0, 1, 0}, + {1, 0, 0}, + {0, 1, 1}, + {1, 0, 1}, + {1, 1, 0}, + {0.5, 0.5, 1}, + {0.5, 0.5, 0.5}, + }; + char *name = gr->name; + + /* replace '-' with a space */ + while (*name) { + if (*name == '-') + *name = ' '; + name++; + } + + assert(pane->num_graphs < Elements(colors)); + gr->vertices = MALLOC(pane->max_num_vertices * sizeof(float) * 2); + gr->color[0] = colors[pane->num_graphs][0]; + gr->color[1] = colors[pane->num_graphs][1]; + gr->color[2] = colors[pane->num_graphs][2]; + gr->pane = pane; + LIST_ADDTAIL(&gr->head, &pane->graph_list); + pane->num_graphs++; +} + +void +hud_graph_add_value(struct hud_graph *gr, uint64_t value) +{ + if (gr->index == gr->pane->max_num_vertices) { + gr->vertices[0] = 0; + gr->vertices[1] = gr->vertices[(gr->index-1)*2+1]; + gr->index = 1; + } + gr->vertices[(gr->index)*2+0] = gr->index*2; + gr->vertices[(gr->index)*2+1] = value; + gr->index++; + + if (gr->num_vertices < gr->pane->max_num_vertices) { + gr->num_vertices++; + } + + gr->current_value = value; + if (value > gr->pane->max_value) { + hud_pane_set_max_value(gr->pane, value); + } +} + +static void +hud_graph_destroy(struct hud_graph *graph) +{ + FREE(graph->vertices); + if (graph->free_query_data) + graph->free_query_data(graph->query_data); + FREE(graph); +} + +/** + * Read a string from the environment variable. + * The separators "+", ",", ":", and ";" terminate the string. + * Return the number of read characters. + */ +static int +parse_string(const char *s, char *out) +{ + int i; + + for (i = 0; *s && *s != '+' && *s != ',' && *s != ':' && *s != ';'; + s++, out++, i++) + *out = *s; + + *out = 0; + + if (*s && !i) + fprintf(stderr, "gallium_hud: syntax error: unexpected '%c' (%i) while " + "parsing a string\n", *s, *s); + return i; +} + +static boolean +has_occlusion_query(struct pipe_screen *screen) +{ + return screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY) != 0; +} + +static boolean +has_streamout(struct pipe_screen *screen) +{ + return screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0; +} + +static void +hud_parse_env_var(struct hud_context *hud, const char *env) +{ + unsigned num, i; + char name[256], s[256]; + struct hud_pane *pane = NULL; + unsigned x = 10, y = 10; + unsigned width = 251, height = 100; + unsigned period = 500 * 1000; /* default period (1/2 second) */ + const char *period_env; + + /* + * The GALLIUM_HUD_PERIOD env var sets the graph update rate. + * The env var is in seconds (a float). + * Zero means update after every frame. + */ + period_env = getenv("GALLIUM_HUD_PERIOD"); + if (period_env) { + float p = atof(period_env); + if (p >= 0.0) { + period = (unsigned) (p * 1000 * 1000); + } + } + + while ((num = parse_string(env, name)) != 0) { + env += num; + + if (!pane) { + pane = hud_pane_create(x, y, x + width, y + height, period, 10); + if (!pane) + return; + } + + /* add a graph */ + if (strcmp(name, "fps") == 0) { + hud_fps_graph_install(pane); + } + else if (strcmp(name, "cpu") == 0) { + hud_cpu_graph_install(pane, ALL_CPUS); + } + else if (sscanf(name, "cpu%u%s", &i, s) == 1) { + hud_cpu_graph_install(pane, i); + } + else if (strcmp(name, "samples-passed") == 0 && + has_occlusion_query(hud->pipe->screen)) { + hud_pipe_query_install(pane, hud->pipe, "samples-passed", + PIPE_QUERY_OCCLUSION_COUNTER, 0, 0, FALSE); + } + else if (strcmp(name, "primitives-generated") == 0 && + has_streamout(hud->pipe->screen)) { + hud_pipe_query_install(pane, hud->pipe, "primitives-generated", + PIPE_QUERY_PRIMITIVES_GENERATED, 0, 0, FALSE); + } + else if (strncmp(name, "pipeline-statistics-", 20) == 0) { + if (hud->cap.query_pipeline_statistics) { + static const char *pipeline_statistics_names[] = + { + "ia-vertices", + "ia-primitives", + "vs-invocations", + "gs-invocations", + "gs-primitives", + "clipper-invocations", + "clipper-primitives-generated", + "ps-invocations", + "hs-invocations", + "ds-invocations", + "cs-invocations" + }; + for (i = 0; i < Elements(pipeline_statistics_names); ++i) + if (strcmp(&name[20], pipeline_statistics_names[i]) == 0) + break; + if (i < Elements(pipeline_statistics_names)) + hud_pipe_query_install(pane, hud->pipe, &name[20], + PIPE_QUERY_PIPELINE_STATISTICS, i, + 0, FALSE); + else + fprintf(stderr, "gallium_hud: invalid pipeline-statistics-*\n"); + } else { + fprintf(stderr, "gallium_hud: PIPE_QUERY_PIPELINE_STATISTICS " + "not supported by the driver\n"); + } + } + else { + if (!hud_driver_query_install(pane, hud->pipe, name)){ + fprintf(stderr, "gallium_hud: unknown driver query '%s'\n", name); + } + } + + if (*env == ':') { + env++; + + if (!pane) { + fprintf(stderr, "gallium_hud: syntax error: unexpected ':', " + "expected a name\n"); + break; + } + + num = parse_string(env, s); + env += num; + + if (num && sscanf(s, "%u", &i) == 1) { + hud_pane_set_max_value(pane, i); + } + else { + fprintf(stderr, "gallium_hud: syntax error: unexpected '%c' (%i) " + "after ':'\n", *env, *env); + } + } + + if (*env == 0) + break; + + /* parse a separator */ + switch (*env) { + case '+': + env++; + break; + + case ',': + env++; + y += height + hud->font.glyph_height * (pane->num_graphs + 2); + + if (pane && pane->num_graphs) { + LIST_ADDTAIL(&pane->head, &hud->pane_list); + pane = NULL; + } + break; + + case ';': + env++; + y = 10; + x += width + hud->font.glyph_width * 7; + + if (pane && pane->num_graphs) { + LIST_ADDTAIL(&pane->head, &hud->pane_list); + pane = NULL; + } + break; + + default: + fprintf(stderr, "gallium_hud: syntax error: unexpected '%c'\n", *env); + } + } + + if (pane) { + if (pane->num_graphs) { + LIST_ADDTAIL(&pane->head, &hud->pane_list); + } + else { + FREE(pane); + } + } +} + +static void +print_help(struct pipe_screen *screen) +{ + int i, num_queries, num_cpus = hud_get_num_cpus(); + + puts("Syntax: GALLIUM_HUD=name1[+name2][...][:value1][,nameI...][;nameJ...]"); + puts(""); + puts(" Names are identifiers of data sources which will be drawn as graphs"); + puts(" in panes. Multiple graphs can be drawn in the same pane."); + puts(" There can be multiple panes placed in rows and columns."); + puts(""); + puts(" '+' separates names which will share a pane."); + puts(" ':[value]' specifies the initial maximum value of the Y axis"); + puts(" for the given pane."); + puts(" ',' creates a new pane below the last one."); + puts(" ';' creates a new pane at the top of the next column."); + puts(""); + puts(" Example: GALLIUM_HUD=\"cpu,fps;primitives-generated\""); + puts(""); + puts(" Available names:"); + puts(" fps"); + puts(" cpu"); + + for (i = 0; i < num_cpus; i++) + printf(" cpu%i\n", i); + + if (has_occlusion_query(screen)) + puts(" pixels-rendered"); + if (has_streamout(screen)) + puts(" primitives-generated"); + + if (screen->get_driver_query_info){ + struct pipe_driver_query_info info; + num_queries = screen->get_driver_query_info(screen, 0, NULL); + + for (i = 0; i < num_queries; i++){ + screen->get_driver_query_info(screen, i, &info); + printf(" %s\n", info.name); + } + } + + puts(""); +} + +struct hud_context * +hud_create(struct pipe_context *pipe, struct cso_context *cso) +{ + struct hud_context *hud; + struct pipe_sampler_view view_templ; + unsigned i; + const char *env = debug_get_option("GALLIUM_HUD", NULL); + + if (!env || !*env) + return NULL; + + if (strcmp(env, "help") == 0) { + print_help(pipe->screen); + return NULL; + } + + hud = CALLOC_STRUCT(hud_context); + if (!hud) + return NULL; + + hud->pipe = pipe; + hud->cso = cso; + hud->uploader = u_upload_create(pipe, 256 * 1024, 16, + PIPE_BIND_VERTEX_BUFFER); + + /* font */ + if (!util_font_create(pipe, UTIL_FONT_FIXED_8X13, &hud->font)) { + u_upload_destroy(hud->uploader); + FREE(hud); + return NULL; + } + + /* blend state */ + hud->alpha_blend.rt[0].colormask = PIPE_MASK_RGBA; + hud->alpha_blend.rt[0].blend_enable = 1; + hud->alpha_blend.rt[0].rgb_func = PIPE_BLEND_ADD; + hud->alpha_blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + hud->alpha_blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; + hud->alpha_blend.rt[0].alpha_func = PIPE_BLEND_ADD; + hud->alpha_blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO; + hud->alpha_blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + + /* fragment shader */ + hud->fs_color = + util_make_fragment_passthrough_shader(pipe, + TGSI_SEMANTIC_COLOR, + TGSI_INTERPOLATE_CONSTANT); + + { + /* Read a texture and do .xxxx swizzling. */ + static const char *fragment_shader_text = { + "FRAG\n" + "DCL IN[0], GENERIC[0], LINEAR\n" + "DCL SAMP[0]\n" + "DCL OUT[0], COLOR[0]\n" + "DCL TEMP[0]\n" + + "TEX TEMP[0], IN[0], SAMP[0], RECT\n" + "MOV OUT[0], TEMP[0].xxxx\n" + "END\n" + }; + + struct tgsi_token tokens[1000]; + struct pipe_shader_state state = {tokens}; + + if (!tgsi_text_translate(fragment_shader_text, tokens, Elements(tokens))) { + assert(0); + pipe_resource_reference(&hud->font.texture, NULL); + u_upload_destroy(hud->uploader); + FREE(hud); + return NULL; + } + + hud->fs_text = pipe->create_fs_state(pipe, &state); + } + + /* rasterizer */ + hud->rasterizer.gl_rasterization_rules = 1; + hud->rasterizer.depth_clip = 1; + hud->rasterizer.line_width = 1; + hud->rasterizer.line_last_pixel = 1; + + /* vertex shader */ + { + static const char *vertex_shader_text = { + "VERT\n" + "DCL IN[0..1]\n" + "DCL OUT[0], POSITION\n" + "DCL OUT[1], COLOR[0]\n" /* color */ + "DCL OUT[2], GENERIC[0]\n" /* texcoord */ + /* [0] = color, + * [1] = (2/fb_width, 2/fb_height, xoffset, yoffset) + * [2] = (xscale, yscale, 0, 0) */ + "DCL CONST[0..2]\n" + "DCL TEMP[0]\n" + "IMM[0] FLT32 { -1, 0, 0, 1 }\n" + + /* v = in * (xscale, yscale) + (xoffset, yoffset) */ + "MAD TEMP[0].xy, IN[0], CONST[2].xyyy, CONST[1].zwww\n" + /* pos = v * (2 / fb_width, 2 / fb_height) - (1, 1) */ + "MAD OUT[0].xy, TEMP[0], CONST[1].xyyy, IMM[0].xxxx\n" + "MOV OUT[0].zw, IMM[0]\n" + + "MOV OUT[1], CONST[0]\n" + "MOV OUT[2], IN[1]\n" + "END\n" + }; + + struct tgsi_token tokens[1000]; + struct pipe_shader_state state = {tokens}; + + if (!tgsi_text_translate(vertex_shader_text, tokens, Elements(tokens))) { + assert(0); + pipe_resource_reference(&hud->font.texture, NULL); + u_upload_destroy(hud->uploader); + FREE(hud); + return NULL; + } + + hud->vs = pipe->create_vs_state(pipe, &state); + } + + /* vertex elements */ + for (i = 0; i < 2; i++) { + hud->velems[i].src_offset = i * 2 * sizeof(float); + hud->velems[i].src_format = PIPE_FORMAT_R32G32_FLOAT; + hud->velems[i].vertex_buffer_index = cso_get_aux_vertex_buffer_slot(cso); + } + + /* sampler view */ + memset(&view_templ, 0, sizeof(view_templ)); + view_templ.format = hud->font.texture->format; + view_templ.swizzle_r = PIPE_SWIZZLE_RED; + view_templ.swizzle_g = PIPE_SWIZZLE_GREEN; + view_templ.swizzle_b = PIPE_SWIZZLE_BLUE; + view_templ.swizzle_a = PIPE_SWIZZLE_ALPHA; + hud->font_sampler_view = pipe->create_sampler_view(pipe, hud->font.texture, + &view_templ); + + /* sampler state (for font drawing) */ + hud->font_sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + hud->font_sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + hud->font_sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + hud->font_sampler_state.normalized_coords = 0; + + /* constants */ + hud->constbuf.buffer_size = sizeof(hud->constants); + hud->constbuf.user_buffer = &hud->constants; + + LIST_INITHEAD(&hud->pane_list); + + hud->cap.query_pipeline_statistics = + pipe->screen->get_param(pipe->screen, PIPE_CAP_QUERY_PIPELINE_STATISTICS); + + hud_parse_env_var(hud, env); + return hud; +} + +void +hud_destroy(struct hud_context *hud) +{ + struct pipe_context *pipe = hud->pipe; + struct hud_pane *pane, *pane_tmp; + struct hud_graph *graph, *graph_tmp; + + LIST_FOR_EACH_ENTRY_SAFE(pane, pane_tmp, &hud->pane_list, head) { + LIST_FOR_EACH_ENTRY_SAFE(graph, graph_tmp, &pane->graph_list, head) { + LIST_DEL(&graph->head); + hud_graph_destroy(graph); + } + LIST_DEL(&pane->head); + FREE(pane); + } + + pipe->delete_fs_state(pipe, hud->fs_color); + pipe->delete_fs_state(pipe, hud->fs_text); + pipe->delete_vs_state(pipe, hud->vs); + pipe_sampler_view_reference(&hud->font_sampler_view, NULL); + pipe_resource_reference(&hud->font.texture, NULL); + u_upload_destroy(hud->uploader); + FREE(hud); +} diff --git a/mesalib/src/gallium/auxiliary/hud/hud_context.h b/mesalib/src/gallium/auxiliary/hud/hud_context.h new file mode 100644 index 000000000..abf2ad586 --- /dev/null +++ b/mesalib/src/gallium/auxiliary/hud/hud_context.h @@ -0,0 +1,45 @@ +/************************************************************************** + * + * Copyright 2013 Marek Olšák + * 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 THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef HUD_CONTEXT_H +#define HUD_CONTEXT_H + +struct hud_context; +struct cso_context; +struct pipe_context; +struct pipe_resource; + +struct hud_context * +hud_create(struct pipe_context *pipe, struct cso_context *cso); + +void +hud_destroy(struct hud_context *hud); + +void +hud_draw(struct hud_context *hud, struct pipe_resource *tex); + +#endif diff --git a/mesalib/src/gallium/auxiliary/hud/hud_cpu.c b/mesalib/src/gallium/auxiliary/hud/hud_cpu.c new file mode 100644 index 000000000..ce98115d5 --- /dev/null +++ b/mesalib/src/gallium/auxiliary/hud/hud_cpu.c @@ -0,0 +1,166 @@ +/************************************************************************** + * + * Copyright 2013 Marek Olšák + * 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 THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* This file contains code for reading CPU load for displaying on the HUD. + */ + +#include "hud/hud_private.h" +#include "os/os_time.h" +#include "util/u_memory.h" +#include +#include + +static boolean +get_cpu_stats(unsigned cpu_index, uint64_t *busy_time, uint64_t *total_time) +{ + char cpuname[32]; + char line[1024]; + FILE *f; + + if (cpu_index == ALL_CPUS) + strcpy(cpuname, "cpu"); + else + sprintf(cpuname, "cpu%u", cpu_index); + + f = fopen("/proc/stat", "r"); + if (!f) + return FALSE; + + while (!feof(f) && fgets(line, sizeof(line), f)) { + if (strstr(line, cpuname) == line) { + uint64_t v[12]; + int i, num; + + num = sscanf(line, + "%s %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64 + " %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64 + " %"PRIu64" %"PRIu64"", + cpuname, &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], + &v[6], &v[7], &v[8], &v[9], &v[10], &v[11]); + if (num < 5) { + fclose(f); + return FALSE; + } + + /* user + nice + system */ + *busy_time = v[0] + v[1] + v[2]; + *total_time = *busy_time; + + /* ... + idle + iowait + irq + softirq + ... */ + for (i = 3; i < num-1; i++) { + *total_time += v[i]; + } + fclose(f); + return TRUE; + } + } + fclose(f); + return FALSE; +} + +struct cpu_info { + unsigned cpu_index; + uint64_t last_cpu_busy, last_cpu_total, last_time; +}; + +static void +query_cpu_load(struct hud_graph *gr) +{ + struct cpu_info *info = gr->query_data; + uint64_t now = os_time_get(); + + if (info->last_time) { + if (info->last_time + gr->pane->period <= now) { + uint64_t cpu_busy, cpu_total, cpu_load; + + get_cpu_stats(info->cpu_index, &cpu_busy, &cpu_total); + + cpu_load = (cpu_busy - info->last_cpu_busy) * 100 / + (double)(cpu_total - info->last_cpu_total); + hud_graph_add_value(gr, cpu_load); + + info->last_cpu_busy = cpu_busy; + info->last_cpu_total = cpu_total; + info->last_time = now; + } + } + else { + /* initialize */ + info->last_time = now; + get_cpu_stats(info->cpu_index, &info->last_cpu_busy, + &info->last_cpu_total); + } +} + +void +hud_cpu_graph_install(struct hud_pane *pane, unsigned cpu_index) +{ + struct hud_graph *gr; + struct cpu_info *info; + uint64_t busy, total; + + /* see if the cpu exists */ + if (cpu_index != ALL_CPUS && !get_cpu_stats(cpu_index, &busy, &total)) { + return; + } + + gr = CALLOC_STRUCT(hud_graph); + if (!gr) + return; + + if (cpu_index == ALL_CPUS) + strcpy(gr->name, "cpu"); + else + sprintf(gr->name, "cpu%u", cpu_index); + + gr->query_data = CALLOC_STRUCT(cpu_info); + if (!gr->query_data) { + FREE(gr); + return; + } + + gr->query_new_value = query_cpu_load; + gr->free_query_data = free; + + info = gr->query_data; + info->cpu_index = cpu_index; + + hud_pane_add_graph(pane, gr); + hud_pane_set_max_value(pane, 100); +} + +int +hud_get_num_cpus(void) +{ + uint64_t busy, total; + int i = 0; + + while (get_cpu_stats(i, &busy, &total)) + i++; + + return i; +} diff --git a/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c b/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c new file mode 100644 index 000000000..0f52e18cc --- /dev/null +++ b/mesalib/src/gallium/auxiliary/hud/hud_driver_query.c @@ -0,0 +1,210 @@ +/************************************************************************** + * + * Copyright 2013 Marek Olšák + * 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 THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* This file contains code for reading values from pipe queries + * for displaying on the HUD. To prevent stalls when reading queries, we + * keep a list of busy queries in a ring. We read only those queries which + * are idle. + */ + +#include "hud/hud_private.h" +#include "pipe/p_screen.h" +#include "os/os_time.h" +#include "util/u_memory.h" +#include + +#define NUM_QUERIES 8 + +struct query_info { + struct pipe_context *pipe; + unsigned query_type; + unsigned result_index; /* unit depends on query_type */ + + /* Ring of queries. If a query is busy, we use another slot. */ + struct pipe_query *query[NUM_QUERIES]; + unsigned head, tail; + unsigned num_queries; + + uint64_t last_time; + uint64_t results_cumulative; + unsigned num_results; +}; + +static void +query_new_value(struct hud_graph *gr) +{ + struct query_info *info = gr->query_data; + struct pipe_context *pipe = info->pipe; + uint64_t now = os_time_get(); + + if (info->last_time) { + pipe->end_query(pipe, info->query[info->head]); + + /* read query results */ + while (1) { + struct pipe_query *query = info->query[info->tail]; + union pipe_query_result result; + uint64_t *res64 = (uint64_t *)&result; + + if (pipe->get_query_result(pipe, query, FALSE, &result)) { + info->results_cumulative += res64[info->result_index]; + info->num_results++; + + if (info->tail == info->head) + break; + + info->tail = (info->tail+1) % NUM_QUERIES; + } + else { + /* the oldest query is busy */ + if ((info->head+1) % NUM_QUERIES == info->tail) { + /* all queries are busy, throw away the last query and create + * a new one */ + fprintf(stderr, + "gallium_hud: all queries are busy after %i frames, " + "can't add another query\n", + NUM_QUERIES); + pipe->destroy_query(pipe, info->query[info->head]); + info->query[info->head] = + pipe->create_query(pipe, info->query_type); + } + else { + /* the last query is busy, we need to add a new one we can use + * for this frame */ + info->head = (info->head+1) % NUM_QUERIES; + if (!info->query[info->head]) { + info->query[info->head] = + pipe->create_query(pipe, info->query_type); + } + } + break; + } + } + + if (info->num_results && info->last_time + gr->pane->period <= now) { + /* compute the average value across all frames */ + hud_graph_add_value(gr, info->results_cumulative / info->num_results); + + info->last_time = now; + info->results_cumulative = 0; + info->num_results = 0; + } + + pipe->begin_query(pipe, info->query[info->head]); + } + else { + /* initialize */ + info->last_time = now; + info->query[info->head] = pipe->create_query(pipe, info->query_type); + pipe->begin_query(pipe, info->query[info->head]); + } +} + +static void +free_query_info(void *ptr) +{ + struct query_info *info = ptr; + + if (info->last_time) { + struct pipe_context *pipe = info->pipe; + int i; + + pipe->end_query(pipe, info->query[info->head]); + + for (i = 0; i < Elements(info->query); i++) { + if (info->query[i]) { + pipe->destroy_query(pipe, info->query[i]); + } + } + } + FREE(info); +} + +void +hud_pipe_query_install(struct hud_pane *pane, struct pipe_context *pipe, + const char *name, unsigned query_type, + unsigned result_index, + uint64_t max_value, boolean uses_byte_units) +{ + struct hud_graph *gr; + struct query_info *info; + + gr = CALLOC_STRUCT(hud_graph); + if (!gr) + return; + + strcpy(gr->name, name); + gr->query_data = CALLOC_STRUCT(query_info); + if (!gr->query_data) { + FREE(gr); + return; + } + + gr->query_new_value = query_new_value; + gr->free_query_data = free_query_info; + + info = gr->query_data; + info->pipe = pipe; + info->query_type = query_type; + info->result_index = result_index; + + hud_pane_add_graph(pane, gr); + if (pane->max_value < max_value) + hud_pane_set_max_value(pane, max_value); + if (uses_byte_units) + pane->uses_byte_units = TRUE; +} + +boolean +hud_driver_query_install(struct hud_pane *pane, struct pipe_context *pipe, + const char *name) +{ + struct pipe_screen *screen = pipe->screen; + struct pipe_driver_query_info query; + unsigned num_queries, i; + boolean found = FALSE; + + if (!screen->get_driver_query_info) + return FALSE; + + num_queries = screen->get_driver_query_info(screen, 0, NULL); + + for (i = 0; i < num_queries; i++) { + if (screen->get_driver_query_info(screen, i, &query) && + strcmp(query.name, name) == 0) { + found = TRUE; + break; + } + } + + if (!found) + return FALSE; + + hud_pipe_query_install(pane, pipe, query.name, query.query_type, 0, + query.max_value, query.uses_byte_units); + return TRUE; +} diff --git a/mesalib/src/gallium/auxiliary/hud/hud_fps.c b/mesalib/src/gallium/auxiliary/hud/hud_fps.c new file mode 100644 index 000000000..71cdfd04e --- /dev/null +++ b/mesalib/src/gallium/auxiliary/hud/hud_fps.c @@ -0,0 +1,81 @@ +/************************************************************************** + * + * Copyright 2013 Marek Olšák + * 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 THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* This file contains code for calculating framerate for displaying on the HUD. + */ + +#include "hud/hud_private.h" +#include "os/os_time.h" +#include "util/u_memory.h" + +struct fps_info { + int frames; + uint64_t last_time; +}; + +static void +query_fps(struct hud_graph *gr) +{ + struct fps_info *info = gr->query_data; + uint64_t now = os_time_get(); + + info->frames++; + + if (info->last_time) { + if (info->last_time + gr->pane->period <= now) { + double fps = info->frames * 1000000 / (double)(now - info->last_time); + info->frames = 0; + info->last_time = now; + + hud_graph_add_value(gr, fps); + } + } + else { + info->last_time = now; + } +} + +void +hud_fps_graph_install(struct hud_pane *pane) +{ + struct hud_graph *gr = CALLOC_STRUCT(hud_graph); + + if (!gr) + return; + + strcpy(gr->name, "fps"); + gr->query_data = CALLOC_STRUCT(fps_info); + if (!gr->query_data) { + FREE(gr); + return; + } + + gr->query_new_value = query_fps; + gr->free_query_data = free; + + hud_pane_add_graph(pane, gr); +} diff --git a/mesalib/src/gallium/auxiliary/hud/hud_private.h b/mesalib/src/gallium/auxiliary/hud/hud_private.h new file mode 100644 index 000000000..2b7d56bb1 --- /dev/null +++ b/mesalib/src/gallium/auxiliary/hud/hud_private.h @@ -0,0 +1,92 @@ +/************************************************************************** + * + * Copyright 2013 Marek Olšák + * 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 THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef HUD_PRIVATE_H +#define HUD_PRIVATE_H + +#include "pipe/p_context.h" +#include "util/u_double_list.h" + +struct hud_graph { + /* initialized by common code */ + struct list_head head; + struct hud_pane *pane; + float color[3]; + float *vertices; /* ring buffer of vertices */ + + /* name and query */ + char name[128]; + void *query_data; + void (*query_new_value)(struct hud_graph *gr); + void (*free_query_data)(void *ptr); + + /* mutable variables */ + unsigned num_vertices; + unsigned index; /* vertex index being updated */ + uint64_t current_value; +}; + +struct hud_pane { + struct list_head head; + unsigned x1, y1, x2, y2; + unsigned inner_x1; + unsigned inner_y1; + unsigned inner_x2; + unsigned inner_y2; + unsigned inner_width; + unsigned inner_height; + float yscale; + unsigned max_num_vertices; + uint64_t max_value; + boolean uses_byte_units; + uint64_t period; /* in microseconds */ + + struct list_head graph_list; + unsigned num_graphs; +}; + + +/* core */ +void hud_pane_add_graph(struct hud_pane *pane, struct hud_graph *gr); +void hud_pane_set_max_value(struct hud_pane *pane, uint64_t value); +void hud_graph_add_value(struct hud_graph *gr, uint64_t value); + +/* graphs/queries */ +#define ALL_CPUS ~0 /* optionally set as cpu_index */ + +int hud_get_num_cpus(void); + +void hud_fps_graph_install(struct hud_pane *pane); +void hud_cpu_graph_install(struct hud_pane *pane, unsigned cpu_index); +void hud_pipe_query_install(struct hud_pane *pane, struct pipe_context *pipe, + const char *name, unsigned query_type, + unsigned result_index, + uint64_t max_value, boolean uses_byte_units); +boolean hud_driver_query_install(struct hud_pane *pane, + struct pipe_context *pipe, const char *name); + +#endif diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c index 70fec9118..2a4a13e9f 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.c +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c @@ -1135,18 +1135,17 @@ static boolean is_blit_generic_supported(struct blitter_context *blitter, if (dst) { unsigned bind; - boolean is_stencil; const struct util_format_description *desc = util_format_description(dst_format); - - is_stencil = util_format_has_stencil(desc); + boolean dst_has_stencil = util_format_has_stencil(desc); /* Stencil export must be supported for stencil copy. */ - if ((mask & PIPE_MASK_S) && is_stencil && !ctx->has_stencil_export) { + if ((mask & PIPE_MASK_S) && dst_has_stencil && + !ctx->has_stencil_export) { return FALSE; } - if (is_stencil || util_format_has_depth(desc)) + if (dst_has_stencil || util_format_has_depth(desc)) bind = PIPE_BIND_DEPTH_STENCIL; else bind = PIPE_BIND_RENDER_TARGET; @@ -1168,15 +1167,18 @@ static boolean is_blit_generic_supported(struct blitter_context *blitter, } /* Check stencil sampler support for stencil copy. */ - if (util_format_has_stencil(util_format_description(src_format))) { - enum pipe_format stencil_format = + if (mask & PIPE_MASK_S) { + if (util_format_has_stencil(util_format_description(src_format))) { + enum pipe_format stencil_format = util_format_stencil_only(src_format); - assert(stencil_format != PIPE_FORMAT_NONE); + assert(stencil_format != PIPE_FORMAT_NONE); - if (stencil_format != src_format && - !screen->is_format_supported(screen, stencil_format, src->target, - src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) { - return FALSE; + if (stencil_format != src_format && + !screen->is_format_supported(screen, stencil_format, + src->target, src->nr_samples, + PIPE_BIND_SAMPLER_VIEW)) { + return FALSE; + } } } } diff --git a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c index 03280515b..7e6df9df1 100644 --- a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c +++ b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c @@ -279,6 +279,7 @@ util_cpu_detect(void) util_cpu_caps.has_sse4_1 = (regs2[2] >> 19) & 1; util_cpu_caps.has_sse4_2 = (regs2[2] >> 20) & 1; util_cpu_caps.has_avx = (regs2[2] >> 28) & 1; + util_cpu_caps.has_f16c = (regs2[2] >> 29) & 1; util_cpu_caps.has_mmx2 = util_cpu_caps.has_sse; /* SSE cpus supports mmxext too */ cacheline = ((regs2[1] >> 8) & 0xFF) * 8; diff --git a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h index acac68658..21c2f048f 100644 --- a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h +++ b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h @@ -63,6 +63,7 @@ struct util_cpu_caps { unsigned has_sse4_1:1; unsigned has_sse4_2:1; unsigned has_avx:1; + unsigned has_f16c:1; unsigned has_3dnow:1; unsigned has_3dnow_ext:1; unsigned has_altivec:1; diff --git a/mesalib/src/gallium/auxiliary/util/u_debug_memory.c b/mesalib/src/gallium/auxiliary/util/u_debug_memory.c index 4bf26a524..472354781 100644 --- a/mesalib/src/gallium/auxiliary/util/u_debug_memory.c +++ b/mesalib/src/gallium/auxiliary/util/u_debug_memory.c @@ -76,6 +76,7 @@ struct debug_memory_header #endif unsigned magic; + unsigned tag; }; struct debug_memory_footer @@ -140,6 +141,7 @@ debug_malloc(const char *file, unsigned line, const char *function, hdr->function = function; hdr->size = size; hdr->magic = DEBUG_MEMORY_MAGIC; + hdr->tag = 0; #if DEBUG_FREED_MEMORY hdr->freed = FALSE; #endif @@ -263,6 +265,7 @@ debug_realloc(const char *file, unsigned line, const char *function, new_hdr->function = old_hdr->function; new_hdr->size = new_size; new_hdr->magic = DEBUG_MEMORY_MAGIC; + new_hdr->tag = 0; #if DEBUG_FREED_MEMORY new_hdr->freed = FALSE; #endif @@ -347,6 +350,58 @@ debug_memory_end(unsigned long start_no) } +/** + * Put a tag (arbitrary integer) on a memory block. + * Can be useful for debugging. + */ +void +debug_memory_tag(void *ptr, unsigned tag) +{ + struct debug_memory_header *hdr; + + if (!ptr) + return; + + hdr = header_from_data(ptr); + if (hdr->magic != DEBUG_MEMORY_MAGIC) { + debug_printf("%s corrupted memory at %p\n", __FUNCTION__, ptr); + debug_assert(0); + } + + hdr->tag = tag; +} + + +/** + * Check the given block of memory for validity/corruption. + */ +void +debug_memory_check_block(void *ptr) +{ + struct debug_memory_header *hdr; + struct debug_memory_footer *ftr; + + if (!ptr) + return; + + hdr = header_from_data(ptr); + ftr = footer_from_header(hdr); + + if (hdr->magic != DEBUG_MEMORY_MAGIC) { + debug_printf("%s:%u:%s: bad or corrupted memory %p\n", + hdr->file, hdr->line, hdr->function, ptr); + debug_assert(0); + } + + if (ftr->magic != DEBUG_MEMORY_MAGIC) { + debug_printf("%s:%u:%s: buffer overflow %p\n", + hdr->file, hdr->line, hdr->function, ptr); + debug_assert(0); + } +} + + + /** * We can periodically call this from elsewhere to do a basic sanity * check of the heap memory we've allocated. diff --git a/mesalib/src/gallium/auxiliary/util/u_format.h b/mesalib/src/gallium/auxiliary/util/u_format.h index 00301265d..ed942fb16 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format.h +++ b/mesalib/src/gallium/auxiliary/util/u_format.h @@ -447,6 +447,7 @@ util_format_is_compressed(enum pipe_format format) switch (desc->layout) { case UTIL_FORMAT_LAYOUT_S3TC: case UTIL_FORMAT_LAYOUT_RGTC: + case UTIL_FORMAT_LAYOUT_ETC: /* XXX add other formats in the future */ return TRUE; default: diff --git a/mesalib/src/gallium/auxiliary/util/u_inlines.h b/mesalib/src/gallium/auxiliary/util/u_inlines.h index ba745ebb5..7770cd514 100644 --- a/mesalib/src/gallium/auxiliary/util/u_inlines.h +++ b/mesalib/src/gallium/auxiliary/util/u_inlines.h @@ -517,7 +517,7 @@ util_query_clear_result(union pipe_query_result *result, unsigned type) memset(&result->pipeline_statistics, 0, sizeof(result->pipeline_statistics)); break; default: - assert(0); + memset(result, 0, sizeof(*result)); } } @@ -583,7 +583,7 @@ util_copy_constant_buffer(struct pipe_constant_buffer *dst, } static INLINE unsigned -util_max_layer(struct pipe_resource *r, unsigned level) +util_max_layer(const struct pipe_resource *r, unsigned level) { switch (r->target) { case PIPE_TEXTURE_CUBE: diff --git a/mesalib/src/gallium/auxiliary/util/u_resource.c b/mesalib/src/gallium/auxiliary/util/u_resource.c index a32c4f6df..66caaae84 100644 --- a/mesalib/src/gallium/auxiliary/util/u_resource.c +++ b/mesalib/src/gallium/auxiliary/util/u_resource.c @@ -1,76 +1,65 @@ +/* + * Copyright 2013 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, 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 THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ -#include "util/u_inlines.h" -#include "util/u_transfer.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_resource.h" -static INLINE struct u_resource * -u_resource( struct pipe_resource *res ) -{ - return (struct u_resource *)res; -} -boolean u_resource_get_handle_vtbl(struct pipe_screen *screen, - struct pipe_resource *resource, - struct winsys_handle *handle) +/** + * Return the size of the resource in bytes. + */ +unsigned +util_resource_size(const struct pipe_resource *res) { - struct u_resource *ur = u_resource(resource); - return ur->vtbl->resource_get_handle(screen, resource, handle); -} + unsigned width = res->width0; + unsigned height = res->height0; + unsigned depth = res->depth0; + unsigned size = 0; + unsigned level; -void u_resource_destroy_vtbl(struct pipe_screen *screen, - struct pipe_resource *resource) -{ - struct u_resource *ur = u_resource(resource); - ur->vtbl->resource_destroy(screen, resource); -} + for (level = 0; level <= res->last_level; level++) { + unsigned slices; -void *u_transfer_map_vtbl(struct pipe_context *context, - struct pipe_resource *resource, - unsigned level, - unsigned usage, - const struct pipe_box *box, - struct pipe_transfer **transfer) -{ - struct u_resource *ur = u_resource(resource); - return ur->vtbl->transfer_map(context, resource, level, usage, box, - transfer); -} + if (res->target == PIPE_TEXTURE_CUBE) + slices = 6; + else if (res->target == PIPE_TEXTURE_3D) + slices = depth; + else + slices = res->array_size; -void u_transfer_flush_region_vtbl( struct pipe_context *pipe, - struct pipe_transfer *transfer, - const struct pipe_box *box) -{ - struct u_resource *ur = u_resource(transfer->resource); - ur->vtbl->transfer_flush_region(pipe, transfer, box); -} + size += (util_format_get_nblocksy(res->format, height) * + util_format_get_stride(res->format, width) * slices); -void u_transfer_unmap_vtbl( struct pipe_context *pipe, - struct pipe_transfer *transfer ) -{ - struct u_resource *ur = u_resource(transfer->resource); - ur->vtbl->transfer_unmap(pipe, transfer); -} + width = u_minify(width, 1); + height = u_minify(height, 1); + depth = u_minify(depth, 1); + } -void u_transfer_inline_write_vtbl( 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 u_resource *ur = u_resource(resource); - ur->vtbl->transfer_inline_write(pipe, - resource, - level, - usage, - box, - data, - stride, - layer_stride); + return size; } - - - - diff --git a/mesalib/src/gallium/auxiliary/util/u_resource.h b/mesalib/src/gallium/auxiliary/util/u_resource.h new file mode 100644 index 000000000..977e0136b --- /dev/null +++ b/mesalib/src/gallium/auxiliary/util/u_resource.h @@ -0,0 +1,34 @@ +/* + * Copyright 2013 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, 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 THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef U_RESOURCE_H +#define U_RESOURCE_H + +struct pipe_resource; + +unsigned +util_resource_size(const struct pipe_resource *res); + +#endif diff --git a/mesalib/src/gallium/auxiliary/util/u_transfer.c b/mesalib/src/gallium/auxiliary/util/u_transfer.c index 861682553..56e059bfd 100644 --- a/mesalib/src/gallium/auxiliary/util/u_transfer.c +++ b/mesalib/src/gallium/auxiliary/util/u_transfer.c @@ -87,3 +87,76 @@ void u_default_transfer_unmap( struct pipe_context *pipe, struct pipe_transfer *transfer ) { } + + +static INLINE struct u_resource * +u_resource( struct pipe_resource *res ) +{ + return (struct u_resource *)res; +} + +boolean u_resource_get_handle_vtbl(struct pipe_screen *screen, + struct pipe_resource *resource, + struct winsys_handle *handle) +{ + struct u_resource *ur = u_resource(resource); + return ur->vtbl->resource_get_handle(screen, resource, handle); +} + +void u_resource_destroy_vtbl(struct pipe_screen *screen, + struct pipe_resource *resource) +{ + struct u_resource *ur = u_resource(resource); + ur->vtbl->resource_destroy(screen, resource); +} + +void *u_transfer_map_vtbl(struct pipe_context *context, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box, + struct pipe_transfer **transfer) +{ + struct u_resource *ur = u_resource(resource); + return ur->vtbl->transfer_map(context, resource, level, usage, box, + transfer); +} + +void u_transfer_flush_region_vtbl( struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) +{ + struct u_resource *ur = u_resource(transfer->resource); + ur->vtbl->transfer_flush_region(pipe, transfer, box); +} + +void u_transfer_unmap_vtbl( struct pipe_context *pipe, + struct pipe_transfer *transfer ) +{ + struct u_resource *ur = u_resource(transfer->resource); + ur->vtbl->transfer_unmap(pipe, transfer); +} + +void u_transfer_inline_write_vtbl( 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 u_resource *ur = u_resource(resource); + ur->vtbl->transfer_inline_write(pipe, + resource, + level, + usage, + box, + data, + stride, + layer_stride); +} + + + + diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources index c294aa429..b5282a604 100644 --- a/mesalib/src/glsl/Makefile.sources +++ b/mesalib/src/glsl/Makefile.sources @@ -80,6 +80,7 @@ LIBGLSL_FILES = \ $(GLSL_SRCDIR)/opt_dead_code.cpp \ $(GLSL_SRCDIR)/opt_dead_code_local.cpp \ $(GLSL_SRCDIR)/opt_dead_functions.cpp \ + $(GLSL_SRCDIR)/opt_flatten_nested_if_blocks.cpp \ $(GLSL_SRCDIR)/opt_function_inlining.cpp \ $(GLSL_SRCDIR)/opt_if_simplification.cpp \ $(GLSL_SRCDIR)/opt_noop_swizzle.cpp \ diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index d6afe8814..00edbbfbd 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -1233,6 +1233,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api) if (extensions->ARB_texture_multisample) add_builtin_define(parser, "GL_ARB_texture_multisample", 1); + + if (extensions->ARB_texture_query_lod) + add_builtin_define(parser, "GL_ARB_texture_query_lod", 1); } } diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 56082f761..099229410 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -467,6 +467,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { EXT(ARB_texture_cube_map_array, true, false, true, true, false, ARB_texture_cube_map_array), EXT(ARB_shading_language_packing, true, false, true, true, false, ARB_shading_language_packing), EXT(ARB_texture_multisample, true, false, true, true, false, ARB_texture_multisample), + EXT(ARB_texture_query_lod, false, false, true, true, false, ARB_texture_query_lod), }; #undef EXT @@ -1217,6 +1218,7 @@ do_common_optimization(exec_list *ir, bool linked, progress = do_structure_splitting(ir) || progress; } progress = do_if_simplification(ir) || progress; + progress = opt_flatten_nested_if_blocks(ir) || progress; progress = do_copy_propagation(ir) || progress; progress = do_copy_propagation_elements(ir) || progress; if (linked) diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index 1765cdf16..95891b595 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -282,6 +282,8 @@ struct _mesa_glsl_parse_state { bool ARB_shading_language_packing_warn; bool ARB_texture_multisample_enable; bool ARB_texture_multisample_warn; + bool ARB_texture_query_lod_enable; + bool ARB_texture_query_lod_warn; /*@}*/ /** Extensions supported by the OpenGL implementation. */ diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index 8b0a24805..419761a7d 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -476,6 +476,8 @@ const glsl_type *glsl_type::get_scalar_type() const return int_type; case GLSL_TYPE_FLOAT: return float_type; + case GLSL_TYPE_BOOL: + return bool_type; default: /* Handle everything else */ return type; diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index 60ef8b95a..05b77da2c 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -1307,7 +1307,7 @@ ir_dereference::is_lvalue() const } -static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs" }; +static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs", "lod" }; const char *ir_texture::opcode_string() { @@ -1338,6 +1338,9 @@ ir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type) if (this->op == ir_txs) { assert(type->base_type == GLSL_TYPE_INT); + } else if (this->op == ir_lod) { + assert(type->vector_elements == 2); + assert(type->base_type == GLSL_TYPE_FLOAT); } else { assert(sampler->type->sampler_type == (int) type->base_type); if (sampler->type->sampler_shadow) diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index bbfec695f..0c3e39979 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -120,6 +120,7 @@ public: virtual class ir_dereference * as_dereference() { return NULL; } virtual class ir_dereference_array * as_dereference_array() { return NULL; } virtual class ir_dereference_variable *as_dereference_variable() { return NULL; } + virtual class ir_dereference_record *as_dereference_record() { return NULL; } virtual class ir_expression * as_expression() { return NULL; } virtual class ir_rvalue * as_rvalue() { return NULL; } virtual class ir_loop * as_loop() { return NULL; } @@ -1425,7 +1426,8 @@ enum ir_texture_opcode { ir_txd, /**< Texture look-up with partial derivatvies */ ir_txf, /**< Texel fetch with explicit LOD */ ir_txf_ms, /**< Multisample texture fetch */ - ir_txs /**< Texture size */ + ir_txs, /**< Texture size */ + ir_lod /**< Texture lod query */ }; @@ -1449,6 +1451,7 @@ enum ir_texture_opcode { * (txf_ms * ) * (txs ) + * (lod ) */ class ir_texture : public ir_rvalue { public: @@ -1738,6 +1741,11 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); + virtual ir_dereference_record *as_dereference_record() + { + return this; + } + /** * Get the variable that is ultimately referenced by an r-value */ diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp index 4797451d7..5b42935f8 100644 --- a/mesalib/src/glsl/ir_clone.cpp +++ b/mesalib/src/glsl/ir_clone.cpp @@ -243,6 +243,7 @@ ir_texture::clone(void *mem_ctx, struct hash_table *ht) const switch (this->op) { case ir_tex: + case ir_lod: break; case ir_txb: new_tex->lod_info.bias = this->lod_info.bias->clone(mem_ctx, ht); diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp index c2d0dc46c..c09e56a3d 100644 --- a/mesalib/src/glsl/ir_constant_expression.cpp +++ b/mesalib/src/glsl/ir_constant_expression.cpp @@ -1398,7 +1398,7 @@ ir_dereference_array::constant_referenced(struct hash_table *variable_context, return; } - const glsl_type *vt = substore->type; + const glsl_type *vt = array->type; if (vt->is_array()) { store = substore->get_array_element(index); offset = 0; diff --git a/mesalib/src/glsl/ir_hv_accept.cpp b/mesalib/src/glsl/ir_hv_accept.cpp index 5fa75011e..559b71af3 100644 --- a/mesalib/src/glsl/ir_hv_accept.cpp +++ b/mesalib/src/glsl/ir_hv_accept.cpp @@ -213,6 +213,7 @@ ir_texture::accept(ir_hierarchical_visitor *v) switch (this->op) { case ir_tex: + case ir_lod: break; case ir_txb: s = this->lod_info.bias->accept(v); diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h index 2454bbe6f..a8885d722 100644 --- a/mesalib/src/glsl/ir_optimization.h +++ b/mesalib/src/glsl/ir_optimization.h @@ -82,6 +82,7 @@ bool do_function_inlining(exec_list *instructions); bool do_lower_jumps(exec_list *instructions, bool pull_out_jumps = true, bool lower_sub_return = true, bool lower_main_return = false, bool lower_continue = false, bool lower_break = false); bool do_lower_texture_projection(exec_list *instructions); bool do_if_simplification(exec_list *instructions); +bool opt_flatten_nested_if_blocks(exec_list *instructions); bool do_discard_simplification(exec_list *instructions); bool lower_if_to_cond_assign(exec_list *instructions, unsigned max_depth = 0); bool do_mat_op_to_vec(exec_list *instructions); diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp index 3bdea9bbc..597d2813f 100644 --- a/mesalib/src/glsl/ir_print_visitor.cpp +++ b/mesalib/src/glsl/ir_print_visitor.cpp @@ -278,6 +278,7 @@ void ir_print_visitor::visit(ir_texture *ir) switch (ir->op) { case ir_tex: + case ir_lod: break; case ir_txb: ir->lod_info.bias->accept(this); diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp index 22ce03b0d..16fdc41b4 100644 --- a/mesalib/src/glsl/ir_reader.cpp +++ b/mesalib/src/glsl/ir_reader.cpp @@ -917,6 +917,8 @@ ir_reader::read_texture(s_expression *expr) s_pattern tex_pattern[] = { "tex", s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow }; + s_pattern lod_pattern[] = + { "lod", s_type, s_sampler, s_coord }; s_pattern txf_pattern[] = { "txf", s_type, s_sampler, s_coord, s_offset, s_lod }; s_pattern txf_ms_pattern[] = @@ -926,7 +928,9 @@ ir_reader::read_texture(s_expression *expr) s_pattern other_pattern[] = { tag, s_type, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod }; - if (MATCH(expr, tex_pattern)) { + if (MATCH(expr, lod_pattern)) { + op = ir_lod; + } else if (MATCH(expr, tex_pattern)) { op = ir_tex; } else if (MATCH(expr, txf_pattern)) { op = ir_txf; @@ -939,7 +943,7 @@ ir_reader::read_texture(s_expression *expr) if (op == -1) return NULL; } else { - ir_read_error(NULL, "unexpected texture pattern"); + ir_read_error(NULL, "unexpected texture pattern %s", tag->value()); return NULL; } @@ -971,7 +975,7 @@ ir_reader::read_texture(s_expression *expr) return NULL; } - if (op != ir_txf_ms) { + if (op != ir_txf_ms && op != ir_lod) { // Read texel offset - either 0 or an rvalue. s_int *si_offset = SX_AS_INT(s_offset); if (si_offset == NULL || si_offset->value() != 0) { @@ -984,7 +988,7 @@ ir_reader::read_texture(s_expression *expr) } } - if (op != ir_txf && op != ir_txf_ms && op != ir_txs) { + if (op != ir_txf && op != ir_txf_ms && op != ir_txs && op != ir_lod) { s_int *proj_as_int = SX_AS_INT(s_proj); if (proj_as_int && proj_as_int->value() == 1) { tex->projector = NULL; @@ -1054,7 +1058,7 @@ ir_reader::read_texture(s_expression *expr) break; } default: - // tex doesn't have any extra parameters. + // tex and lod don't have any extra parameters. break; }; return tex; diff --git a/mesalib/src/glsl/ir_rvalue_visitor.cpp b/mesalib/src/glsl/ir_rvalue_visitor.cpp index 543c54496..3504a4dda 100644 --- a/mesalib/src/glsl/ir_rvalue_visitor.cpp +++ b/mesalib/src/glsl/ir_rvalue_visitor.cpp @@ -57,6 +57,7 @@ ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir) switch (ir->op) { case ir_tex: + case ir_lod: break; case ir_txb: handle_rvalue(&ir->lod_info.bias); diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp index 24ea506dc..699c192cd 100644 --- a/mesalib/src/glsl/ir_validate.cpp +++ b/mesalib/src/glsl/ir_validate.cpp @@ -701,6 +701,11 @@ check_node_type(ir_instruction *ir, void *data) void validate_ir_tree(exec_list *instructions) { + /* We shouldn't have any reason to validate IR in a release build, + * and it's half composed of assert()s anyway which wouldn't do + * anything. + */ +#ifdef DEBUG ir_validate v; v.run(instructions); @@ -710,4 +715,5 @@ validate_ir_tree(exec_list *instructions) visit_tree(ir, check_node_type, NULL); } +#endif } diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 29856b080..2b30d2b65 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -1067,13 +1067,11 @@ link_intrastage_shaders(void *mem_ctx, free(linking_shaders); -#ifdef DEBUG /* At this point linked should contain all of the linked IR, so * validate it to make sure nothing went wrong. */ if (linked) validate_ir_tree(linked->ir); -#endif /* Make a pass over all variable declarations to ensure that arrays with * unspecified sizes have a size specified. The size is inferred from the diff --git a/mesalib/src/glsl/lower_jumps.cpp b/mesalib/src/glsl/lower_jumps.cpp index 92813f567..bfc8c013b 100644 --- a/mesalib/src/glsl/lower_jumps.cpp +++ b/mesalib/src/glsl/lower_jumps.cpp @@ -1002,10 +1002,12 @@ do_lower_jumps(exec_list *instructions, bool pull_out_jumps, bool lower_sub_retu v.lower_sub_return = lower_sub_return; v.lower_main_return = lower_main_return; + bool progress_ever = false; do { v.progress = false; visit_exec_list(instructions, &v); + progress_ever = v.progress || progress_ever; } while (v.progress); - return v.progress; + return progress_ever; } diff --git a/mesalib/src/glsl/lower_ubo_reference.cpp b/mesalib/src/glsl/lower_ubo_reference.cpp index 026197df7..aade203e7 100644 --- a/mesalib/src/glsl/lower_ubo_reference.cpp +++ b/mesalib/src/glsl/lower_ubo_reference.cpp @@ -356,18 +356,14 @@ lower_ubo_reference_visitor::emit_ubo_loads(ir_dereference *deref, unsigned matrix_stride = 16; for (unsigned i = 0; i < deref->type->vector_elements; i++) { - ir_rvalue *chan = new(mem_ctx) ir_constant((int)i); - ir_dereference *deref_chan = - new(mem_ctx) ir_dereference_array(deref->clone(mem_ctx, NULL), - chan); - ir_rvalue *chan_offset = add(base_offset, new(mem_ctx) ir_constant(deref_offset + i * matrix_stride)); - base_ir->insert_before(assign(deref_chan, + base_ir->insert_before(assign(deref->clone(mem_ctx, NULL), ubo_load(glsl_type::float_type, - chan_offset))); + chan_offset), + (1U << i))); } } } diff --git a/mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp b/mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp new file mode 100644 index 000000000..c70210204 --- /dev/null +++ b/mesalib/src/glsl/opt_flatten_nested_if_blocks.cpp @@ -0,0 +1,103 @@ +/* + * Copyright © 2013 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. + */ + +/** + * \file opt_flatten_nested_if_blocks.cpp + * + * Flattens nested if blocks such as: + * + * if (x) { + * if (y) { + * ... + * } + * } + * + * into a single if block with a combined condition: + * + * if (x && y) { + * ... + * } + */ + +#include "ir.h" +#include "ir_builder.h" + +using namespace ir_builder; + +namespace { + +class nested_if_flattener : public ir_hierarchical_visitor { +public: + nested_if_flattener() + { + progress = false; + } + + ir_visitor_status visit_leave(ir_if *); + ir_visitor_status visit_enter(ir_assignment *); + + bool progress; +}; + +} /* unnamed namespace */ + +/* We only care about the top level "if" instructions, so don't + * descend into expressions. + */ +ir_visitor_status +nested_if_flattener::visit_enter(ir_assignment *ir) +{ + (void) ir; + return visit_continue_with_parent; +} + +bool +opt_flatten_nested_if_blocks(exec_list *instructions) +{ + nested_if_flattener v; + + v.run(instructions); + return v.progress; +} + + +ir_visitor_status +nested_if_flattener::visit_leave(ir_if *ir) +{ + /* Only handle a single ir_if within the then clause of an ir_if. No extra + * instructions, no else clauses, nothing. + */ + if (ir->then_instructions.is_empty() || !ir->else_instructions.is_empty()) + return visit_continue; + + ir_if *inner = ((ir_instruction *) ir->then_instructions.head)->as_if(); + if (!inner || !inner->next->is_tail_sentinel() || + !inner->else_instructions.is_empty()) + return visit_continue; + + ir->condition = logic_and(ir->condition, inner->condition); + inner->then_instructions.move_nodes_to(&ir->then_instructions); + + progress = true; + return visit_continue; +} diff --git a/mesalib/src/glsl/opt_tree_grafting.cpp b/mesalib/src/glsl/opt_tree_grafting.cpp index 985540196..9aceb134d 100644 --- a/mesalib/src/glsl/opt_tree_grafting.cpp +++ b/mesalib/src/glsl/opt_tree_grafting.cpp @@ -274,6 +274,7 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir) switch (ir->op) { case ir_tex: + case ir_lod: break; case ir_txb: if (do_graft(&ir->lod_info.bias)) diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp index b5ef768bd..0c1f52f48 100644 --- a/mesalib/src/glsl/standalone_scaffolding.cpp +++ b/mesalib/src/glsl/standalone_scaffolding.cpp @@ -103,6 +103,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api) ctx->Extensions.OES_standard_derivatives = true; ctx->Extensions.ARB_texture_cube_map_array = true; ctx->Extensions.ARB_texture_multisample = true; + ctx->Extensions.ARB_texture_query_lod = true; ctx->Const.GLSLVersion = 120; diff --git a/mesalib/src/mapi/glapi/gen/ARB_texture_storage_multisample.xml b/mesalib/src/mapi/glapi/gen/ARB_texture_storage_multisample.xml new file mode 100644 index 000000000..0f9d323d4 --- /dev/null +++ b/mesalib/src/mapi/glapi/gen/ARB_texture_storage_multisample.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mesalib/src/mapi/glapi/gen/gl_API.xml b/mesalib/src/mapi/glapi/gen/gl_API.xml index 75957dc7d..df9592477 100644 --- a/mesalib/src/mapi/glapi/gen/gl_API.xml +++ b/mesalib/src/mapi/glapi/gen/gl_API.xml @@ -8321,6 +8321,10 @@ + + + + diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.c b/mesalib/src/mesa/drivers/common/driverfuncs.c index 731d46658..a98dfc607 100644 --- a/mesalib/src/mesa/drivers/common/driverfuncs.c +++ b/mesalib/src/mesa/drivers/common/driverfuncs.c @@ -28,6 +28,7 @@ #include "main/accum.h" #include "main/arrayobj.h" #include "main/context.h" +#include "main/formatquery.h" #include "main/framebuffer.h" #include "main/mipmap.h" #include "main/queryobj.h" @@ -90,7 +91,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver) /* Texture functions */ driver->ChooseTextureFormat = _mesa_choose_tex_format; - driver->QuerySamplesForFormat = NULL; + driver->QuerySamplesForFormat = _mesa_query_samples_for_format; driver->TexImage = _mesa_store_teximage; driver->TexSubImage = _mesa_store_texsubimage; driver->GetTexImage = _mesa_meta_GetTexImage; diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index 8114550ba..e3ab82bfe 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -757,7 +757,8 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state) * it's for the pixel path (ClampFragmentColor is GL_TRUE), * regardless of the internal implementation of the metaops. */ - if (ctx->Color.ClampFragmentColor != GL_TRUE) + if (ctx->Color.ClampFragmentColor != GL_TRUE && + ctx->Extensions.ARB_color_buffer_float) _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); } @@ -767,7 +768,8 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state) /* Generally in here we never want vertex color clamping -- * result clamping is only dependent on fragment clamping. */ - _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE); + if (ctx->Extensions.ARB_color_buffer_float) + _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE); } if (state & MESA_META_CONDITIONAL_RENDER) { @@ -1091,11 +1093,13 @@ _mesa_meta_end(struct gl_context *ctx) _mesa_DepthRange(save->DepthNear, save->DepthFar); } - if (state & MESA_META_CLAMP_FRAGMENT_COLOR) { + if (state & MESA_META_CLAMP_FRAGMENT_COLOR && + ctx->Extensions.ARB_color_buffer_float) { _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, save->ClampFragmentColor); } - if (state & MESA_META_CLAMP_VERTEX_COLOR) { + if (state & MESA_META_CLAMP_VERTEX_COLOR && + ctx->Extensions.ARB_color_buffer_float) { _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR, save->ClampVertexColor); } @@ -2044,7 +2048,8 @@ _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers) /* leave colormask, glDrawBuffer state as-is */ /* Clears never have the color clamped. */ - _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); + if (ctx->Extensions.ARB_color_buffer_float) + _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); } else { ASSERT(metaSave & MESA_META_COLOR_MASK); @@ -2295,7 +2300,8 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers) /* leave colormask, glDrawBuffer state as-is */ /* Clears never have the color clamped. */ - _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); + if (ctx->Extensions.ARB_color_buffer_float) + _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); } else { ASSERT(metaSave & MESA_META_COLOR_MASK); diff --git a/mesalib/src/mesa/drivers/dri/common/Android.mk b/mesalib/src/mesa/drivers/dri/common/Android.mk index f428c3855..b3dac29dd 100644 --- a/mesalib/src/mesa/drivers/dri/common/Android.mk +++ b/mesalib/src/mesa/drivers/dri/common/Android.mk @@ -77,7 +77,8 @@ $(intermediates)/xmlpool/options.h: PRIVATE_SCRIPT := $(LOCAL_PATH)/xmlpool/gen_ $(intermediates)/xmlpool/options.h: PRIVATE_LOCALEDIR := $(intermediates)/xmlpool $(intermediates)/xmlpool/options.h: PRIVATE_TEMPLATE_HEADER := $(LOCAL_PATH)/xmlpool/t_options.h $(intermediates)/xmlpool/options.h: PRIVATE_MO_FILES := $(MESA_DRI_OPTIONS_LANGS:%=$(intermediates)/xmlpool/%/LC_MESSAGES/options.mo) -$(intermediates)/xmlpool/options.h: $(PRIVATE_SCRIPT) $(PRIVATE_TEMPLATE_HEADER) $(PRIVATE_MO_FILES) +.SECONDEXPANSION: +$(intermediates)/xmlpool/options.h: $$(PRIVATE_SCRIPT) $$(PRIVATE_TEMPLATE_HEADER) $$(PRIVATE_MO_FILES) mkdir -p $(dir $@) mkdir -p $(PRIVATE_LOCALEDIR) $(MESA_PYTHON2) $(PRIVATE_SCRIPT) $(PRIVATE_TEMPLATE_HEADER) \ diff --git a/mesalib/src/mesa/drivers/dri/common/drirc b/mesalib/src/mesa/drivers/dri/common/drirc index a13941f68..556d1b599 100644 --- a/mesalib/src/mesa/drivers/dri/common/drirc +++ b/mesalib/src/mesa/drivers/dri/common/drirc @@ -25,5 +25,11 @@ + + + + diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c index 3b991bcac..a672845bf 100644 --- a/mesalib/src/mesa/main/attrib.c +++ b/mesalib/src/mesa/main/attrib.c @@ -986,7 +986,9 @@ _mesa_PopAttrib(void) _mesa_set_enable(ctx, GL_INDEX_LOGIC_OP, color->IndexLogicOpEnabled); _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag); - _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, color->ClampFragmentColor); + if (ctx->Extensions.ARB_color_buffer_float) + _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, + color->ClampFragmentColor); _mesa_ClampColor(GL_CLAMP_READ_COLOR_ARB, color->ClampReadColor); /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ @@ -1114,7 +1116,10 @@ _mesa_PopAttrib(void) /* materials */ memcpy(&ctx->Light.Material, &light->Material, sizeof(struct gl_material)); - _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR_ARB, light->ClampVertexColor); + if (ctx->Extensions.ARB_color_buffer_float) { + _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR_ARB, + light->ClampVertexColor); + } } break; case GL_LINE_BIT: diff --git a/mesalib/src/mesa/main/blend.c b/mesalib/src/mesa/main/blend.c index 309f1d538..09a1c9ae8 100644 --- a/mesalib/src/mesa/main/blend.c +++ b/mesalib/src/mesa/main/blend.c @@ -765,24 +765,96 @@ _mesa_ClampColor(GLenum target, GLenum clamp) switch (target) { case GL_CLAMP_VERTEX_COLOR_ARB: + if (ctx->API == API_OPENGL_CORE && + !ctx->Extensions.ARB_color_buffer_float) { + goto invalid_enum; + } FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.ClampVertexColor = clamp; + _mesa_update_clamp_vertex_color(ctx); break; case GL_CLAMP_FRAGMENT_COLOR_ARB: + if (ctx->API == API_OPENGL_CORE && + !ctx->Extensions.ARB_color_buffer_float) { + goto invalid_enum; + } FLUSH_VERTICES(ctx, _NEW_FRAG_CLAMP); ctx->Color.ClampFragmentColor = clamp; + _mesa_update_clamp_fragment_color(ctx); break; case GL_CLAMP_READ_COLOR_ARB: FLUSH_VERTICES(ctx, _NEW_COLOR); ctx->Color.ClampReadColor = clamp; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(target)"); - return; + goto invalid_enum; } + return; + +invalid_enum: + _mesa_error(ctx, GL_INVALID_ENUM, "glClampColor(%s)", + _mesa_lookup_enum_by_nr(target)); +} + +static GLboolean +get_clamp_color(const struct gl_framebuffer *fb, GLenum clamp) +{ + if (clamp == GL_TRUE || clamp == GL_FALSE) + return clamp; + + ASSERT(clamp == GL_FIXED_ONLY); + if (!fb) + return GL_TRUE; + + return fb->_AllColorBuffersFixedPoint; +} + +GLboolean +_mesa_get_clamp_fragment_color(const struct gl_context *ctx) +{ + return get_clamp_color(ctx->DrawBuffer, + ctx->Color.ClampFragmentColor); +} + +GLboolean +_mesa_get_clamp_vertex_color(const struct gl_context *ctx) +{ + return get_clamp_color(ctx->DrawBuffer, ctx->Light.ClampVertexColor); +} + +GLboolean +_mesa_get_clamp_read_color(const struct gl_context *ctx) +{ + return get_clamp_color(ctx->ReadBuffer, ctx->Color.ClampReadColor); } +/** + * Update the ctx->Color._ClampFragmentColor field + */ +void +_mesa_update_clamp_fragment_color(struct gl_context *ctx) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + /* Don't clamp if: + * - there is no colorbuffer + * - all colorbuffers are unsigned normalized, so clamping has no effect + * - there is an integer colorbuffer + */ + if (!fb || !fb->_HasSNormOrFloatColorBuffer || fb->_IntegerColor) + ctx->Color._ClampFragmentColor = GL_FALSE; + else + ctx->Color._ClampFragmentColor = _mesa_get_clamp_fragment_color(ctx); +} + +/** + * Update the ctx->Color._ClampVertexColor field + */ +void +_mesa_update_clamp_vertex_color(struct gl_context *ctx) +{ + ctx->Light._ClampVertexColor = _mesa_get_clamp_vertex_color(ctx); +} /**********************************************************************/ @@ -832,10 +904,10 @@ void _mesa_init_color( struct gl_context * ctx ) ctx->Color.DrawBuffer[0] = GL_FRONT; } - ctx->Color.ClampFragmentColor = GL_FIXED_ONLY_ARB; - ctx->Color._ClampFragmentColor = GL_TRUE; + ctx->Color.ClampFragmentColor = ctx->API == API_OPENGL_COMPAT ? + GL_FIXED_ONLY_ARB : GL_FALSE; + ctx->Color._ClampFragmentColor = GL_FALSE; ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB; - ctx->Color._ClampReadColor = GL_TRUE; if (ctx->API == API_OPENGLES2) { /* GLES 3 behaves as though GL_FRAMEBUFFER_SRGB is always enabled. */ diff --git a/mesalib/src/mesa/main/blend.h b/mesalib/src/mesa/main/blend.h index a539aa809..621311d55 100644 --- a/mesalib/src/mesa/main/blend.h +++ b/mesalib/src/mesa/main/blend.h @@ -99,6 +99,20 @@ _mesa_ColorMaski( GLuint buf, GLboolean red, GLboolean green, extern void GLAPIENTRY _mesa_ClampColor(GLenum target, GLenum clamp); +extern GLboolean +_mesa_get_clamp_fragment_color(const struct gl_context *ctx); + +extern GLboolean +_mesa_get_clamp_vertex_color(const struct gl_context *ctx); + +extern GLboolean +_mesa_get_clamp_read_color(const struct gl_context *ctx); + +extern void +_mesa_update_clamp_fragment_color(struct gl_context *ctx); + +extern void +_mesa_update_clamp_vertex_color(struct gl_context *ctx); extern void _mesa_init_color( struct gl_context * ctx ); diff --git a/mesalib/src/mesa/main/compiler.h b/mesalib/src/mesa/main/compiler.h index 8b23665e6..8431534c3 100644 --- a/mesalib/src/mesa/main/compiler.h +++ b/mesalib/src/mesa/main/compiler.h @@ -256,7 +256,7 @@ static INLINE GLuint CPU_TO_LE32(GLuint x) */ #define STATIC_ASSERT(COND) \ do { \ - typedef int static_assertion_failed[(!!(COND))*2-1]; \ + (void) sizeof(char [1 - 2*!(COND)]); \ } while (0) diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index e90a29680..c7f038b88 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -144,10 +144,12 @@ static const struct extension extension_table[] = { { "GL_ARB_texture_mirrored_repeat", o(dummy_true), GLL, 2001 }, { "GL_ARB_texture_multisample", o(ARB_texture_multisample), GL, 2009 }, { "GL_ARB_texture_non_power_of_two", o(ARB_texture_non_power_of_two), GL, 2003 }, + { "GL_ARB_texture_query_lod", o(ARB_texture_query_lod), GL, 2009 }, { "GL_ARB_texture_rectangle", o(NV_texture_rectangle), GL, 2004 }, { "GL_ARB_texture_rgb10_a2ui", o(ARB_texture_rgb10_a2ui), GL, 2009 }, { "GL_ARB_texture_rg", o(ARB_texture_rg), GL, 2008 }, { "GL_ARB_texture_storage", o(ARB_texture_storage), GL, 2011 }, + { "GL_ARB_texture_storage_multisample", o(ARB_texture_storage_multisample), GL, 2012 }, { "GL_ARB_texture_swizzle", o(EXT_texture_swizzle), GL, 2008 }, { "GL_ARB_timer_query", o(ARB_timer_query), GL, 2010 }, { "GL_ARB_transform_feedback2", o(ARB_transform_feedback2), GL, 2010 }, diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 3fdf62667..fc2b2620b 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -784,6 +784,8 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, numImages = 0; fb->Width = 0; fb->Height = 0; + fb->_AllColorBuffersFixedPoint = GL_TRUE; + fb->_HasSNormOrFloatColorBuffer = GL_FALSE; /* Start at -2 to more easily loop over all attachment points. * -2: depth buffer @@ -900,6 +902,19 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, /* check if integer color */ fb->_IntegerColor = _mesa_is_format_integer_color(attFormat); + /* Update _AllColorBuffersFixedPoint and _HasSNormOrFloatColorBuffer. */ + if (i >= 0) { + GLenum type = _mesa_get_format_datatype(attFormat); + + fb->_AllColorBuffersFixedPoint = + fb->_AllColorBuffersFixedPoint && + (type == GL_UNSIGNED_NORMALIZED || type == GL_SIGNED_NORMALIZED); + + fb->_HasSNormOrFloatColorBuffer = + fb->_HasSNormOrFloatColorBuffer || + type == GL_SIGNED_NORMALIZED || type == GL_FLOAT; + } + /* Error-check width, height, format */ if (numImages == 1) { /* save format */ @@ -1537,15 +1552,16 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, /* NumSamples == 0 indicates non-multisampling */ samples = 0; } - - /* check the sample count; - * note: driver may choose to use more samples than what's requested - */ - sample_count_error = _mesa_check_sample_count(ctx, target, - internalFormat, samples); - if (sample_count_error != GL_NO_ERROR) { - _mesa_error(ctx, sample_count_error, "%s(samples)", func); - return; + else { + /* check the sample count; + * note: driver may choose to use more samples than what's requested + */ + sample_count_error = _mesa_check_sample_count(ctx, target, + internalFormat, samples); + if (sample_count_error != GL_NO_ERROR) { + _mesa_error(ctx, sample_count_error, "%s(samples)", func); + return; + } } rb = ctx->CurrentRenderbuffer; diff --git a/mesalib/src/mesa/main/formatquery.c b/mesalib/src/mesa/main/formatquery.c index 78c5fbe5e..e45dc8680 100644 --- a/mesalib/src/mesa/main/formatquery.c +++ b/mesalib/src/mesa/main/formatquery.c @@ -30,6 +30,21 @@ #include "fbobject.h" #include "formatquery.h" +/* default implementation of QuerySamplesForFormat driverfunc, for + * non-multisample-capable drivers. */ +size_t +_mesa_query_samples_for_format(struct gl_context *ctx, GLenum target, + GLenum internalFormat, int samples[16]) +{ + (void) target; + (void) internalFormat; + (void) ctx; + + samples[0] = 1; + return 1; +} + + void GLAPIENTRY _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) diff --git a/mesalib/src/mesa/main/formatquery.h b/mesalib/src/mesa/main/formatquery.h index 585c3eb64..603400059 100644 --- a/mesalib/src/mesa/main/formatquery.h +++ b/mesalib/src/mesa/main/formatquery.h @@ -28,6 +28,10 @@ #include "compiler.h" #include "glheader.h" +size_t +_mesa_query_samples_for_format(struct gl_context *ctx, GLenum target, + GLenum internalFormat, int samples[16]); + extern void GLAPIENTRY _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); diff --git a/mesalib/src/mesa/main/framebuffer.c b/mesalib/src/mesa/main/framebuffer.c index 619aaa337..6c6977431 100644 --- a/mesalib/src/mesa/main/framebuffer.c +++ b/mesalib/src/mesa/main/framebuffer.c @@ -32,6 +32,7 @@ #include "glheader.h" #include "imports.h" +#include "blend.h" #include "buffers.h" #include "context.h" #include "enums.h" @@ -154,6 +155,8 @@ _mesa_initialize_window_framebuffer(struct gl_framebuffer *fb, fb->Delete = _mesa_destroy_framebuffer; fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT; + fb->_AllColorBuffersFixedPoint = !visual->floatMode; + fb->_HasSNormOrFloatColorBuffer = visual->floatMode; compute_depth_max(fb); } @@ -740,6 +743,9 @@ _mesa_update_framebuffer(struct gl_context *ctx) update_framebuffer(ctx, drawFb); if (readFb != drawFb) update_framebuffer(ctx, readFb); + + _mesa_update_clamp_vertex_color(ctx); + _mesa_update_clamp_fragment_color(ctx); } diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index 582ef3198..2ba868c0d 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -24,6 +24,7 @@ #include "glheader.h" #include "context.h" +#include "blend.h" #include "enable.h" #include "enums.h" #include "extensions.h" @@ -357,6 +358,13 @@ EXTRA_EXT(ARB_texture_cube_map_array); EXTRA_EXT(ARB_texture_buffer_range); EXTRA_EXT(ARB_texture_multisample); +static const int +extra_ARB_color_buffer_float_or_glcore[] = { + EXT(ARB_color_buffer_float), + EXTRA_API_GL_CORE, + EXTRA_END +}; + static const int extra_NV_primitive_restart[] = { EXT(NV_primitive_restart), @@ -767,13 +775,13 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu break; case GL_FOG_COLOR: - if(ctx->Color._ClampFragmentColor) + if (_mesa_get_clamp_fragment_color(ctx)) COPY_4FV(v->value_float_4, ctx->Fog.Color); else COPY_4FV(v->value_float_4, ctx->Fog.ColorUnclamped); break; case GL_COLOR_CLEAR_VALUE: - if(ctx->Color._ClampFragmentColor) { + if (_mesa_get_clamp_fragment_color(ctx)) { v->value_float_4[0] = CLAMP(ctx->Color.ClearColor.f[0], 0.0F, 1.0F); v->value_float_4[1] = CLAMP(ctx->Color.ClearColor.f[1], 0.0F, 1.0F); v->value_float_4[2] = CLAMP(ctx->Color.ClearColor.f[2], 0.0F, 1.0F); @@ -782,13 +790,13 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu COPY_4FV(v->value_float_4, ctx->Color.ClearColor.f); break; case GL_BLEND_COLOR_EXT: - if(ctx->Color._ClampFragmentColor) + if (_mesa_get_clamp_fragment_color(ctx)) COPY_4FV(v->value_float_4, ctx->Color.BlendColor); else COPY_4FV(v->value_float_4, ctx->Color.BlendColorUnclamped); break; case GL_ALPHA_TEST_REF: - if(ctx->Color._ClampFragmentColor) + if (_mesa_get_clamp_fragment_color(ctx)) v->value_float = ctx->Color.AlphaRef; else v->value_float = ctx->Color.AlphaRefUnclamped; @@ -868,7 +876,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu * \param func name of calling glGet*v() function for error reporting * \param d the struct value_desc that has the extra constraints * - * \return GL_FALSE if one of the constraints was not satisfied, + * \return GL_FALSE if all of the constraints were not satisfied, * otherwise GL_TRUE. */ static GLboolean diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py index 7d4f7e2a4..4ef23247b 100644 --- a/mesalib/src/mesa/main/get_hash_params.py +++ b/mesalib/src/mesa/main/get_hash_params.py @@ -96,7 +96,7 @@ descriptor=[ # GL_ARB_color_buffer_float [ "CLAMP_VERTEX_COLOR", "CONTEXT_ENUM(Light.ClampVertexColor), extra_ARB_color_buffer_float" ], [ "CLAMP_FRAGMENT_COLOR", "CONTEXT_ENUM(Color.ClampFragmentColor), extra_ARB_color_buffer_float" ], - [ "CLAMP_READ_COLOR", "CONTEXT_ENUM(Color.ClampReadColor), extra_ARB_color_buffer_float" ], + [ "CLAMP_READ_COLOR", "CONTEXT_ENUM(Color.ClampReadColor), extra_ARB_color_buffer_float_or_glcore" ], # GL_ARB_copy_buffer [ "COPY_READ_BUFFER", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ], diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h index 4b783818b..c4110ef10 100644 --- a/mesalib/src/mesa/main/imports.h +++ b/mesalib/src/mesa/main/imports.h @@ -500,17 +500,11 @@ _mesa_realloc( void *oldBuffer, size_t oldSize, size_t newSize ); #ifndef FFS_DEFINED #define FFS_DEFINED 1 #ifdef __GNUC__ - -#if defined(__MINGW32__) || defined(__CYGWIN__) || defined(ANDROID) || defined(__APPLE__) #define ffs __builtin_ffs #define ffsll __builtin_ffsll -#endif - #else - extern int ffs(int i); extern int ffsll(long long int i); - #endif /*__ GNUC__ */ #endif /* FFS_DEFINED */ diff --git a/mesalib/src/mesa/main/light.c b/mesalib/src/mesa/main/light.c index 3c43ec766..c694bebe6 100644 --- a/mesalib/src/mesa/main/light.c +++ b/mesalib/src/mesa/main/light.c @@ -1202,7 +1202,8 @@ _mesa_init_lighting( struct gl_context *ctx ) NULL ); ctx->Light.ColorMaterialEnabled = GL_FALSE; - ctx->Light.ClampVertexColor = GL_TRUE; + ctx->Light.ClampVertexColor = ctx->API == API_OPENGL_COMPAT; + ctx->Light._ClampVertexColor = ctx->API == API_OPENGL_COMPAT; /* Miscellaneous */ ctx->Light._NeedEyeCoords = GL_FALSE; diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index a0e7e281d..008f68bda 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -146,9 +146,6 @@ typedef enum * VERT_ATTRIB_TEX * include the classic texture coordinate attributes. * Is a subset of VERT_ATTRIB_FF. - * VERT_ATTRIB_GENERIC_NV - * include the NV shader attributes. - * Is a subset of VERT_ATTRIB_FF. * VERT_ATTRIB_GENERIC * include the OpenGL 2.0+ GLSL generic shader attributes. * These alias the generic GL_ARB_vertex_shader attributes. @@ -159,9 +156,6 @@ typedef enum #define VERT_ATTRIB_TEX(i) (VERT_ATTRIB_TEX0 + (i)) #define VERT_ATTRIB_TEX_MAX MAX_TEXTURE_COORD_UNITS -#define VERT_ATTRIB_GENERIC_NV(i) (VERT_ATTRIB_POS + (i)) -#define VERT_ATTRIB_GENERIC_NV_MAX MAX_VERTEX_GENERIC_ATTRIBS - #define VERT_ATTRIB_GENERIC(i) (VERT_ATTRIB_GENERIC0 + (i)) #define VERT_ATTRIB_GENERIC_MAX MAX_VERTEX_GENERIC_ATTRIBS @@ -198,10 +192,6 @@ typedef enum #define VERT_BIT_TEX_ALL \ BITFIELD64_RANGE(VERT_ATTRIB_TEX(0), VERT_ATTRIB_TEX_MAX) -#define VERT_BIT_GENERIC_NV(i) VERT_BIT(VERT_ATTRIB_GENERIC_NV(i)) -#define VERT_BIT_GENERIC_NV_ALL \ - BITFIELD64_RANGE(VERT_ATTRIB_GENERIC_NV(0), VERT_ATTRIB_GENERIC_NV_MAX) - #define VERT_BIT_GENERIC(i) VERT_BIT(VERT_ATTRIB_GENERIC(i)) #define VERT_BIT_GENERIC_ALL \ BITFIELD64_RANGE(VERT_ATTRIB_GENERIC(0), VERT_ATTRIB_GENERIC_MAX) @@ -683,7 +673,6 @@ struct gl_colorbuffer_attrib GLenum ClampFragmentColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */ GLboolean _ClampFragmentColor; /** < with GL_FIXED_ONLY_ARB resolved */ GLenum ClampReadColor; /**< GL_TRUE, GL_FALSE or GL_FIXED_ONLY_ARB */ - GLboolean _ClampReadColor; /** < with GL_FIXED_ONLY_ARB resolved */ GLboolean sRGBEnabled; /**< Framebuffer sRGB blending/updating requested */ }; @@ -1025,6 +1014,7 @@ struct gl_stencil_attrib GLboolean TestTwoSide; /**< GL_EXT_stencil_two_side */ GLubyte ActiveFace; /**< GL_EXT_stencil_two_side (0 or 2) */ GLboolean _Enabled; /**< Enabled and stencil buffer present */ + GLboolean _WriteEnabled; /**< _Enabled and non-zero writemasks */ GLboolean _TestTwoSide; GLubyte _BackFace; /**< Current back stencil state (1 or 2) */ GLenum Function[3]; /**< Stencil function */ @@ -2670,6 +2660,10 @@ struct gl_framebuffer /** Integer color values */ GLboolean _IntegerColor; + /* ARB_color_buffer_float */ + GLboolean _AllColorBuffersFixedPoint; /* no integer, no float */ + GLboolean _HasSNormOrFloatColorBuffer; + /** Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */ struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT]; @@ -3002,9 +2996,11 @@ struct gl_extensions GLboolean ARB_texture_float; GLboolean ARB_texture_multisample; GLboolean ARB_texture_non_power_of_two; + GLboolean ARB_texture_query_lod; GLboolean ARB_texture_rg; GLboolean ARB_texture_rgb10_a2ui; GLboolean ARB_texture_storage; + GLboolean ARB_texture_storage_multisample; GLboolean ARB_timer_query; GLboolean ARB_transform_feedback2; GLboolean ARB_transform_feedback3; diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c index d3d09dea3..0dee38063 100644 --- a/mesalib/src/mesa/main/readpix.c +++ b/mesalib/src/mesa/main/readpix.c @@ -24,6 +24,7 @@ #include "glheader.h" #include "imports.h" +#include "blend.h" #include "bufferobj.h" #include "context.h" #include "enums.h" @@ -80,7 +81,7 @@ get_readpixels_transfer_ops(const struct gl_context *ctx, gl_format texFormat, if (uses_blit) { /* For blit-based ReadPixels packing, the clamping is done automatically * unless the type is float. */ - if (ctx->Color._ClampReadColor == GL_TRUE && + if (_mesa_get_clamp_read_color(ctx) && (type == GL_FLOAT || type == GL_HALF_FLOAT)) { transferOps |= IMAGE_CLAMP_BIT; } @@ -88,7 +89,7 @@ get_readpixels_transfer_ops(const struct gl_context *ctx, gl_format texFormat, else { /* For CPU-based ReadPixels packing, the clamping must always be done * for non-float types, */ - if (ctx->Color._ClampReadColor == GL_TRUE || + if (_mesa_get_clamp_read_color(ctx) || (type != GL_FLOAT && type != GL_HALF_FLOAT)) { transferOps |= IMAGE_CLAMP_BIT; } diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index be6946798..2c307e79c 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -518,9 +518,11 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param GLint max_len = 0; for (i = 0; i < shProg->NumUserUniformStorage; i++) { - /* Add one for the terminating NUL character. + /* Add one for the terminating NUL character for a non-array, and + * 4 for the "[0]" and the NUL for an array. */ - const GLint len = strlen(shProg->UniformStorage[i].name) + 1; + const GLint len = strlen(shProg->UniformStorage[i].name) + 1 + + ((shProg->UniformStorage[i].array_elements != 0) ? 3 : 0); if (len > max_len) max_len = len; diff --git a/mesalib/src/mesa/main/state.c b/mesalib/src/mesa/main/state.c index fb8b71cfe..251c1aea9 100644 --- a/mesalib/src/mesa/main/state.c +++ b/mesalib/src/mesa/main/state.c @@ -51,6 +51,7 @@ #include "texobj.h" #include "texstate.h" #include "varray.h" +#include "blend.h" static void @@ -307,47 +308,6 @@ update_multisample(struct gl_context *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; - 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; - 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; - else - ctx->Color._ClampReadColor = ctx->Color.ClampReadColor; -} - /** * Update the ctx->VertexProgram._TwoSideEnabled flag. */ @@ -507,9 +467,6 @@ _mesa_update_state_locked( struct gl_context *ctx ) if (new_state & (_NEW_LIGHT | _NEW_PROGRAM)) update_twoside( ctx ); - if (new_state & (_NEW_LIGHT | _NEW_BUFFERS)) - update_clamp_vertex_color(ctx); - if (new_state & (_NEW_STENCIL | _NEW_BUFFERS)) _mesa_update_stencil( ctx ); @@ -525,12 +482,6 @@ _mesa_update_state_locked( struct gl_context *ctx ) if (new_state & (_NEW_MULTISAMPLE | _NEW_BUFFERS)) update_multisample( ctx ); - if (new_state & (_NEW_COLOR | _NEW_BUFFERS)) - update_clamp_read_color(ctx); - - if(new_state & (_NEW_FRAG_CLAMP | _NEW_BUFFERS)) - update_clamp_fragment_color(ctx); - #if 0 if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT | _NEW_STENCIL | _MESA_NEW_SEPARATE_SPECULAR)) diff --git a/mesalib/src/mesa/main/stencil.c b/mesalib/src/mesa/main/stencil.c index c161808e5..330841731 100644 --- a/mesalib/src/mesa/main/stencil.c +++ b/mesalib/src/mesa/main/stencil.c @@ -551,6 +551,11 @@ _mesa_update_stencil(struct gl_context *ctx) ctx->Stencil.Ref[0] != ctx->Stencil.Ref[face] || ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[face] || ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[face]); + + ctx->Stencil._WriteEnabled = + ctx->Stencil._Enabled && + (ctx->Stencil.WriteMask[0] != 0 || + (ctx->Stencil._TestTwoSide && ctx->Stencil.WriteMask[face] != 0)); } diff --git a/mesalib/src/mesa/main/texenv.c b/mesalib/src/mesa/main/texenv.c index 0fe5fbd7a..2979e6706 100644 --- a/mesalib/src/mesa/main/texenv.c +++ b/mesalib/src/mesa/main/texenv.c @@ -32,6 +32,7 @@ #include "main/glheader.h" #include "main/context.h" +#include "main/blend.h" #include "main/enums.h" #include "main/macros.h" #include "main/mtypes.h" @@ -680,7 +681,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) if (pname == GL_TEXTURE_ENV_COLOR) { if(ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP)) _mesa_update_state(ctx); - if(ctx->Color._ClampFragmentColor) + if (_mesa_get_clamp_fragment_color(ctx)) COPY_4FV( params, texUnit->EnvColor ); else COPY_4FV( params, texUnit->EnvColorUnclamped ); diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index bc755ae79..784b389a7 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -47,6 +47,7 @@ #include "teximage.h" #include "texobj.h" #include "texstate.h" +#include "texstorage.h" #include "mtypes.h" #include "glformats.h" @@ -4194,7 +4195,8 @@ check_multisample_target(GLuint dims, GLenum target) static void teximagemultisample(GLuint dims, GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, - GLsizei depth, GLboolean fixedsamplelocations) + GLsizei depth, GLboolean fixedsamplelocations, + GLboolean immutable, const char *func) { struct gl_texture_object *texObj; struct gl_texture_image *texImage; @@ -4206,12 +4208,12 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, if (!(ctx->Extensions.ARB_texture_multisample && _mesa_is_desktop_gl(ctx))) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glTexImage%uDMultisample", dims); + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); return; } if (!check_multisample_target(dims, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uDMultisample(target)", dims); + _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func); return; } @@ -4219,26 +4221,40 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, * refer GL3.1 spec 4.4.4 */ + if (immutable && !_mesa_is_legal_tex_storage_format(ctx, internalformat)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(internalformat=%s not legal for immutable-format)", + func, _mesa_lookup_enum_by_nr(internalformat)); + return; + } + if (!is_renderable_texture_format(ctx, internalformat)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexImage%uDMultisample(internalformat=%s)", - dims, - _mesa_lookup_enum_by_nr(internalformat)); + "%s(internalformat=%s)", + func, _mesa_lookup_enum_by_nr(internalformat)); return; } sample_count_error = _mesa_check_sample_count(ctx, target, internalformat, samples); if (sample_count_error != GL_NO_ERROR) { - _mesa_error(ctx, sample_count_error, "glTexImage%uDMultisample(samples)", dims); + _mesa_error(ctx, sample_count_error, "%s(samples)", func); return; } texObj = _mesa_get_current_tex_object(ctx, target); + + if (immutable && (!texObj || (texObj->Name == 0))) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(texture object 0)", + func); + return; + } + texImage = _mesa_get_tex_image(ctx, texObj, 0, 0); if (texImage == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uDMultisample()", dims); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func); return; } @@ -4268,13 +4284,19 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, else { if (!dimensionsOK) { _mesa_error(ctx, GL_INVALID_VALUE, - "glTexImage%uDMultisample(invalid width or height)", dims); + "%s(invalid width or height)", func); return; } if (!sizeOK) { _mesa_error(ctx, GL_OUT_OF_MEMORY, - "glTexImage%uDMultisample(texture too large)", dims); + "%s(texture too large)", func); + return; + } + + /* Check if texObj->Immutable is set */ + if (texObj->Immutable) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable)", func); return; } @@ -4299,6 +4321,7 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, } } + texObj->Immutable = immutable; _mesa_update_fbo_texture(ctx, texObj, 0, 0); } } @@ -4309,7 +4332,7 @@ _mesa_TexImage2DMultisample(GLenum target, GLsizei samples, GLsizei height, GLboolean fixedsamplelocations) { teximagemultisample(2, target, samples, internalformat, - width, height, 1, fixedsamplelocations); + width, height, 1, fixedsamplelocations, GL_FALSE, "glTexImage2DMultisample"); } void GLAPIENTRY @@ -4319,5 +4342,25 @@ _mesa_TexImage3DMultisample(GLenum target, GLsizei samples, GLboolean fixedsamplelocations) { teximagemultisample(3, target, samples, internalformat, - width, height, depth, fixedsamplelocations); + width, height, depth, fixedsamplelocations, GL_FALSE, "glTexImage3DMultisample"); +} + + +void GLAPIENTRY +_mesa_TexStorage2DMultisample(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLboolean fixedsamplelocations) +{ + teximagemultisample(2, target, samples, internalformat, + width, height, 1, fixedsamplelocations, GL_TRUE, "glTexStorage2DMultisample"); +} + +void GLAPIENTRY +_mesa_TexStorage3DMultisample(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations) +{ + teximagemultisample(3, target, samples, internalformat, + width, height, depth, fixedsamplelocations, GL_TRUE, "glTexStorage3DMultisample"); } diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h index 744c47a8a..bb295c7a7 100644 --- a/mesalib/src/mesa/main/teximage.h +++ b/mesalib/src/mesa/main/teximage.h @@ -305,6 +305,17 @@ _mesa_TexImage3DMultisample(GLenum target, GLsizei samples, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +extern void GLAPIENTRY +_mesa_TexStorage2DMultisample(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLboolean fixedsamplelocations); + +extern void GLAPIENTRY +_mesa_TexStorage3DMultisample(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations); + /*@}*/ #ifdef __cplusplus diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index bd2f75170..f60eb204e 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -31,6 +31,7 @@ #include #include "main/glheader.h" +#include "main/blend.h" #include "main/colormac.h" #include "main/context.h" #include "main/enums.h" @@ -175,6 +176,16 @@ get_texobj(struct gl_context *ctx, GLenum target, GLboolean get) return texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX]; } break; + case GL_TEXTURE_2D_MULTISAMPLE: + if (ctx->Extensions.ARB_texture_storage_multisample) { + return texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX]; + } + break; + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + if (ctx->Extensions.ARB_texture_storage_multisample) { + return texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX]; + } + break; default: ; } @@ -250,6 +261,20 @@ incomplete(struct gl_context *ctx, struct gl_texture_object *texObj) } +static GLboolean +target_allows_setting_sampler_parameters(GLenum target) +{ + switch (target) { + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + return GL_FALSE; + + default: + return GL_TRUE; + } +} + + /** * Set an integer-valued texture parameter * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise @@ -261,6 +286,9 @@ set_tex_parameteri(struct gl_context *ctx, { switch (pname) { case GL_TEXTURE_MIN_FILTER: + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + if (texObj->Sampler.MinFilter == params[0]) return GL_FALSE; switch (params[0]) { @@ -286,6 +314,9 @@ set_tex_parameteri(struct gl_context *ctx, return GL_FALSE; case GL_TEXTURE_MAG_FILTER: + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + if (texObj->Sampler.MagFilter == params[0]) return GL_FALSE; switch (params[0]) { @@ -300,6 +331,9 @@ set_tex_parameteri(struct gl_context *ctx, return GL_FALSE; case GL_TEXTURE_WRAP_S: + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + if (texObj->Sampler.WrapS == params[0]) return GL_FALSE; if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { @@ -310,6 +344,9 @@ set_tex_parameteri(struct gl_context *ctx, return GL_FALSE; case GL_TEXTURE_WRAP_T: + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + if (texObj->Sampler.WrapT == params[0]) return GL_FALSE; if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { @@ -320,6 +357,9 @@ set_tex_parameteri(struct gl_context *ctx, return GL_FALSE; case GL_TEXTURE_WRAP_R: + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + if (texObj->Sampler.WrapR == params[0]) return GL_FALSE; if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { @@ -335,6 +375,11 @@ set_tex_parameteri(struct gl_context *ctx, if (texObj->BaseLevel == params[0]) return GL_FALSE; + + if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE || + texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && params[0] != 0) + goto invalid_operation; + if (params[0] < 0 || (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -348,6 +393,7 @@ set_tex_parameteri(struct gl_context *ctx, case GL_TEXTURE_MAX_LEVEL: if (texObj->MaxLevel == params[0]) return GL_FALSE; + if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param=%d)", params[0]); @@ -373,6 +419,10 @@ set_tex_parameteri(struct gl_context *ctx, case GL_TEXTURE_COMPARE_MODE_ARB: if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow) || _mesa_is_gles3(ctx)) { + + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + if (texObj->Sampler.CompareMode == params[0]) return GL_FALSE; if (params[0] == GL_NONE || @@ -388,6 +438,10 @@ set_tex_parameteri(struct gl_context *ctx, case GL_TEXTURE_COMPARE_FUNC_ARB: if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow) || _mesa_is_gles3(ctx)) { + + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + if (texObj->Sampler.CompareFunc == params[0]) return GL_FALSE; switch (params[0]) { @@ -489,7 +543,11 @@ set_tex_parameteri(struct gl_context *ctx, case GL_TEXTURE_SRGB_DECODE_EXT: if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_sRGB_decode) { - GLenum decode = params[0]; + GLenum decode = params[0]; + + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) { if (texObj->Sampler.sRGBDecode != decode) { flush(ctx); @@ -504,6 +562,10 @@ set_tex_parameteri(struct gl_context *ctx, if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.AMD_seamless_cubemap_per_texture) { GLenum param = params[0]; + + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + if (param != GL_TRUE && param != GL_FALSE) { goto invalid_param; } @@ -528,6 +590,11 @@ invalid_param: _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=%s)", _mesa_lookup_enum_by_nr(params[0])); return GL_FALSE; + +invalid_operation: + _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)", + _mesa_lookup_enum_by_nr(pname)); + return GL_FALSE; } @@ -545,6 +612,9 @@ set_tex_parameterf(struct gl_context *ctx, if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_pname; + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + if (texObj->Sampler.MinLod == params[0]) return GL_FALSE; flush(ctx); @@ -555,6 +625,9 @@ set_tex_parameterf(struct gl_context *ctx, if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_pname; + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + if (texObj->Sampler.MaxLod == params[0]) return GL_FALSE; flush(ctx); @@ -571,6 +644,9 @@ set_tex_parameterf(struct gl_context *ctx, case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (ctx->Extensions.EXT_texture_filter_anisotropic) { + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + if (texObj->Sampler.MaxAnisotropy == params[0]) return GL_FALSE; if (params[0] < 1.0) { @@ -598,6 +674,9 @@ set_tex_parameterf(struct gl_context *ctx, if (ctx->API != API_OPENGL_COMPAT) goto invalid_pname; + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + if (texObj->Sampler.LodBias != params[0]) { flush(ctx); texObj->Sampler.LodBias = params[0]; @@ -609,6 +688,9 @@ set_tex_parameterf(struct gl_context *ctx, if (!_mesa_is_desktop_gl(ctx)) goto invalid_pname; + if (!target_allows_setting_sampler_parameters(texObj->Target)) + goto invalid_operation; + flush(ctx); /* ARB_texture_float disables clamping */ if (ctx->Extensions.ARB_texture_float) { @@ -633,6 +715,11 @@ invalid_pname: _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)", _mesa_lookup_enum_by_nr(pname)); return GL_FALSE; + +invalid_operation: + _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)", + _mesa_lookup_enum_by_nr(pname)); + return GL_FALSE; } @@ -1329,7 +1416,7 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP)) _mesa_update_state_locked(ctx); - if (ctx->Color._ClampFragmentColor) { + if (_mesa_get_clamp_fragment_color(ctx)) { params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F); params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F); params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F); diff --git a/mesalib/src/mesa/main/texstorage.c b/mesalib/src/mesa/main/texstorage.c index 675fd745b..6309b5716 100644 --- a/mesalib/src/mesa/main/texstorage.c +++ b/mesalib/src/mesa/main/texstorage.c @@ -202,20 +202,9 @@ clear_texture_fields(struct gl_context *ctx, } -/** - * Do error checking for calls to glTexStorage1/2/3D(). - * If an error is found, record it with _mesa_error(), unless the target - * is a proxy texture. - * \return GL_TRUE if any error, GL_FALSE otherwise. - */ -static GLboolean -tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, - GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth) +GLboolean +_mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat) { - struct gl_texture_object *texObj; - GLboolean legalFormat; - /* check internal format - note that only sized formats are allowed */ switch (internalformat) { case GL_ALPHA: @@ -250,13 +239,27 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, case GL_LUMINANCE_INTEGER_EXT: case GL_LUMINANCE_ALPHA_INTEGER_EXT: /* these unsized formats are illegal */ - legalFormat = GL_FALSE; - break; + return GL_FALSE; default: - legalFormat = _mesa_base_tex_format(ctx, internalformat) > 0; + return _mesa_base_tex_format(ctx, internalformat) > 0; } +} + + +/** + * Do error checking for calls to glTexStorage1/2/3D(). + * If an error is found, record it with _mesa_error(), unless the target + * is a proxy texture. + * \return GL_TRUE if any error, GL_FALSE otherwise. + */ +static GLboolean +tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, + GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth) +{ + struct gl_texture_object *texObj; - if (!legalFormat) { + if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexStorage%uD(internalformat = %s)", dims, _mesa_lookup_enum_by_nr(internalformat)); diff --git a/mesalib/src/mesa/main/texstorage.h b/mesalib/src/mesa/main/texstorage.h index 99382df51..9f172e1ca 100644 --- a/mesalib/src/mesa/main/texstorage.h +++ b/mesalib/src/mesa/main/texstorage.h @@ -57,5 +57,8 @@ _mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +extern GLboolean +_mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat); + #endif /* TEXSTORAGE_H */ diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c index 3d4af5923..ecca446c1 100644 --- a/mesalib/src/mesa/main/version.c +++ b/mesalib/src/mesa/main/version.c @@ -233,7 +233,8 @@ compute_version(struct gl_context *ctx) const GLboolean ver_3_0 = (ver_2_1 && ctx->Const.GLSLVersion >= 130 && ctx->Const.MaxSamples >= 4 && - ctx->Extensions.ARB_color_buffer_float && + (ctx->API == API_OPENGL_CORE || + ctx->Extensions.ARB_color_buffer_float) && ctx->Extensions.ARB_depth_buffer_float && ctx->Extensions.ARB_half_float_pixel && ctx->Extensions.ARB_half_float_vertex && diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index 2cb5f02f4..14cf5baa7 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -2048,6 +2048,9 @@ ir_to_mesa_visitor::visit(ir_texture *ir) case ir_txf_ms: assert(!"Unexpected ir_txf_ms opcode"); break; + case ir_lod: + assert(!"Unexpected ir_lod opcode"); + break; } const glsl_type *sampler_type = ir->sampler->type; diff --git a/mesalib/src/mesa/program/prog_cache.c b/mesalib/src/mesa/program/prog_cache.c index 47f926b1b..1f1c6142d 100644 --- a/mesalib/src/mesa/program/prog_cache.c +++ b/mesalib/src/mesa/program/prog_cache.c @@ -37,6 +37,7 @@ struct cache_item { GLuint hash; + unsigned keysize; void *key; struct gl_program *program; struct cache_item *next; @@ -174,7 +175,8 @@ struct gl_program * _mesa_search_program_cache(struct gl_program_cache *cache, const void *key, GLuint keysize) { - if (cache->last && + if (cache->last && + cache->last->keysize == keysize && memcmp(cache->last->key, key, keysize) == 0) { return cache->last->program; } @@ -183,7 +185,10 @@ _mesa_search_program_cache(struct gl_program_cache *cache, struct cache_item *c; for (c = cache->items[hash % cache->size]; c; c = c->next) { - if (c->hash == hash && memcmp(c->key, key, keysize) == 0) { + if (c->hash == hash && + c->keysize == keysize && + memcmp(c->key, key, keysize) == 0) { + cache->last = c; return c->program; } @@ -207,6 +212,7 @@ _mesa_program_cache_insert(struct gl_context *ctx, c->key = malloc(keysize); memcpy(c->key, key, keysize); + c->keysize = keysize; c->program = program; /* no refcount change */ @@ -235,6 +241,7 @@ _mesa_shader_cache_insert(struct gl_context *ctx, c->key = malloc(keysize); memcpy(c->key, key, keysize); + c->keysize = keysize; c->program = (struct gl_program *)program; /* no refcount change */ diff --git a/mesalib/src/mesa/program/prog_statevars.c b/mesalib/src/mesa/program/prog_statevars.c index 5a350798c..09d2a568a 100644 --- a/mesalib/src/mesa/program/prog_statevars.c +++ b/mesalib/src/mesa/program/prog_statevars.c @@ -31,6 +31,7 @@ #include "main/glheader.h" #include "main/context.h" +#include "main/blend.h" #include "main/imports.h" #include "main/macros.h" #include "main/mtypes.h" @@ -239,14 +240,14 @@ _mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[], { /* state[1] is the texture unit */ const GLuint unit = (GLuint) state[1]; - if(ctx->Color._ClampFragmentColor) + if (_mesa_get_clamp_fragment_color(ctx)) COPY_4V(value, ctx->Texture.Unit[unit].EnvColor); else COPY_4V(value, ctx->Texture.Unit[unit].EnvColorUnclamped); } return; case STATE_FOG_COLOR: - if(ctx->Color._ClampFragmentColor) + if (_mesa_get_clamp_fragment_color(ctx)) COPY_4V(value, ctx->Fog.Color); else COPY_4V(value, ctx->Fog.ColorUnclamped); @@ -871,6 +872,9 @@ append_token(char *dst, gl_state_index k) case STATE_CURRENT_ATTRIB: append(dst, "current"); break; + case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED: + append(dst, "currentAttribMaybeVPClamped"); + break; case STATE_NORMAL_SCALE: append(dst, "normalScale"); break; diff --git a/mesalib/src/mesa/program/register_allocate.c b/mesalib/src/mesa/program/register_allocate.c index a9064c38c..2c826fc66 100644 --- a/mesalib/src/mesa/program/register_allocate.c +++ b/mesalib/src/mesa/program/register_allocate.c @@ -70,6 +70,7 @@ * this during ra_set_finalize(). */ +#include #include #include "main/imports.h" @@ -93,6 +94,8 @@ struct ra_regs { struct ra_class **classes; unsigned int class_count; + + bool round_robin; }; struct ra_class { @@ -185,6 +188,22 @@ ra_alloc_reg_set(void *mem_ctx, unsigned int count) return regs; } +/** + * The register allocator by default prefers to allocate low register numbers, + * since it was written for hardware (gen4/5 Intel) that is limited in its + * multithreadedness by the number of registers used in a given shader. + * + * However, for hardware without that restriction, densely packed register + * allocation can put serious constraints on instruction scheduling. This + * function tells the allocator to rotate around the registers if possible as + * it allocates the nodes. + */ +void +ra_set_allocate_round_robin(struct ra_regs *regs) +{ + regs->round_robin = true; +} + static void ra_add_conflict_list(struct ra_regs *regs, unsigned int r1, unsigned int r2) { @@ -436,16 +455,19 @@ GLboolean ra_select(struct ra_graph *g) { int i; + int start_search_reg = 0; while (g->stack_count != 0) { - unsigned int r; + unsigned int ri; + unsigned int r = -1; int n = g->stack[g->stack_count - 1]; struct ra_class *c = g->regs->classes[g->nodes[n].class]; /* Find the lowest-numbered reg which is not used by a member * of the graph adjacent to us. */ - for (r = 0; r < g->regs->count; r++) { + for (ri = 0; ri < g->regs->count; ri++) { + r = (start_search_reg + ri) % g->regs->count; if (!c->regs[r]) continue; @@ -461,12 +483,15 @@ ra_select(struct ra_graph *g) if (i == g->nodes[n].adjacency_count) break; } - if (r == g->regs->count) + if (ri == g->regs->count) return GL_FALSE; g->nodes[n].reg = r; g->nodes[n].in_stack = GL_FALSE; g->stack_count--; + + if (g->regs->round_robin) + start_search_reg = r + 1; } return GL_TRUE; diff --git a/mesalib/src/mesa/program/register_allocate.h b/mesalib/src/mesa/program/register_allocate.h index 2a9d61191..fa119e320 100644 --- a/mesalib/src/mesa/program/register_allocate.h +++ b/mesalib/src/mesa/program/register_allocate.h @@ -37,6 +37,7 @@ struct ra_regs; * two real registers from which they are composed. */ struct ra_regs *ra_alloc_reg_set(void *mem_ctx, unsigned int count); +void ra_set_allocate_round_robin(struct ra_regs *regs); unsigned int ra_alloc_reg_class(struct ra_regs *regs); void ra_add_reg_conflict(struct ra_regs *regs, unsigned int r1, unsigned int r2); diff --git a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c index 961fb28a9..56ba96fe3 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c +++ b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c @@ -39,6 +39,7 @@ #include "pipe/p_defines.h" #include "util/u_inlines.h" #include "util/u_upload_mgr.h" +#include "cso_cache/cso_context.h" #include "st_debug.h" #include "st_context.h" @@ -96,16 +97,17 @@ void st_upload_constants( struct st_context *st, _mesa_print_parameter_list(params); } - st->pipe->set_constant_buffer(st->pipe, shader_type, 0, &cb); + cso_set_constant_buffer(st->cso_context, shader_type, 0, &cb); pipe_resource_reference(&cb.buffer, NULL); st->state.constants[shader_type].ptr = params->ParameterValues; st->state.constants[shader_type].size = paramBytes; } else if (st->state.constants[shader_type].ptr) { + /* Unbind. */ st->state.constants[shader_type].ptr = NULL; st->state.constants[shader_type].size = 0; - st->pipe->set_constant_buffer(st->pipe, shader_type, 0, NULL); + cso_set_constant_buffer(st->cso_context, shader_type, 0, NULL); } } @@ -196,7 +198,7 @@ static void st_bind_ubos(struct st_context *st, cb.buffer_size = st_obj->buffer->width0 - binding->Offset; - st->pipe->set_constant_buffer(st->pipe, shader_type, 1 + i, &cb); + cso_set_constant_buffer(st->cso_context, shader_type, 1 + i, &cb); pipe_resource_reference(&cb.buffer, NULL); } } diff --git a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c index 866e5627d..62464b475 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c @@ -227,8 +227,7 @@ static void update_raster_state( struct st_context *st ) /* _NEW_FRAG_CLAMP */ raster->clamp_fragment_color = !st->clamp_frag_color_in_shader && - ctx->Color._ClampFragmentColor && - !ctx->DrawBuffer->_IntegerColor; + ctx->Color._ClampFragmentColor; raster->gl_rasterization_rules = 1; /* _NEW_RASTERIZER_DISCARD */ diff --git a/mesalib/src/mesa/state_tracker/st_atom_shader.c b/mesalib/src/mesa/state_tracker/st_atom_shader.c index c1d7c80bb..c0239e929 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_shader.c +++ b/mesalib/src/mesa/state_tracker/st_atom_shader.c @@ -86,8 +86,7 @@ update_fp( struct st_context *st ) /* _NEW_FRAG_CLAMP */ key.clamp_color = st->clamp_frag_color_in_shader && - st->ctx->Color._ClampFragmentColor && - !st->ctx->DrawBuffer->_IntegerColor; + st->ctx->Color._ClampFragmentColor; st->fp_variant = st_get_fp_variant(st, stfp, &key); diff --git a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c index bae9ff858..b3ca40501 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c +++ b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c @@ -417,8 +417,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, key.st = st; key.bitmap = GL_TRUE; key.clamp_color = st->clamp_frag_color_in_shader && - st->ctx->Color._ClampFragmentColor && - !st->ctx->DrawBuffer->_IntegerColor; + st->ctx->Color._ClampFragmentColor; fpv = st_get_fp_variant(st, st->fp, &key); @@ -766,6 +765,7 @@ st_Bitmap(struct gl_context *ctx, GLint x, GLint y, /* create pass-through vertex shader now */ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_COLOR, + st->needs_texcoord_semantic ? TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC }; const uint semantic_indexes[] = { 0, 0, 0 }; st->bitmap.vs = util_make_vertex_passthrough_shader(st->pipe, 3, diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c index f0baa3435..f5a1e27f7 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c @@ -294,6 +294,9 @@ static void * make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor) { + const unsigned texcoord_semantic = st->needs_texcoord_semantic ? + TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC; + if (!st->drawpix.vert_shaders[passColor]) { struct ureg_program *ureg = ureg_create( TGSI_PROCESSOR_VERTEX ); @@ -307,7 +310,7 @@ make_passthrough_vertex_shader(struct st_context *st, /* MOV result.texcoord0, vertex.attr[1]; */ ureg_MOV(ureg, - ureg_DECL_output( ureg, TGSI_SEMANTIC_GENERIC, 0 ), + ureg_DECL_output( ureg, texcoord_semantic, 0 ), ureg_DECL_vs_input( ureg, 1 )); if (passColor) { @@ -707,8 +710,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, struct pipe_rasterizer_state rasterizer; memset(&rasterizer, 0, sizeof(rasterizer)); rasterizer.clamp_fragment_color = !st->clamp_frag_color_in_shader && - ctx->Color._ClampFragmentColor && - !ctx->DrawBuffer->_IntegerColor; + ctx->Color._ClampFragmentColor; rasterizer.gl_rasterization_rules = 1; rasterizer.depth_clip = !ctx->Transform.DepthClamp; rasterizer.scissor = ctx->Scissor.Enabled; @@ -1034,8 +1036,7 @@ get_color_fp_variant(struct st_context *st) ctx->Pixel.AlphaScale != 1.0); key.pixelMaps = ctx->Pixel.MapColorFlag; key.clamp_color = st->clamp_frag_color_in_shader && - st->ctx->Color._ClampFragmentColor && - !st->ctx->DrawBuffer->_IntegerColor; + st->ctx->Color._ClampFragmentColor; fpv = st_get_fp_variant(st, st->fp, &key); diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c index a8806c91e..c4efce02f 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c @@ -209,7 +209,9 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, SET_ATTRIB(2, attr, s1, t1, 0.0f, 1.0f); /* upper right */ SET_ATTRIB(3, attr, s0, t1, 0.0f, 1.0f); /* upper left */ - semantic_names[attr] = TGSI_SEMANTIC_GENERIC; + semantic_names[attr] = st->needs_texcoord_semantic ? + TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC; + /* XXX: should this use semantic index i instead of 0 ? */ semantic_indexes[attr] = 0; attr++; diff --git a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c index bfed98870..9fab113fa 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c @@ -133,7 +133,6 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, !screen->is_format_supported(screen, src_format, src->target, src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) { - printf("fallback: src format unsupported %s\n", util_format_short_name(src_format)); goto fallback; } @@ -147,8 +146,6 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, dst_format = st_choose_matching_format(screen, bind, format, type, pack->SwapBytes); if (dst_format == PIPE_FORMAT_NONE) { - printf("fallback: no matching format for %s, %s\n", - _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type)); goto fallback; } diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index 94fbbf7be..0cd0d77af 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -868,7 +868,7 @@ st_GetTexImage(struct gl_context * ctx, goto fallback; } - if (!stImage->pt) { + if (!stImage->pt || !src) { goto fallback; } diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index 11db9d3f3..2d8b9efec 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -629,6 +629,7 @@ void st_init_extensions(struct st_context *st) ctx->Const.PrimitiveRestartInSoftware = GL_TRUE; } + /* ARB_color_buffer_float. */ if (screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_UNCLAMPED)) { ctx->Extensions.ARB_color_buffer_float = GL_TRUE; @@ -639,6 +640,16 @@ void st_init_extensions(struct st_context *st) if (!screen->get_param(screen, PIPE_CAP_FRAGMENT_COLOR_CLAMPED)) { st->clamp_frag_color_in_shader = TRUE; } + + /* For drivers which cannot do color clamping, it's better to just + * disable ARB_color_buffer_float in the core profile, because + * the clamping is deprecated there anyway. */ + if (ctx->API == API_OPENGL_CORE && + (st->clamp_frag_color_in_shader || st->clamp_vert_color_in_shader)) { + st->clamp_vert_color_in_shader = GL_FALSE; + st->clamp_frag_color_in_shader = GL_FALSE; + ctx->Extensions.ARB_color_buffer_float = GL_FALSE; + } } if (screen->fence_finish) { diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index e3718eeda..338c652cb 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -1009,7 +1009,9 @@ glsl_to_tgsi_visitor::get_temp(const glsl_type *type) src.reladdr = NULL; src.negate = 0; - if (type->is_array() || type->is_matrix()) { + if (!options->EmitNoIndirectTemp && + (type->is_array() || type->is_matrix())) { + src.file = PROGRAM_ARRAY; src.index = next_array << 16 | 0x8000; array_sizes[next_array] = type_size(type); @@ -2772,6 +2774,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) case ir_txf_ms: assert(!"Unexpected ir_txf_ms opcode"); break; + case ir_lod: + assert(!"Unexpected ir_lod opcode"); + break; } if (ir->projector) { @@ -3191,7 +3196,7 @@ glsl_to_tgsi_visitor::simplify_cmp(void) prevWriteMask = tempWrites[inst->dst.index]; tempWrites[inst->dst.index] |= inst->dst.writemask; } else - break; + continue; /* For a CMP to be considered a conditional write, the destination * register and source register two must be the same. */ diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c index 0b025d9d5..03e086a72 100644 --- a/mesalib/src/mesa/state_tracker/st_manager.c +++ b/mesalib/src/mesa/state_tracker/st_manager.c @@ -170,9 +170,8 @@ st_context_validate(struct st_context *st, /** * 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(): + * The context is only used for creating pipe surfaces and for calling + * _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). diff --git a/mesalib/src/mesa/swrast/s_blit.c b/mesalib/src/mesa/swrast/s_blit.c index 82fa43f1c..051354dc8 100644 --- a/mesalib/src/mesa/swrast/s_blit.c +++ b/mesalib/src/mesa/swrast/s_blit.c @@ -110,8 +110,8 @@ blit_nearest(struct gl_context *ctx, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield buffer) { - struct gl_renderbuffer *readRb, *drawRb; - struct gl_renderbuffer_attachment *readAtt, *drawAtt; + struct gl_renderbuffer *readRb, *drawRb = NULL; + struct gl_renderbuffer_attachment *readAtt = NULL, *drawAtt = NULL; struct gl_framebuffer *readFb = ctx->ReadBuffer; struct gl_framebuffer *drawFb = ctx->DrawBuffer; GLuint numDrawBuffers = 0; @@ -135,12 +135,12 @@ blit_nearest(struct gl_context *ctx, UNPACK_Z_FLOAT, UNPACK_Z_INT, UNPACK_S, - } mode; + } mode = DIRECT; GLubyte *srcMap, *dstMap; GLint srcRowStride, dstRowStride; GLint dstRow; - GLint pixelSize; + GLint pixelSize = 0; GLvoid *srcBuffer, *dstBuffer; GLint prevY = -1; diff --git a/xorg-server/hw/kdrive/fbdev/fbdev.c b/xorg-server/hw/kdrive/fbdev/fbdev.c index fb6e3a292..d6fcf1a5f 100644 --- a/xorg-server/hw/kdrive/fbdev/fbdev.c +++ b/xorg-server/hw/kdrive/fbdev/fbdev.c @@ -465,6 +465,20 @@ fbdevRandRSetConfig(ScreenPtr pScreen, int oldheight; int oldmmwidth; int oldmmheight; + int newwidth, newheight, newmmwidth, newmmheight; + + if (screen->randr & (RR_Rotate_0 | RR_Rotate_180)) { + newwidth = pSize->width; + newheight = pSize->height; + newmmwidth = pSize->mmWidth; + newmmheight = pSize->mmHeight; + } + else { + newwidth = pSize->height; + newheight = pSize->width; + newmmwidth = pSize->mmHeight; + newmmheight = pSize->mmWidth; + } if (wasEnabled) KdDisableScreen(pScreen); @@ -481,6 +495,10 @@ fbdevRandRSetConfig(ScreenPtr pScreen, */ scrpriv->randr = KdAddRotation(screen->randr, randr); + pScreen->width = newwidth; + pScreen->height = newheight; + pScreen->mmWidth = newmmwidth; + pScreen->mmHeight = newmmheight; fbdevUnmapFramebuffer(screen); diff --git a/xorg-server/hw/xfree86/man/xorg.conf.man b/xorg-server/hw/xfree86/man/xorg.conf.man index 9361ce978..67d8594fb 100644 --- a/xorg-server/hw/xfree86/man/xorg.conf.man +++ b/xorg-server/hw/xfree86/man/xorg.conf.man @@ -1676,6 +1676,17 @@ This optional entry specifies a mode to be marked as the preferred initial mode of the monitor. (RandR 1.2-supporting drivers only) .TP 7 +.BI "Option \*qZoomModes\*q \*q" name " " name " " ... \*q +This optional entry specifies modes to be marked as zoom modes. +It is possible to switch to the next and previous mode via +.BR Ctrl+Alt+Keypad\-Plus " and " Ctrl+Alt+Keypad\-Minus . +All these keypad available modes are selected from the screen mode list. +This list is a copy of the compatibility output monitor mode list. +Since this output is the output connected to the lowest +dot-area monitor, as determined from its largest size mode, that +monitor defines the available zoom modes. +(RandR 1.2-supporting drivers only) +.TP 7 .BI "Option \*qPosition\*q \*q" x " " y \*q This optional entry specifies the position of the monitor within the X screen. diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c index f9ae46596..e4b393cb1 100644 --- a/xorg-server/hw/xfree86/modes/xf86Crtc.c +++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c @@ -428,6 +428,7 @@ extern XF86ConfigPtr xf86configptr; typedef enum { OPTION_PREFERRED_MODE, + OPTION_ZOOM_MODES, OPTION_POSITION, OPTION_BELOW, OPTION_RIGHT_OF, @@ -446,6 +447,7 @@ typedef enum { static OptionInfoRec xf86OutputOptions[] = { {OPTION_PREFERRED_MODE, "PreferredMode", OPTV_STRING, {0}, FALSE}, + {OPTION_ZOOM_MODES, "ZoomModes", OPTV_STRING, {0}, FALSE }, {OPTION_POSITION, "Position", OPTV_STRING, {0}, FALSE}, {OPTION_BELOW, "Below", OPTV_STRING, {0}, FALSE}, {OPTION_RIGHT_OF, "RightOf", OPTV_STRING, {0}, FALSE}, @@ -1418,6 +1420,90 @@ preferredMode(ScrnInfoPtr pScrn, xf86OutputPtr output) return preferred_mode; } +/** identify a token + * args + * *src a string with zero or more tokens, e.g. "tok0 tok1", + * **token stores a pointer to the first token character, + * *len stores the token length. + * return + * a pointer into src[] at the token terminating character, or + * NULL if no token is found. + */ +static const char * +gettoken(const char *src, const char **token, int *len) +{ + const char *delim = " \t"; + int skip; + + if (!src) + return NULL; + + skip = strspn(src, delim); + *token = &src[skip]; + + *len = strcspn(*token, delim); + /* Support for backslash escaped delimiters could be implemented + * here. + */ + + /* (*token)[0] != '\0' <==> *len > 0 */ + if (*len > 0) + return &(*token)[*len]; + else + return NULL; +} + +/** Check for a user configured zoom mode list, Option "ZoomModes": + * + * Section "Monitor" + * Identifier "a21inch" + * Option "ZoomModes" "1600x1200 1280x1024 1280x1024 640x480" + * EndSection + * + * Each user mode name is searched for independently so the list + * specification order is free. An output mode is matched at most + * once, a mode with an already set M_T_USERDEF type bit is skipped. + * Thus a repeat mode name specification matches the next output mode + * with the same name. + * + * Ctrl+Alt+Keypad-{Plus,Minus} zooms {in,out} by selecting the + * {next,previous} M_T_USERDEF mode in the screen modes list, itself + * sorted toward lower dot area or lower dot clock frequency, see + * modes/xf86Crtc.c: xf86SortModes() xf86SetScrnInfoModes(), and + * common/xf86Cursor.c: xf86ZoomViewport(). + */ +static int +processZoomModes(xf86OutputPtr output) +{ + const char *zoom_modes; + int count = 0; + + zoom_modes = xf86GetOptValString(output->options, OPTION_ZOOM_MODES); + + if (zoom_modes) { + const char *token, *next; + int len; + + next = gettoken(zoom_modes, &token, &len); + while (next) { + DisplayModePtr mode; + + for (mode = output->probed_modes; mode; mode = mode->next) + if (!strncmp(token, mode->name, len) /* prefix match */ + && mode->name[len] == '\0' /* equal length */ + && !(mode->type & M_T_USERDEF)) { /* no rematch */ + mode->type |= M_T_USERDEF; + break; + } + + count++; + next = gettoken(next, &token, &len); + } + } + + return count; +} + static void GuessRangeFromModes(MonPtr mon, DisplayModePtr mode) { @@ -1713,6 +1799,9 @@ xf86ProbeOutputModes(ScrnInfoPtr scrn, int maxX, int maxY) } } + /* Ctrl+Alt+Keypad-{Plus,Minus} zoom mode: M_T_USERDEF mode type */ + processZoomModes(output); + output->initial_rotation = xf86OutputInitialRotation(output); if (debug_modes) { diff --git a/xorg-server/xkeyboard-config/symbols/gb b/xorg-server/xkeyboard-config/symbols/gb index c7de8c33e..10372afcd 100644 --- a/xorg-server/xkeyboard-config/symbols/gb +++ b/xorg-server/xkeyboard-config/symbols/gb @@ -169,7 +169,8 @@ xkb_symbols "mac" { key { [ 2, at, EuroSign ] }; key { [ 3, sterling, numbersign ] }; - key { [ grave, asciitilde ] }; + key { [ section, plusminus ] }; + key { [ grave, asciitilde ] }; // End alphanumeric section diff --git a/xorg-server/xkeyboard-config/symbols/macintosh_vndr/gb b/xorg-server/xkeyboard-config/symbols/macintosh_vndr/gb index a6bc48e8c..4e4248561 100644 --- a/xorg-server/xkeyboard-config/symbols/macintosh_vndr/gb +++ b/xorg-server/xkeyboard-config/symbols/macintosh_vndr/gb @@ -4,12 +4,14 @@ xkb_symbols "basic" { // Describes the differences between a very simple en_US // keyboard and a very simple U.K. keyboard layout - include "latin" + include "macintosh_vndr/us" name[Group1]= "United Kingdom - Mac"; key { [ 2, at, EuroSign ] }; key { [ 3, sterling, numbersign ] }; + key { [ section, plusminus ] }; + key { [ grave, asciitilde ] }; // End alphanumeric section diff --git a/xorg-server/xkeyboard-config/symbols/md b/xorg-server/xkeyboard-config/symbols/md index 848fe05a7..f7700e930 100644 --- a/xorg-server/xkeyboard-config/symbols/md +++ b/xorg-server/xkeyboard-config/symbols/md @@ -38,7 +38,7 @@ name[Group1]="Moldavian (Gagauz)"; // Alphanumeric section key { [ grave, asciitilde ] }; key { [ 1, exclam ] }; - key { [ 2, quotedb1, at ] }; + key { [ 2, quotedbl, at ] }; key { [ 3, numbersign ] }; key { [ 4, semicolon, dollar ] }; key { [ 5, percent, EuroSign, cent ] }; -- cgit v1.2.3
  • +Mesa 9.1.1 is released. +This is a bug fix release. +