From 9e23b44bfe1e6e85231b1c07d945cadf0c868648 Mon Sep 17 00:00:00 2001 From: marha Date: Wed, 16 Oct 2013 11:23:27 +0200 Subject: fontconfig libxcb libxcb/xcb-proto xserver mesa pixman xkbcomp git update 16 oct 2013 xserver commit 7cf1b595c8c8f9776a39559d2878cf90af3f2859 libxcb commit e4e0c6eec861f4c69da12060dc8dbe7a63fa5eb6 libxcb/xcb-proto commit 55c75accecf0e76d2aa38656efd2be4044b9e643 xkbcomp commit 839ccda42d8b088d94324cd77c4be954859914d3 pixman commit 9e81419ed5c0ee490ddacf7bada516a25cae87eb fontconfig commit 5406919c5e186f74ccdade1a65344ce7b5c56a64 mesa commit 6e444a72c1f9e4446e025b8cb780523cb89f0584 --- fontconfig/README | 29 +- fontconfig/configure.ac | 6 +- fontconfig/doc/fcstrset.fncs | 10 +- fontconfig/fc-case/CaseFolding.txt | 6 +- fontconfig/fontconfig/fontconfig.h | 4 +- fontconfig/test/Makefile.am | 5 +- libxcb/src/xcb_util.c | 4 + libxcb/xcb-proto/src/composite.xml | 4 +- libxcb/xcb-proto/src/damage.xml | 8 +- libxcb/xcb-proto/src/dpms.xml | 8 +- libxcb/xcb-proto/src/dri2.xml | 26 +- libxcb/xcb-proto/src/randr.xml | 9 +- libxcb/xcb-proto/src/render.xml | 140 ++--- libxcb/xcb-proto/src/screensaver.xml | 14 +- libxcb/xcb-proto/src/shape.xml | 16 +- libxcb/xcb-proto/src/sync.xml | 18 +- libxcb/xcb-proto/src/xcb.xsd | 5 +- libxcb/xcb-proto/src/xevie.xml | 4 +- libxcb/xcb-proto/src/xfixes.xml | 22 +- libxcb/xcb-proto/src/xinput.xml | 112 ++-- libxcb/xcb-proto/src/xkb.xml | 4 +- libxcb/xcb-proto/src/xproto.xml | 136 ++--- libxcb/xcb-proto/src/xv.xml | 34 +- mesalib/VERSION | 2 +- mesalib/configure.ac | 25 +- mesalib/docs/relnotes.html | 2 +- mesalib/docs/relnotes/10.0.html | 65 ++ mesalib/docs/relnotes/9.3.html | 65 -- mesalib/include/GL/internal/dri_interface.h | 2 + mesalib/scons/llvm.py | 6 +- mesalib/src/gallium/auxiliary/Makefile.am | 6 - mesalib/src/gallium/auxiliary/SConscript | 2 + mesalib/src/gallium/auxiliary/util/u_math.h | 2 +- mesalib/src/glsl/.dir-locals.el | 3 - mesalib/src/glsl/Makefile.am | 11 + mesalib/src/glsl/SConscript | 6 +- mesalib/src/glsl/ast_array_index.cpp | 84 ++- mesalib/src/glsl/ast_to_hir.cpp | 311 ++++++++-- mesalib/src/glsl/builtin_functions.cpp | 73 +++ mesalib/src/glsl/builtin_types.cpp | 74 +-- mesalib/src/glsl/builtin_variables.cpp | 113 +++- mesalib/src/glsl/glsl_parser.yy | 6 + mesalib/src/glsl/glsl_parser_extras.cpp | 11 +- mesalib/src/glsl/glsl_parser_extras.h | 11 +- mesalib/src/glsl/glsl_symbol_table.cpp | 15 + mesalib/src/glsl/glsl_symbol_table.h | 8 + mesalib/src/glsl/glsl_types.cpp | 13 +- mesalib/src/glsl/glsl_types.h | 11 +- mesalib/src/glsl/ir.cpp | 9 +- mesalib/src/glsl/ir.h | 91 ++- mesalib/src/glsl/ir_builder.cpp | 15 + mesalib/src/glsl/ir_builder.h | 3 + mesalib/src/glsl/ir_clone.cpp | 6 + mesalib/src/glsl/ir_validate.cpp | 33 + mesalib/src/glsl/link_functions.cpp | 37 +- mesalib/src/glsl/link_interface_blocks.cpp | 17 +- .../src/glsl/link_uniform_block_active_visitor.cpp | 12 +- mesalib/src/glsl/link_uniforms.cpp | 13 +- mesalib/src/glsl/link_varyings.cpp | 113 +++- mesalib/src/glsl/link_varyings.h | 11 +- mesalib/src/glsl/linker.cpp | 167 ++++- mesalib/src/glsl/lower_clip_distance.cpp | 253 ++++++-- mesalib/src/glsl/lower_named_interface_blocks.cpp | 7 +- mesalib/src/glsl/lower_ubo_reference.cpp | 3 +- mesalib/src/glsl/main.cpp | 197 +++++- mesalib/src/glsl/standalone_scaffolding.cpp | 28 +- mesalib/src/mapi/glapi/gen/gl_API.xml | 2 +- mesalib/src/mapi/glapi/gen/gl_gentable.py | 2 +- mesalib/src/mesa/drivers/SConscript | 2 +- mesalib/src/mesa/drivers/dri/Makefile.am | 2 - mesalib/src/mesa/drivers/dri/common/dri_util.c | 171 +++++- mesalib/src/mesa/drivers/dri/common/dri_util.h | 11 + mesalib/src/mesa/drivers/dri/common/drisw_util.c | 375 ------------ mesalib/src/mesa/drivers/dri/common/utils.c | 10 + mesalib/src/mesa/drivers/dri/swrast/Makefile.am | 1 + .../src/mesa/drivers/dri/swrast/Makefile.sources | 3 +- mesalib/src/mesa/drivers/dri/swrast/swrast.c | 20 +- mesalib/src/mesa/main/api_validate.c | 53 +- mesalib/src/mesa/main/dd.h | 3 +- mesalib/src/mesa/main/fbobject.c | 1 + mesalib/src/mesa/main/imports.c | 3 +- mesalib/src/mesa/main/macros.h | 36 +- mesalib/src/mesa/main/shaderapi.c | 6 - mesalib/src/mesa/main/texgetimage.c | 2 +- mesalib/src/mesa/main/texgetimage.h | 3 + mesalib/src/mesa/main/texstore.c | 1 + mesalib/src/mesa/program/ir_to_mesa.cpp | 3 + .../src/mesa/state_tracker/st_cb_bufferobjects.c | 26 +- mesalib/src/mesa/state_tracker/st_format.c | 36 ++ mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 6 + mesalib/src/mesa/vbo/vbo_exec.c | 2 +- mesalib/src/mesa/vbo/vbo_exec_eval.c | 2 +- mesalib/src/mesa/vbo/vbo_save.h | 2 +- mesalib/src/mesa/vbo/vbo_save_api.c | 22 +- pixman/configure.ac | 7 + pixman/demos/scale.c | 6 +- pixman/pixman/Makefile.win32 | 29 +- pixman/pixman/pixman-combine32.c | 671 ++++++++++++--------- pixman/pixman/pixman-mmx.c | 2 +- pixman/pixman/pixman-sse2.c | 69 ++- pixman/test/Makefile.win32 | 6 +- pixman/test/blitters-test.c | 2 +- pixman/test/thread-test.c | 17 +- pixman/test/utils.h | 5 + xkbcomp/compat.c | 2 +- xorg-server/configure.ac | 3 + xorg-server/dix/events.c | 22 +- xorg-server/dix/inpututils.c | 30 +- xorg-server/hw/kdrive/ephyr/ephyrdriext.c | 2 +- xorg-server/hw/kdrive/ephyr/hostx.c | 2 + xorg-server/hw/xquartz/GL/visualConfigs.c | 2 - xorg-server/hw/xwin/glx/indirect.c | 6 - xorg-server/include/input.h | 6 +- xorg-server/miext/rootless/rootlessWindow.c | 6 +- 114 files changed, 2754 insertions(+), 1513 deletions(-) create mode 100644 mesalib/docs/relnotes/10.0.html delete mode 100644 mesalib/docs/relnotes/9.3.html delete mode 100644 mesalib/src/glsl/.dir-locals.el delete mode 100644 mesalib/src/mesa/drivers/dri/common/drisw_util.c diff --git a/fontconfig/README b/fontconfig/README index 06f862b21..d2288a559 100644 --- a/fontconfig/README +++ b/fontconfig/README @@ -1,12 +1,37 @@ Fontconfig Font configuration and customization library - Version 2.10.95 (2.11 RC5) - 2013-08-31 + Version 2.11 + 2013-10-11 Check INSTALL for compilation and installation instructions. Report bugs to https://bugs.freedesktop.org in the fontconfig module. +2.11 + +Akira TAGOH (15): + Do not create a config dir for migration when no config files nor dirs + Add a test case of the migration for config place + Fix memory leaks in FcFreeTypeQueryFace + Bug 68955 - Deprecate / remove FC_RASTERIZER + Copy all values from the font to the pattern if the pattern doesn't have the element + Fix a crash when FcPattern is set to null on FcFontSetList() and FcFontList() + Add the description of -q option to the man page + avoid reading config.h twice + clean up + Add the relative path for to fonts.conf if the parent path is same to fonts.conf + Workaround the race condition issue on updating cache + exit with the error code when FcNameParse() failed + Add missing doc for FcStrListFirst and fix a typo + Bump libtool revision + Update CaseFolding.txt to Unicode 6.3 + +Jan Alexander Steffens (heftig) (1): + Further changes to 30-metric-aliases.conf + +W. Trevor King (1): + doc/fccharset.fncs: Describe the map format in more detail + 2.10.95 (2.11 RC5) Akira TAGOH (2): diff --git a/fontconfig/configure.ac b/fontconfig/configure.ac index 4b631bd53..c3743f435 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.95], [https://bugs.freedesktop.org/enter_bug.cgi?product=fontconfig]) +AC_INIT([fontconfig], [2.11.0], [https://bugs.freedesktop.org/enter_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=8 +LIBT_CURRENT=9 LIBT_REVISION=0 AC_SUBST(LIBT_CURRENT) AC_SUBST(LIBT_REVISION) -LIBT_AGE=7 +LIBT_AGE=8 LIBT_VERSION_INFO="$LIBT_CURRENT:$LIBT_REVISION:$LIBT_AGE" AC_SUBST(LIBT_VERSION_INFO) diff --git a/fontconfig/doc/fcstrset.fncs b/fontconfig/doc/fcstrset.fncs index 737347b00..b96489a43 100644 --- a/fontconfig/doc/fcstrset.fncs +++ b/fontconfig/doc/fcstrset.fncs @@ -98,12 +98,20 @@ Destroys set. Creates an iterator to list the strings in set. @@ +@RET@ void +@FUNC@ FcStrListFirst +@TYPE1@ FcStrList * @ARG1@ list +@PURPOSE@ get first string in iteration +@DESC@ +Returns the first string in list. +@@ + @RET@ FcChar8 * @FUNC@ FcStrListNext @TYPE1@ FcStrList * @ARG1@ list @PURPOSE@ get next string in iteration @DESC@ -Returns the next string in set. +Returns the next string in list. @@ @RET@ void diff --git a/fontconfig/fc-case/CaseFolding.txt b/fontconfig/fc-case/CaseFolding.txt index df1813d2a..cf5779f40 100644 --- a/fontconfig/fc-case/CaseFolding.txt +++ b/fontconfig/fc-case/CaseFolding.txt @@ -1,8 +1,8 @@ -# CaseFolding-6.2.0.txt -# Date: 2012-08-14, 17:54:49 GMT [MD] +# CaseFolding-6.3.0.txt +# Date: 2012-12-20, 22:14:35 GMT [MD] # # Unicode Character Database -# Copyright (c) 1991-2012 Unicode, Inc. +# Copyright (c) 1991-2013 Unicode, Inc. # For terms of use, see http://www.unicode.org/terms_of_use.html # For documentation, see http://www.unicode.org/reports/tr44/ # diff --git a/fontconfig/fontconfig/fontconfig.h b/fontconfig/fontconfig/fontconfig.h index e58857972..dfc48f9e3 100644 --- a/fontconfig/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig/fontconfig.h @@ -51,8 +51,8 @@ typedef int FcBool; */ #define FC_MAJOR 2 -#define FC_MINOR 10 -#define FC_REVISION 95 +#define FC_MINOR 11 +#define FC_REVISION 0 #define FC_VERSION ((FC_MAJOR * 10000) + (FC_MINOR * 100) + (FC_REVISION)) diff --git a/fontconfig/test/Makefile.am b/fontconfig/test/Makefile.am index 52c63dc41..f270b5071 100644 --- a/fontconfig/test/Makefile.am +++ b/fontconfig/test/Makefile.am @@ -16,7 +16,7 @@ TESTDATA=4x6.pcf 8x16.pcf out.expected fonts.conf.in AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir) -check_PROGRAMS = test-migration +check_PROGRAMS = if HAVE_PTHREAD check_PROGRAMS += test-pthread test_pthread_LDADD = $(top_builddir)/src/libfontconfig.la @@ -26,7 +26,10 @@ test_pthread_LDADD = $(top_builddir)/src/libfontconfig.la endif noinst_PROGRAMS = $(check_PROGRAMS) +if !OS_WIN32 +check_PROGRAMS += test-migration test_migration_LDADD = $(top_builddir)/src/libfontconfig.la +endif EXTRA_DIST=$(check_SCRIPTS) $(TESTDATA) diff --git a/libxcb/src/xcb_util.c b/libxcb/src/xcb_util.c index 463d085f6..466dc23bc 100644 --- a/libxcb/src/xcb_util.c +++ b/libxcb/src/xcb_util.c @@ -168,7 +168,11 @@ static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen); static int _xcb_open(const char *host, char *protocol, const int display) { int fd; +#ifdef __hpux + static const char unix_base[] = "/usr/spool/sockets/X11/"; +#else static const char unix_base[] = "/tmp/.X11-unix/X"; +#endif const char *base = unix_base; size_t filelen; char *file = NULL; diff --git a/libxcb/xcb-proto/src/composite.xml b/libxcb/xcb-proto/src/composite.xml index 535a0eecf..86de14629 100644 --- a/libxcb/xcb-proto/src/composite.xml +++ b/libxcb/xcb-proto/src/composite.xml @@ -32,8 +32,8 @@ authorization from the authors. xfixes - - + 0 + 1 diff --git a/libxcb/xcb-proto/src/damage.xml b/libxcb/xcb-proto/src/damage.xml index 9c5cde5b6..c04721d1e 100644 --- a/libxcb/xcb-proto/src/damage.xml +++ b/libxcb/xcb-proto/src/damage.xml @@ -35,10 +35,10 @@ authorization from the authors. - - - - + 0 + 1 + 2 + 3 diff --git a/libxcb/xcb-proto/src/dpms.xml b/libxcb/xcb-proto/src/dpms.xml index 0c2ac2027..55812845f 100644 --- a/libxcb/xcb-proto/src/dpms.xml +++ b/libxcb/xcb-proto/src/dpms.xml @@ -66,10 +66,10 @@ authorization from the authors. - - - - + 0 + 1 + 2 + 3 diff --git a/libxcb/xcb-proto/src/dri2.xml b/libxcb/xcb-proto/src/dri2.xml index 508e4c1fc..0160c6ba8 100644 --- a/libxcb/xcb-proto/src/dri2.xml +++ b/libxcb/xcb-proto/src/dri2.xml @@ -32,22 +32,22 @@ authorization from the authors. xproto - - - - - - - - - - - + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 - - + 0 + 1 diff --git a/libxcb/xcb-proto/src/randr.xml b/libxcb/xcb-proto/src/randr.xml index 1ec3234fb..d9192b216 100644 --- a/libxcb/xcb-proto/src/randr.xml +++ b/libxcb/xcb-proto/src/randr.xml @@ -248,9 +248,9 @@ authorization from the authors. - - - + 0 + 1 + 2 @@ -752,11 +752,10 @@ authorization from the authors. - - + diff --git a/libxcb/xcb-proto/src/render.xml b/libxcb/xcb-proto/src/render.xml index 9667fbeb6..55b73f7b8 100644 --- a/libxcb/xcb-proto/src/render.xml +++ b/libxcb/xcb-proto/src/render.xml @@ -11,84 +11,84 @@ for licensing information. xproto - - + 0 + 1 - + 0 - - - - - - - - - - - - - - + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 - 16 - - - - - - - - - - - + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 - 32 - - - - - - - - - - - + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 - 48 - - - - - - - - - - - - - - + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 - - + 0 + 1 - - + 0 + 1 @@ -108,20 +108,20 @@ for licensing information. - - - - - - + 0 + 1 + 2 + 3 + 4 + 5 - - - - + 0 + 1 + 2 + 3 diff --git a/libxcb/xcb-proto/src/screensaver.xml b/libxcb/xcb-proto/src/screensaver.xml index 7449c0a0b..491869e81 100644 --- a/libxcb/xcb-proto/src/screensaver.xml +++ b/libxcb/xcb-proto/src/screensaver.xml @@ -36,9 +36,9 @@ Draft Standard Version 1.1 xproto - - - + 0 + 1 + 2 @@ -47,10 +47,10 @@ Draft Standard Version 1.1 - - - - + 0 + 1 + 2 + 3 diff --git a/libxcb/xcb-proto/src/shape.xml b/libxcb/xcb-proto/src/shape.xml index c128ade32..d75549e05 100644 --- a/libxcb/xcb-proto/src/shape.xml +++ b/libxcb/xcb-proto/src/shape.xml @@ -34,18 +34,18 @@ authorization from the authors. - - - - - + 0 + 1 + 2 + 3 + 4 - - - + 0 + 1 + 2 diff --git a/libxcb/xcb-proto/src/sync.xml b/libxcb/xcb-proto/src/sync.xml index 8a5194752..7bcf0ae32 100644 --- a/libxcb/xcb-proto/src/sync.xml +++ b/libxcb/xcb-proto/src/sync.xml @@ -11,9 +11,9 @@ for licensing information. - - - + 0 + 1 + 2 @@ -21,15 +21,15 @@ for licensing information. - - - - + 0 + 1 + 2 + 3 - - + 0 + 1 diff --git a/libxcb/xcb-proto/src/xcb.xsd b/libxcb/xcb-proto/src/xcb.xsd index 819495b95..7a9c80018 100644 --- a/libxcb/xcb-proto/src/xcb.xsd +++ b/libxcb/xcb-proto/src/xcb.xsd @@ -353,7 +353,10 @@ authorization from the authors. - + + + + diff --git a/libxcb/xcb-proto/src/xevie.xml b/libxcb/xcb-proto/src/xevie.xml index 222b412e4..bafa9900b 100644 --- a/libxcb/xcb-proto/src/xevie.xml +++ b/libxcb/xcb-proto/src/xevie.xml @@ -55,8 +55,8 @@ authorization from the authors. - - + 0 + 1 - - - - - - + 0 + 1 + 2 + 3 + 4 + 5 @@ -437,12 +437,12 @@ authorization from the authors. - - - - - - + 0 + 1 + 2 + 3 + 4 + 5 @@ -1099,8 +1099,8 @@ authorization from the authors. - - + 0 + 1 @@ -1463,8 +1463,8 @@ authorization from the authors. - - + 0 + 1 @@ -1498,14 +1498,14 @@ authorization from the authors. - - - - - - - - + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 @@ -1520,17 +1520,17 @@ authorization from the authors. - - - + 0 + 1 + 2 - - - - - + 0 + 1 + 2 + 3 + 4 @@ -1822,12 +1822,12 @@ authorization from the authors. - - - - - - + 0 + 1 + 2 + 3 + 4 + 5 @@ -1947,23 +1947,23 @@ authorization from the authors. - - - - - - + 0 + 1 + 2 + 3 + 4 + 5 - - - - - - - - + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 @@ -2029,9 +2029,9 @@ authorization from the authors. - - - + 0 + 1 + 2 @@ -2131,7 +2131,7 @@ authorization from the authors. - + 0 diff --git a/libxcb/xcb-proto/src/xkb.xml b/libxcb/xcb-proto/src/xkb.xml index b702cad43..45f64127e 100644 --- a/libxcb/xcb-proto/src/xkb.xml +++ b/libxcb/xcb-proto/src/xkb.xml @@ -648,6 +648,7 @@ authorization from the authors. + @@ -1002,6 +1003,7 @@ authorization from the authors. + @@ -2610,7 +2612,7 @@ authorization from the authors. - + diff --git a/libxcb/xcb-proto/src/xproto.xml b/libxcb/xcb-proto/src/xproto.xml index c97919bef..16e04b442 100644 --- a/libxcb/xcb-proto/src/xproto.xml +++ b/libxcb/xcb-proto/src/xproto.xml @@ -889,74 +889,74 @@ A timestamp of the server time when the property was changed. 0 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 diff --git a/libxcb/xcb-proto/src/xv.xml b/libxcb/xcb-proto/src/xv.xml index d2bfc2992..a05767c53 100644 --- a/libxcb/xcb-proto/src/xv.xml +++ b/libxcb/xcb-proto/src/xv.xml @@ -44,13 +44,13 @@ authorization from the authors. - - + 0 + 1 - - + 0 + 1 @@ -59,25 +59,25 @@ authorization from the authors. - - - - - + 0 + 1 + 2 + 3 + 4 - - + 0 + 1 - - - - - - + 0 + 1 + 2 + 3 + 4 + 5 diff --git a/mesalib/VERSION b/mesalib/VERSION index b26064902..8e92e8350 100644 --- a/mesalib/VERSION +++ b/mesalib/VERSION @@ -1 +1 @@ -9.3.0-devel +10.0.0-devel diff --git a/mesalib/configure.ac b/mesalib/configure.ac index 954616318..08344c501 100644 --- a/mesalib/configure.ac +++ b/mesalib/configure.ac @@ -1025,8 +1025,6 @@ if test "x$enable_dri" = xyes; then if test "x$have_libdrm" != xyes; then AC_MSG_ERROR([DRI drivers requires libdrm >= $LIBDRM_REQUIRED]) fi - # ... and build dricommon - HAVE_COMMON_DRI=yes fi # put all the necessary libs together @@ -1255,20 +1253,8 @@ AM_CONDITIONAL(HAVE_ST_XORG, test "x$enable_xorg" = xyes) dnl dnl XA configuration dnl -if test "x$enable_xa" = xyes; then -AC_PROG_AWK -AC_PROG_GREP -AC_CHECK_PROG(NM, nm, "nm") -if test "x$AWK" = x || test "x$GREP" = x || test "x$NM" = x; then -AC_MSG_WARN([Missing one of nm, grep or awk. Disabling xa.]) -enable_xa=no -fi -fi if test "x$enable_xa" = xyes; then GALLIUM_STATE_TRACKERS_DIRS="xa $GALLIUM_STATE_TRACKERS_DIRS" - AC_SUBST(AWK) - AC_SUBST(GREP) - AC_SUBST(NM) fi AM_CONDITIONAL(HAVE_ST_XA, test "x$enable_xa" = xyes) @@ -1532,8 +1518,9 @@ AC_ARG_WITH([llvm-shared-libs], [with_llvm_shared_libs=no]) AS_IF([test x$enable_opencl = xyes], [ - AC_MSG_WARN([OpenCL required, forcing LLVM shared libraries]) - with_llvm_shared_libs=yes + if test "x$with_llvm_shared_libs" != xyes; then + AC_MSG_ERROR([OpenCL requires LLVM shared libraries]) + fi ]) AC_ARG_WITH([llvm-prefix], @@ -1680,7 +1667,6 @@ gallium_check_st() { fi if test "x$enable_dri" = xyes && test "x$2" != x; then GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $2" - HAVE_COMMON_DRI=yes fi if test "x$enable_xorg" = xyes && test "x$3" != x; then GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $3" @@ -1823,7 +1809,6 @@ if test "x$with_gallium_drivers" != x; then if test "x$enable_dri" = xyes; then GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS dri-swrast" - HAVE_COMMON_DRI=yes fi if test "x$enable_vdpau" = xyes; then GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS vdpau-softpipe" @@ -1927,7 +1912,6 @@ 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(NEED_RADEON_DRM_WINSYS, test "x$NEED_NONNULL_WINSYS" = xyes -a \ "x$HAVE_GALLIUM_R300" = xyes -o \ @@ -1942,7 +1926,6 @@ AM_CONDITIONAL(HAVE_LOADER_GALLIUM, test x$enable_gallium_loader = xyes) AM_CONDITIONAL(HAVE_DRM_LOADER_GALLIUM, test x$enable_gallium_drm_loader = xyes) AM_CONDITIONAL(HAVE_GALLIUM_COMPUTE, test x$enable_opencl = xyes) AM_CONDITIONAL(HAVE_MESA_LLVM, test x$MESA_LLVM = x1) -AM_CONDITIONAL(LLVM_NEEDS_FNORTTI, test $LLVM_VERSION_INT -ge 302) AC_SUBST([ELF_LIB]) @@ -1958,8 +1941,6 @@ AM_CONDITIONAL(HAVE_X86_ASM, echo "$DEFINES" | grep 'X86_ASM' >/dev/null 2>&1) AM_CONDITIONAL(HAVE_X86_64_ASM, echo "$DEFINES" | grep 'X86_64_ASM' >/dev/null 2>&1) AM_CONDITIONAL(HAVE_SPARC_ASM, echo "$DEFINES" | grep 'SPARC_ASM' >/dev/null 2>&1) -AM_CONDITIONAL(CROSS_COMPILING, test "x$cross_compiling" = xyes) - AC_SUBST([VDPAU_MAJOR], 1) AC_SUBST([VDPAU_MINOR], 0) diff --git a/mesalib/docs/relnotes.html b/mesalib/docs/relnotes.html index 5929359e0..82072ddfa 100644 --- a/mesalib/docs/relnotes.html +++ b/mesalib/docs/relnotes.html @@ -21,7 +21,7 @@ The release notes summarize what's new or changed in each Mesa release.

    -
  • 9.3 release notes +
  • 10.0 release notes
  • 9.2.1 release notes
  • 9.2 release notes
  • 9.1.7 release notes diff --git a/mesalib/docs/relnotes/10.0.html b/mesalib/docs/relnotes/10.0.html new file mode 100644 index 000000000..8f97921b0 --- /dev/null +++ b/mesalib/docs/relnotes/10.0.html @@ -0,0 +1,65 @@ + + + + + Mesa Release Notes + + + + +
    +

    The Mesa 3D Graphics Library

    +
    + + +
    + +

    Mesa 10.0 Release Notes / TBD

    + +

    +Mesa 10.0 is a new development release. +People who are concerned with stability and reliability should stick +with a previous release or wait for Mesa 10.0.1. +

    +

    +Mesa 10.0 implements the OpenGL 3.2 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.2. OpenGL +3.2 is only available if requested at context creation +because compatibility contexts are not supported. +

    + + +

    MD5 checksums

    +
    +TBD.
    +
    + + +

    New features

    + +

    +Note: some of the new features are only available with certain drivers. +

    + +
      +
    • GL_AMD_seamless_cubemap_per_texture on i965.
    • +
    • GL_ARB_conservative_depth on i965.
    • +
    • GL_ARB_texture_gather on i965.
    • +
    • GL_ARB_texture_query_levels on i965.
    • +
    • GL_KHR_debug
    • +
    + + +

    Bug fixes

    + +TBD. + +

    Changes

    + +TBD. + +
    + + diff --git a/mesalib/docs/relnotes/9.3.html b/mesalib/docs/relnotes/9.3.html deleted file mode 100644 index 58a88b036..000000000 --- a/mesalib/docs/relnotes/9.3.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - Mesa Release Notes - - - - -
    -

    The Mesa 3D Graphics Library

    -
    - - -
    - -

    Mesa 9.3 Release Notes / TBD

    - -

    -Mesa 9.3 is a new development release. -People who are concerned with stability and reliability should stick -with a previous release or wait for Mesa 9.3.1. -

    -

    -Mesa 9.3 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

    -
    -TBD.
    -
    - - -

    New features

    - -

    -Note: some of the new features are only available with certain drivers. -

    - -
      -
    • GL_AMD_seamless_cubemap_per_texture on i965.
    • -
    • GL_ARB_conservative_depth on i965.
    • -
    • GL_ARB_texture_gather on i965.
    • -
    • GL_ARB_texture_query_levels on i965.
    • -
    • GL_KHR_debug
    • -
    - - -

    Bug fixes

    - -TBD. - -

    Changes

    - -TBD. - -
    - - diff --git a/mesalib/include/GL/internal/dri_interface.h b/mesalib/include/GL/internal/dri_interface.h index 709fece8d..33b41ea3b 100644 --- a/mesalib/include/GL/internal/dri_interface.h +++ b/mesalib/include/GL/internal/dri_interface.h @@ -964,6 +964,8 @@ struct __DRIdri2ExtensionRec { #define __DRI_IMAGE_FORMAT_R8 0x1006 /* Since version 5 */ #define __DRI_IMAGE_FORMAT_GR88 0x1007 #define __DRI_IMAGE_FORMAT_NONE 0x1008 +#define __DRI_IMAGE_FORMAT_XRGB2101010 0x1009 +#define __DRI_IMAGE_FORMAT_ARGB2101010 0x100a #define __DRI_IMAGE_USE_SHARE 0x0001 #define __DRI_IMAGE_USE_SCANOUT 0x0002 diff --git a/mesalib/scons/llvm.py b/mesalib/scons/llvm.py index 7cd609c20..34b58910a 100644 --- a/mesalib/scons/llvm.py +++ b/mesalib/scons/llvm.py @@ -190,14 +190,14 @@ def generate(env): pass env.MergeFlags(cppflags) + cxxflags = env.backtick('llvm-config --cxxflags').rstrip() + env.Append(LLVM_CXXFLAGS = cxxflags) + components = ['engine', 'bitwriter', 'x86asmprinter'] if llvm_version >= distutils.version.LooseVersion('3.1'): components.append('mcjit') - if llvm_version >= distutils.version.LooseVersion('3.2'): - env.Append(CXXFLAGS = ('-fno-rtti',)) - env.ParseConfig('llvm-config --libs ' + ' '.join(components)) env.ParseConfig('llvm-config --ldflags') except OSError: diff --git a/mesalib/src/gallium/auxiliary/Makefile.am b/mesalib/src/gallium/auxiliary/Makefile.am index 670e1248d..2d2d8d484 100644 --- a/mesalib/src/gallium/auxiliary/Makefile.am +++ b/mesalib/src/gallium/auxiliary/Makefile.am @@ -25,12 +25,6 @@ AM_CXXFLAGS += \ $(GALLIUM_CFLAGS) \ $(LLVM_CXXFLAGS) -if LLVM_NEEDS_FNORTTI - -AM_CXXFLAGS += -fno-rtti - -endif - libgallium_la_SOURCES += \ $(GALLIVM_SOURCES) \ $(GALLIVM_CPP_SOURCES) diff --git a/mesalib/src/gallium/auxiliary/SConscript b/mesalib/src/gallium/auxiliary/SConscript index 31dfed316..3ac311225 100644 --- a/mesalib/src/gallium/auxiliary/SConscript +++ b/mesalib/src/gallium/auxiliary/SConscript @@ -46,6 +46,8 @@ source = env.ParseSourceList('Makefile.sources', [ ]) if env['llvm']: + env.Append(CXXFLAGS = env['LLVM_CXXFLAGS']) + source += env.ParseSourceList('Makefile.sources', [ 'GALLIVM_SOURCES', 'GALLIVM_CPP_SOURCES' diff --git a/mesalib/src/gallium/auxiliary/util/u_math.h b/mesalib/src/gallium/auxiliary/util/u_math.h index 478a4aa4d..f5c14ef8d 100644 --- a/mesalib/src/gallium/auxiliary/util/u_math.h +++ b/mesalib/src/gallium/auxiliary/util/u_math.h @@ -162,7 +162,7 @@ float log2f(float f) #endif -#if __STDC_VERSION__ < 199901L && !defined(__cplusplus) +#if __STDC_VERSION__ < 199901L && (!defined(__cplusplus) || defined(_MSC_VER)) static INLINE long int lrint(double d) { diff --git a/mesalib/src/glsl/.dir-locals.el b/mesalib/src/glsl/.dir-locals.el deleted file mode 100644 index be19e29a5..000000000 --- a/mesalib/src/glsl/.dir-locals.el +++ /dev/null @@ -1,3 +0,0 @@ -((c-mode . ((c-basic-offset . 3))) - (c++-mode . ((c-basic-offset . 3))) -) diff --git a/mesalib/src/glsl/Makefile.am b/mesalib/src/glsl/Makefile.am index 2e161b844..cbf253cb5 100644 --- a/mesalib/src/glsl/Makefile.am +++ b/mesalib/src/glsl/Makefile.am @@ -49,6 +49,8 @@ check_PROGRAMS = \ tests/sampler-types-test \ tests/uniform-initializer-test +noinst_PROGRAMS = glsl_compiler + tests_uniform_initializer_test_SOURCES = \ $(top_srcdir)/src/mesa/main/hash_table.c \ $(top_srcdir)/src/mesa/main/imports.c \ @@ -99,6 +101,15 @@ libglsl_la_SOURCES = \ glsl_parser.cpp \ $(LIBGLSL_FILES) +glsl_compiler_SOURCES = \ + $(top_srcdir)/src/mesa/main/hash_table.c \ + $(top_srcdir)/src/mesa/main/imports.c \ + $(top_srcdir)/src/mesa/program/prog_hash_table.c \ + $(top_srcdir)/src/mesa/program/symbol_table.c \ + $(GLSL_COMPILER_CXX_FILES) + +glsl_compiler_LDADD = libglsl.la + glsl_test_SOURCES = \ $(top_srcdir)/src/mesa/main/hash_table.c \ $(top_srcdir)/src/mesa/main/imports.c \ diff --git a/mesalib/src/glsl/SConscript b/mesalib/src/glsl/SConscript index e386bdfb1..fe9d50732 100644 --- a/mesalib/src/glsl/SConscript +++ b/mesalib/src/glsl/SConscript @@ -98,11 +98,11 @@ if env['platform'] == 'windows': env.Prepend(LIBS = [glsl]) -glsl2 = env.Program( - target = 'glsl2', +glsl_compiler = env.Program( + target = 'glsl_compiler', source = compiler_objs, ) -env.Alias('glsl2', glsl2) +env.Alias('glsl_compiler', glsl_compiler) glcpp = env.Program( target = 'glcpp/glcpp', diff --git a/mesalib/src/glsl/ast_array_index.cpp b/mesalib/src/glsl/ast_array_index.cpp index 51f6b10f3..da96cc10e 100644 --- a/mesalib/src/glsl/ast_array_index.cpp +++ b/mesalib/src/glsl/ast_array_index.cpp @@ -25,6 +25,71 @@ #include "glsl_types.h" #include "ir.h" + +/** + * If \c ir is a reference to an array for which we are tracking the max array + * element accessed, track that the given element has been accessed. + * Otherwise do nothing. + * + * This function also checks whether the array is a built-in array whose + * maximum size is too small to accommodate the given index, and if so uses + * loc and state to report the error. + */ +static void +update_max_array_access(ir_rvalue *ir, unsigned idx, YYLTYPE *loc, + struct _mesa_glsl_parse_state *state) +{ + if (ir_dereference_variable *deref_var = ir->as_dereference_variable()) { + ir_variable *var = deref_var->var; + if (idx > var->max_array_access) { + var->max_array_access = idx; + + /* Check whether this access will, as a side effect, implicitly cause + * the size of a built-in array to be too large. + */ + check_builtin_array_max_size(var->name, idx+1, *loc, state); + } + } else if (ir_dereference_record *deref_record = + ir->as_dereference_record()) { + /* There are two possibilities we need to consider: + * + * - Accessing an element of an array that is a member of a named + * interface block (e.g. ifc.foo[i]) + * + * - Accessing an element of an array that is a member of a named + * interface block array (e.g. ifc[j].foo[i]). + */ + ir_dereference_variable *deref_var = + deref_record->record->as_dereference_variable(); + if (deref_var == NULL) { + if (ir_dereference_array *deref_array = + deref_record->record->as_dereference_array()) { + deref_var = deref_array->array->as_dereference_variable(); + } + } + + if (deref_var != NULL) { + const glsl_type *interface_type = + deref_var->var->get_interface_type(); + if (interface_type != NULL) { + unsigned field_index = + deref_record->record->type->field_index(deref_record->field); + assert(field_index < interface_type->length); + if (idx > deref_var->var->max_ifc_array_access[field_index]) { + deref_var->var->max_ifc_array_access[field_index] = idx; + + /* Check whether this access will, as a side effect, implicitly + * cause the size of a built-in array to be too large. + */ + check_builtin_array_max_size(deref_record->field, idx+1, *loc, + state); + } + } + } + } +} + + ir_rvalue * _mesa_ast_array_index_to_hir(void *mem_ctx, struct _mesa_glsl_parse_state *state, @@ -97,23 +162,8 @@ _mesa_ast_array_index_to_hir(void *mem_ctx, type_name); } - if (array->type->is_array()) { - /* If the array is a variable dereference, it dereferences the - * whole array, by definition. Use this to get the variable. - * - * FINISHME: Should some methods for getting / setting / testing - * FINISHME: array access limits be added to ir_dereference? - */ - ir_variable *const v = array->whole_variable_referenced(); - if ((v != NULL) && (unsigned(idx) > v->max_array_access)) { - v->max_array_access = idx; - - /* Check whether this access will, as a side effect, implicitly - * cause the size of a built-in array to be too large. - */ - check_builtin_array_max_size(v->name, idx+1, loc, state); - } - } + if (array->type->is_array()) + update_max_array_access(array, idx, &loc, state); } else if (const_index == NULL && array->type->is_array()) { if (array->type->array_size() == 0) { _mesa_glsl_error(&loc, state, "unsized array index must be constant"); diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 0859d9e00..dfa32d920 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -2326,9 +2326,10 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, * A pointer to an existing variable in the current scope if the declaration * is a redeclaration, \c NULL otherwise. */ -ir_variable * -get_variable_being_redeclared(ir_variable *var, ast_declaration *decl, - struct _mesa_glsl_parse_state *state) +static ir_variable * +get_variable_being_redeclared(ir_variable *var, YYLTYPE loc, + struct _mesa_glsl_parse_state *state, + bool allow_all_redeclarations) { /* Check if this declaration is actually a re-declaration, either to * resize an array or add qualifiers to an existing variable. @@ -2336,16 +2337,14 @@ get_variable_being_redeclared(ir_variable *var, ast_declaration *decl, * This is allowed for variables in the current scope, or when at * global scope (for built-ins in the implicit outer scope). */ - ir_variable *earlier = state->symbols->get_variable(decl->identifier); + ir_variable *earlier = state->symbols->get_variable(var->name); if (earlier == NULL || (state->current_function != NULL && - !state->symbols->name_declared_this_scope(decl->identifier))) { + !state->symbols->name_declared_this_scope(var->name))) { return NULL; } - YYLTYPE loc = decl->get_location(); - /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec, * * "It is legal to declare an array without a size and then @@ -2433,8 +2432,18 @@ get_variable_being_redeclared(ir_variable *var, ast_declaration *decl, earlier->depth_layout = var->depth_layout; + } else if (allow_all_redeclarations) { + if (earlier->mode != var->mode) { + _mesa_glsl_error(&loc, state, + "redeclaration of `%s' with incorrect qualifiers", + var->name); + } else if (earlier->type != var->type) { + _mesa_glsl_error(&loc, state, + "redeclaration of `%s' has incorrect type", + var->name); + } } else { - _mesa_glsl_error(&loc, state, "`%s' redeclared", decl->identifier); + _mesa_glsl_error(&loc, state, "`%s' redeclared", var->name); } return earlier; @@ -2649,6 +2658,36 @@ handle_geometry_shader_input_decl(struct _mesa_glsl_parse_state *state, } } + +void +validate_identifier(const char *identifier, YYLTYPE loc, + struct _mesa_glsl_parse_state *state) +{ + /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, + * + * "Identifiers starting with "gl_" are reserved for use by + * OpenGL, and may not be declared in a shader as either a + * variable or a function." + */ + if (strncmp(identifier, "gl_", 3) == 0) { + _mesa_glsl_error(&loc, state, + "identifier `%s' uses reserved `gl_' prefix", + identifier); + } else if (strstr(identifier, "__")) { + /* From page 14 (page 20 of the PDF) of the GLSL 1.10 + * spec: + * + * "In addition, all identifiers containing two + * consecutive underscores (__) are reserved as + * possible future keywords." + */ + _mesa_glsl_error(&loc, state, + "identifier `%s' uses reserved `__' string", + identifier); + } +} + + ir_rvalue * ast_declarator_list::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) @@ -3191,7 +3230,9 @@ ast_declarator_list::hir(exec_list *instructions, * instruction stream. */ exec_list initializer_instructions; - ir_variable *earlier = get_variable_being_redeclared(var, decl, state); + ir_variable *earlier = + get_variable_being_redeclared(var, decl->get_location(), state, + false /* allow_all_redeclarations */); if (decl->initializer != NULL) { result = process_initializer((earlier == NULL) ? var : earlier, @@ -3243,28 +3284,7 @@ ast_declarator_list::hir(exec_list *instructions, * created for the declaration should be added to the IR stream. */ if (earlier == NULL) { - /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, - * - * "Identifiers starting with "gl_" are reserved for use by - * OpenGL, and may not be declared in a shader as either a - * variable or a function." - */ - if (strncmp(decl->identifier, "gl_", 3) == 0) - _mesa_glsl_error(& loc, state, - "identifier `%s' uses reserved `gl_' prefix", - decl->identifier); - else if (strstr(decl->identifier, "__")) { - /* From page 14 (page 20 of the PDF) of the GLSL 1.10 - * spec: - * - * "In addition, all identifiers containing two - * consecutive underscores (__) are reserved as - * possible future keywords." - */ - _mesa_glsl_error(& loc, state, - "identifier `%s' uses reserved `__' string", - decl->identifier); - } + validate_identifier(decl->identifier, loc, state); /* Add the variable to the symbol table. Note that the initializer's * IR was already processed earlier (though it hasn't been emitted @@ -3505,17 +3525,7 @@ ast_function::hir(exec_list *instructions, "function body", name); } - /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, - * - * "Identifiers starting with "gl_" are reserved for use by - * OpenGL, and may not be declared in a shader as either a - * variable or a function." - */ - if (strncmp(name, "gl_", 3) == 0) { - YYLTYPE loc = this->get_location(); - _mesa_glsl_error(&loc, state, - "identifier `%s' uses reserved `gl_' prefix", name); - } + validate_identifier(name, this->get_location(), state); /* Convert the list of function parameters to HIR now so that they can be * used below to compare this function's signature with previously seen @@ -4411,7 +4421,8 @@ ast_process_structure_or_interface_block(exec_list *instructions, YYLTYPE &loc, glsl_struct_field **fields_ret, bool is_interface, - bool block_row_major) + bool block_row_major, + bool allow_reserved_names) { unsigned decl_count = 0; @@ -4453,6 +4464,9 @@ ast_process_structure_or_interface_block(exec_list *instructions, foreach_list_typed (ast_declaration, decl, link, &decl_list->declarations) { + if (!allow_reserved_names) + validate_identifier(decl->identifier, loc, state); + /* From the GL_ARB_uniform_buffer_object spec: * * "Sampler types are not allowed inside of uniform @@ -4491,6 +4505,7 @@ ast_process_structure_or_interface_block(exec_list *instructions, } fields[i].type = field_type; fields[i].name = decl->identifier; + fields[i].location = -1; if (qual->flags.q.row_major || qual->flags.q.column_major) { if (!qual->flags.q.uniform) { @@ -4568,7 +4583,10 @@ ast_struct_specifier::hir(exec_list *instructions, loc, &fields, false, - false); + false, + false /* allow_reserved_names */); + + validate_identifier(this->name, loc, state); const glsl_type *t = glsl_type::get_record_instance(fields, decl_count, this->name); @@ -4593,6 +4611,39 @@ ast_struct_specifier::hir(exec_list *instructions, return NULL; } + +/** + * Visitor class which detects whether a given interface block has been used. + */ +class interface_block_usage_visitor : public ir_hierarchical_visitor +{ +public: + interface_block_usage_visitor(ir_variable_mode mode, const glsl_type *block) + : mode(mode), block(block), found(false) + { + } + + virtual ir_visitor_status visit(ir_dereference_variable *ir) + { + if (ir->var->mode == mode && ir->var->get_interface_type() == block) { + found = true; + return visit_stop; + } + return visit_continue; + } + + bool usage_found() const + { + return this->found; + } + +private: + ir_variable_mode mode; + const glsl_type *block; + bool found; +}; + + ir_rvalue * ast_interface_block::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) @@ -4614,6 +4665,7 @@ ast_interface_block::hir(exec_list *instructions, packing = GLSL_INTERFACE_PACKING_STD140; } + bool redeclaring_per_vertex = strcmp(this->block_name, "gl_PerVertex") == 0; bool block_row_major = this->layout.flags.q.row_major; exec_list declared_variables; glsl_struct_field *fields; @@ -4624,7 +4676,8 @@ ast_interface_block::hir(exec_list *instructions, loc, &fields, true, - block_row_major); + block_row_major, + redeclaring_per_vertex); ir_variable_mode var_mode; const char *iface_type_name; @@ -4643,6 +4696,102 @@ ast_interface_block::hir(exec_list *instructions, assert(!"interface block layout qualifier not found!"); } + if (!redeclaring_per_vertex) + validate_identifier(this->block_name, loc, state); + + const glsl_type *earlier_per_vertex = NULL; + if (redeclaring_per_vertex) { + /* Find the previous declaration of gl_PerVertex. If we're redeclaring + * the named interface block gl_in, we can find it by looking at the + * previous declaration of gl_in. Otherwise we can find it by looking + * at the previous decalartion of any of the built-in outputs, + * e.g. gl_Position. + * + * Also check that the instance name and array-ness of the redeclaration + * are correct. + */ + switch (var_mode) { + case ir_var_shader_in: + if (ir_variable *earlier_gl_in = + state->symbols->get_variable("gl_in")) { + earlier_per_vertex = earlier_gl_in->get_interface_type(); + } else { + _mesa_glsl_error(&loc, state, + "redeclaration of gl_PerVertex input not allowed " + "in the %s shader", + _mesa_glsl_shader_target_name(state->target)); + } + if (this->instance_name == NULL || + strcmp(this->instance_name, "gl_in") != 0 || !this->is_array) { + _mesa_glsl_error(&loc, state, + "gl_PerVertex input must be redeclared as " + "gl_in[]"); + } + break; + case ir_var_shader_out: + if (ir_variable *earlier_gl_Position = + state->symbols->get_variable("gl_Position")) { + earlier_per_vertex = earlier_gl_Position->get_interface_type(); + } else { + _mesa_glsl_error(&loc, state, + "redeclaration of gl_PerVertex output not " + "allowed in the %s shader", + _mesa_glsl_shader_target_name(state->target)); + } + if (this->instance_name != NULL) { + _mesa_glsl_error(&loc, state, + "gl_PerVertex input may not be redeclared with " + "an instance name"); + } + break; + default: + _mesa_glsl_error(&loc, state, + "gl_PerVertex must be declared as an input or an " + "output"); + break; + } + + if (earlier_per_vertex == NULL) { + /* An error has already been reported. Bail out to avoid null + * dereferences later in this function. + */ + return NULL; + } + + /* Copy locations from the old gl_PerVertex interface block. */ + for (unsigned i = 0; i < num_variables; i++) { + int j = earlier_per_vertex->field_index(fields[i].name); + if (j == -1) { + _mesa_glsl_error(&loc, state, + "redeclaration of gl_PerVertex must be a subset " + "of the built-in members of gl_PerVertex"); + } else { + fields[i].location = + earlier_per_vertex->fields.structure[j].location; + } + } + + /* From section 7.1 ("Built-in Language Variables") of the GLSL 4.10 + * spec: + * + * If a built-in interface block is redeclared, it must appear in + * the shader before any use of any member included in the built-in + * declaration, or a compilation error will result. + * + * This appears to be a clarification to the behaviour established for + * gl_PerVertex by GLSL 1.50, therefore we implement this behaviour + * regardless of GLSL version. + */ + interface_block_usage_visitor v(var_mode, earlier_per_vertex); + v.run(instructions); + if (v.usage_found()) { + _mesa_glsl_error(&loc, state, + "redeclaration of a built-in interface block must " + "appear before any use of any member of the " + "interface block"); + } + } + const glsl_type *block_type = glsl_type::get_interface_instance(fields, num_variables, @@ -4682,6 +4831,9 @@ ast_interface_block::hir(exec_list *instructions, * field selector ( . ) operator (analogously to structures)." */ if (this->instance_name) { + if (!redeclaring_per_vertex) + validate_identifier(this->instance_name, loc, state); + ir_variable *var; if (this->is_array) { @@ -4724,11 +4876,23 @@ ast_interface_block::hir(exec_list *instructions, var_mode); } - var->interface_type = block_type; + var->init_interface_type(block_type); if (state->target == geometry_shader && var_mode == ir_var_shader_in) handle_geometry_shader_input_decl(state, loc, var); - state->symbols->add_variable(var); - instructions->push_tail(var); + + if (ir_variable *earlier = + state->symbols->get_variable(this->instance_name)) { + if (!redeclaring_per_vertex) { + _mesa_glsl_error(&loc, state, "`%s' redeclared", + this->instance_name); + } + earlier->type = var->type; + earlier->reinit_interface_type(block_type); + delete var; + } else { + state->symbols->add_variable(var); + instructions->push_tail(var); + } } else { /* In order to have an array size, the block must also be declared with * an instane name. @@ -4740,7 +4904,24 @@ ast_interface_block::hir(exec_list *instructions, new(state) ir_variable(fields[i].type, ralloc_strdup(state, fields[i].name), var_mode); - var->interface_type = block_type; + var->init_interface_type(block_type); + + if (redeclaring_per_vertex) { + ir_variable *earlier = + get_variable_being_redeclared(var, loc, state, + true /* allow_all_redeclarations */); + if (strncmp(var->name, "gl_", 3) != 0 || earlier == NULL) { + _mesa_glsl_error(&loc, state, + "redeclaration of gl_PerVertex can only " + "include built-in variables"); + } else { + earlier->reinit_interface_type(block_type); + } + continue; + } + + if (state->symbols->get_variable(var->name) != NULL) + _mesa_glsl_error(&loc, state, "`%s' redeclared", var->name); /* Propagate the "binding" keyword into this UBO's fields; * the UBO declaration itself doesn't get an ir_variable unless it @@ -4752,6 +4933,38 @@ ast_interface_block::hir(exec_list *instructions, state->symbols->add_variable(var); instructions->push_tail(var); } + + if (redeclaring_per_vertex && block_type != earlier_per_vertex) { + /* From section 7.1 ("Built-in Language Variables") of the GLSL 4.10 spec: + * + * It is also a compilation error ... to redeclare a built-in + * block and then use a member from that built-in block that was + * not included in the redeclaration. + * + * This appears to be a clarification to the behaviour established + * for gl_PerVertex by GLSL 1.50, therefore we implement this + * behaviour regardless of GLSL version. + * + * To prevent the shader from using a member that was not included in + * the redeclaration, we disable any ir_variables that are still + * associated with the old declaration of gl_PerVertex (since we've + * already updated all of the variables contained in the new + * gl_PerVertex to point to it). + * + * As a side effect this will prevent + * validate_intrastage_interface_blocks() from getting confused and + * thinking there are conflicting definitions of gl_PerVertex in the + * shader. + */ + foreach_list_safe(node, instructions) { + ir_variable *const var = ((ir_instruction *) node)->as_variable(); + if (var != NULL && + var->get_interface_type() == earlier_per_vertex) { + state->symbols->disable_variable(var->name); + var->remove(); + } + } + } } return NULL; diff --git a/mesalib/src/glsl/builtin_functions.cpp b/mesalib/src/glsl/builtin_functions.cpp index b6451089c..d40888d38 100644 --- a/mesalib/src/glsl/builtin_functions.cpp +++ b/mesalib/src/glsl/builtin_functions.cpp @@ -531,6 +531,9 @@ private: B1(fma) B2(ldexp) B2(frexp) + B1(uaddCarry) + B1(usubBorrow) + B1(mulExtended) #undef B0 #undef B1 #undef B2 @@ -1947,6 +1950,30 @@ builtin_builder::create_builtins() _frexp(glsl_type::vec3_type, glsl_type::ivec3_type), _frexp(glsl_type::vec4_type, glsl_type::ivec4_type), NULL); + add_function("uaddCarry", + _uaddCarry(glsl_type::uint_type), + _uaddCarry(glsl_type::uvec2_type), + _uaddCarry(glsl_type::uvec3_type), + _uaddCarry(glsl_type::uvec4_type), + NULL); + add_function("usubBorrow", + _usubBorrow(glsl_type::uint_type), + _usubBorrow(glsl_type::uvec2_type), + _usubBorrow(glsl_type::uvec3_type), + _usubBorrow(glsl_type::uvec4_type), + NULL); + add_function("imulExtended", + _mulExtended(glsl_type::int_type), + _mulExtended(glsl_type::ivec2_type), + _mulExtended(glsl_type::ivec3_type), + _mulExtended(glsl_type::ivec4_type), + NULL); + add_function("umulExtended", + _mulExtended(glsl_type::uint_type), + _mulExtended(glsl_type::uvec2_type), + _mulExtended(glsl_type::uvec3_type), + _mulExtended(glsl_type::uvec4_type), + NULL); #undef F #undef FI #undef FIU @@ -3720,6 +3747,52 @@ builtin_builder::_frexp(const glsl_type *x_type, const glsl_type *exp_type) return sig; } + +ir_function_signature * +builtin_builder::_uaddCarry(const glsl_type *type) +{ + ir_variable *x = in_var(type, "x"); + ir_variable *y = in_var(type, "y"); + ir_variable *carry = out_var(type, "carry"); + MAKE_SIG(type, gpu_shader5, 3, x, y, carry); + + body.emit(assign(carry, ir_builder::carry(x, y))); + body.emit(ret(add(x, y))); + + return sig; +} + +ir_function_signature * +builtin_builder::_usubBorrow(const glsl_type *type) +{ + ir_variable *x = in_var(type, "x"); + ir_variable *y = in_var(type, "y"); + ir_variable *borrow = out_var(type, "borrow"); + MAKE_SIG(type, gpu_shader5, 3, x, y, borrow); + + body.emit(assign(borrow, ir_builder::borrow(x, y))); + body.emit(ret(sub(x, y))); + + return sig; +} + +/** + * For both imulExtended() and umulExtended() built-ins. + */ +ir_function_signature * +builtin_builder::_mulExtended(const glsl_type *type) +{ + ir_variable *x = in_var(type, "x"); + ir_variable *y = in_var(type, "y"); + ir_variable *msb = out_var(type, "msb"); + ir_variable *lsb = out_var(type, "lsb"); + MAKE_SIG(glsl_type::void_type, gpu_shader5, 4, x, y, msb, lsb); + + body.emit(assign(msb, imul_high(x, y))); + body.emit(assign(lsb, mul(x, y))); + + return sig; +} /** @} */ /******************************************************************************/ diff --git a/mesalib/src/glsl/builtin_types.cpp b/mesalib/src/glsl/builtin_types.cpp index 722eda2da..1a5e5a190 100644 --- a/mesalib/src/glsl/builtin_types.cpp +++ b/mesalib/src/glsl/builtin_types.cpp @@ -53,64 +53,64 @@ &glsl_type::_struct_##NAME##_type; static const struct glsl_struct_field gl_DepthRangeParameters_fields[] = { - { glsl_type::float_type, "near", false }, - { glsl_type::float_type, "far", false }, - { glsl_type::float_type, "diff", false }, + { glsl_type::float_type, "near", false, -1 }, + { glsl_type::float_type, "far", false, -1 }, + { glsl_type::float_type, "diff", false, -1 }, }; static const struct glsl_struct_field gl_PointParameters_fields[] = { - { glsl_type::float_type, "size", false }, - { glsl_type::float_type, "sizeMin", false }, - { glsl_type::float_type, "sizeMax", false }, - { glsl_type::float_type, "fadeThresholdSize", false }, - { glsl_type::float_type, "distanceConstantAttenuation", false }, - { glsl_type::float_type, "distanceLinearAttenuation", false }, - { glsl_type::float_type, "distanceQuadraticAttenuation", false }, + { glsl_type::float_type, "size", false, -1 }, + { glsl_type::float_type, "sizeMin", false, -1 }, + { glsl_type::float_type, "sizeMax", false, -1 }, + { glsl_type::float_type, "fadeThresholdSize", false, -1 }, + { glsl_type::float_type, "distanceConstantAttenuation", false, -1 }, + { glsl_type::float_type, "distanceLinearAttenuation", false, -1 }, + { glsl_type::float_type, "distanceQuadraticAttenuation", false, -1 }, }; static const struct glsl_struct_field gl_MaterialParameters_fields[] = { - { glsl_type::vec4_type, "emission", false }, - { glsl_type::vec4_type, "ambient", false }, - { glsl_type::vec4_type, "diffuse", false }, - { glsl_type::vec4_type, "specular", false }, - { glsl_type::float_type, "shininess", false }, + { glsl_type::vec4_type, "emission", false, -1 }, + { glsl_type::vec4_type, "ambient", false, -1 }, + { glsl_type::vec4_type, "diffuse", false, -1 }, + { glsl_type::vec4_type, "specular", false, -1 }, + { glsl_type::float_type, "shininess", false, -1 }, }; static const struct glsl_struct_field gl_LightSourceParameters_fields[] = { - { glsl_type::vec4_type, "ambient", false }, - { glsl_type::vec4_type, "diffuse", false }, - { glsl_type::vec4_type, "specular", false }, - { glsl_type::vec4_type, "position", false }, - { glsl_type::vec4_type, "halfVector", false }, - { glsl_type::vec3_type, "spotDirection", false }, - { glsl_type::float_type, "spotExponent", false }, - { glsl_type::float_type, "spotCutoff", false }, - { glsl_type::float_type, "spotCosCutoff", false }, - { glsl_type::float_type, "constantAttenuation", false }, - { glsl_type::float_type, "linearAttenuation", false }, - { glsl_type::float_type, "quadraticAttenuation", false }, + { glsl_type::vec4_type, "ambient", false, -1 }, + { glsl_type::vec4_type, "diffuse", false, -1 }, + { glsl_type::vec4_type, "specular", false, -1 }, + { glsl_type::vec4_type, "position", false, -1 }, + { glsl_type::vec4_type, "halfVector", false, -1 }, + { glsl_type::vec3_type, "spotDirection", false, -1 }, + { glsl_type::float_type, "spotExponent", false, -1 }, + { glsl_type::float_type, "spotCutoff", false, -1 }, + { glsl_type::float_type, "spotCosCutoff", false, -1 }, + { glsl_type::float_type, "constantAttenuation", false, -1 }, + { glsl_type::float_type, "linearAttenuation", false, -1 }, + { glsl_type::float_type, "quadraticAttenuation", false, -1 }, }; static const struct glsl_struct_field gl_LightModelParameters_fields[] = { - { glsl_type::vec4_type, "ambient", false }, + { glsl_type::vec4_type, "ambient", false, -1 }, }; static const struct glsl_struct_field gl_LightModelProducts_fields[] = { - { glsl_type::vec4_type, "sceneColor", false }, + { glsl_type::vec4_type, "sceneColor", false, -1 }, }; static const struct glsl_struct_field gl_LightProducts_fields[] = { - { glsl_type::vec4_type, "ambient", false }, - { glsl_type::vec4_type, "diffuse", false }, - { glsl_type::vec4_type, "specular", false }, + { glsl_type::vec4_type, "ambient", false, -1 }, + { glsl_type::vec4_type, "diffuse", false, -1 }, + { glsl_type::vec4_type, "specular", false, -1 }, }; static const struct glsl_struct_field gl_FogParameters_fields[] = { - { glsl_type::vec4_type, "color", false }, - { glsl_type::float_type, "density", false }, - { glsl_type::float_type, "start", false }, - { glsl_type::float_type, "end", false }, - { glsl_type::float_type, "scale", false }, + { glsl_type::vec4_type, "color", false, -1 }, + { glsl_type::float_type, "density", false, -1 }, + { glsl_type::float_type, "start", false, -1 }, + { glsl_type::float_type, "end", false, -1 }, + { glsl_type::float_type, "scale", false, -1 }, }; #include "builtin_type_macros.h" diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp index 6a808c072..f06d2ab05 100644 --- a/mesalib/src/glsl/builtin_variables.cpp +++ b/mesalib/src/glsl/builtin_variables.cpp @@ -293,6 +293,51 @@ static const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = { namespace { +/** + * Data structure that accumulates fields for the gl_PerVertex interface + * block. + */ +class per_vertex_accumulator +{ +public: + per_vertex_accumulator(); + void add_field(int slot, const glsl_type *type, const char *name); + const glsl_type *construct_interface_instance() const; + +private: + glsl_struct_field fields[10]; + unsigned num_fields; +}; + + +per_vertex_accumulator::per_vertex_accumulator() + : num_fields(0) +{ +} + + +void +per_vertex_accumulator::add_field(int slot, const glsl_type *type, + const char *name) +{ + assert(this->num_fields < ARRAY_SIZE(this->fields)); + this->fields[this->num_fields].type = type; + this->fields[this->num_fields].name = name; + this->fields[this->num_fields].row_major = false; + this->fields[this->num_fields].location = slot; + this->num_fields++; +} + + +const glsl_type * +per_vertex_accumulator::construct_interface_instance() const +{ + return glsl_type::get_interface_instance(this->fields, this->num_fields, + GLSL_INTERFACE_PACKING_STD140, + "gl_PerVertex"); +} + + class builtin_variable_generator { public: @@ -358,6 +403,9 @@ private: const glsl_type * const vec4_t; const glsl_type * const mat3_t; const glsl_type * const mat4_t; + + per_vertex_accumulator per_vertex_in; + per_vertex_accumulator per_vertex_out; }; @@ -497,11 +545,12 @@ builtin_variable_generator::generate_constants() */ if (state->is_version(0, 300)) { add_const("gl_MaxVertexOutputVectors", - state->Const.MaxVaryingFloats / 4); + state->ctx->Const.VertexProgram.MaxOutputComponents / 4); add_const("gl_MaxFragmentInputVectors", - state->Const.MaxVaryingFloats / 4); + state->ctx->Const.FragmentProgram.MaxInputComponents / 4); } else { - add_const("gl_MaxVaryingVectors", state->Const.MaxVaryingFloats / 4); + add_const("gl_MaxVaryingVectors", + state->ctx->Const.MaxVarying); } } else { add_const("gl_MaxVertexUniformComponents", @@ -510,7 +559,7 @@ builtin_variable_generator::generate_constants() /* Note: gl_MaxVaryingFloats was deprecated in GLSL 1.30+, but not * removed */ - add_const("gl_MaxVaryingFloats", state->Const.MaxVaryingFloats); + add_const("gl_MaxVaryingFloats", state->ctx->Const.MaxVarying * 4); add_const("gl_MaxFragmentUniformComponents", state->Const.MaxFragmentUniformComponents); @@ -531,7 +580,38 @@ builtin_variable_generator::generate_constants() if (state->is_version(130, 0)) { add_const("gl_MaxClipDistances", state->Const.MaxClipPlanes); - add_const("gl_MaxVaryingComponents", state->Const.MaxVaryingFloats); + add_const("gl_MaxVaryingComponents", state->ctx->Const.MaxVarying * 4); + } + + if (state->is_version(150, 0)) { + add_const("gl_MaxVertexOutputComponents", + state->Const.MaxVertexOutputComponents); + add_const("gl_MaxGeometryInputComponents", + state->Const.MaxGeometryInputComponents); + add_const("gl_MaxGeometryOutputComponents", + state->Const.MaxGeometryOutputComponents); + add_const("gl_MaxFragmentInputComponents", + state->Const.MaxFragmentInputComponents); + add_const("gl_MaxGeometryTextureImageUnits", + state->Const.MaxGeometryTextureImageUnits); + add_const("gl_MaxGeometryOutputVertices", + state->Const.MaxGeometryOutputVertices); + add_const("gl_MaxGeometryTotalOutputComponents", + state->Const.MaxGeometryTotalOutputComponents); + add_const("gl_MaxGeometryUniformComponents", + state->Const.MaxGeometryUniformComponents); + + /* Note: the GLSL 1.50-4.40 specs require + * gl_MaxGeometryVaryingComponents to be present, and to be at least 64. + * But they do not define what it means (and there does not appear to be + * any corresponding constant in the GL specs). However, + * ARB_geometry_shader4 defines MAX_GEOMETRY_VARYING_COMPONENTS_ARB to + * be the maximum number of components available for use as geometry + * outputs. So we assume this is a synonym for + * gl_MaxGeometryOutputComponents. + */ + add_const("gl_MaxGeometryVaryingComponents", + state->Const.MaxGeometryOutputComponents); } if (compatibility) { @@ -756,10 +836,10 @@ builtin_variable_generator::add_varying(int slot, const glsl_type *type, { switch (state->target) { case geometry_shader: - add_input(slot, array(type, 0), name_as_gs_input); + this->per_vertex_in.add_field(slot, type, name); /* FALLTHROUGH */ case vertex_shader: - add_output(slot, type, name); + this->per_vertex_out.add_field(slot, type, name); break; case fragment_shader: add_input(slot, type, name); @@ -803,6 +883,25 @@ builtin_variable_generator::generate_varyings() ADD_VARYING(VARYING_SLOT_BFC1, vec4_t, "gl_BackSecondaryColor"); } } + + if (state->target == geometry_shader) { + const glsl_type *per_vertex_in_type = + this->per_vertex_in.construct_interface_instance(); + ir_variable *var = add_variable("gl_in", array(per_vertex_in_type, 0), + ir_var_shader_in, -1); + var->init_interface_type(per_vertex_in_type); + } + if (state->target == vertex_shader || state->target == geometry_shader) { + const glsl_type *per_vertex_out_type = + this->per_vertex_out.construct_interface_instance(); + const glsl_struct_field *fields = per_vertex_out_type->fields.structure; + for (unsigned i = 0; i < per_vertex_out_type->length; i++) { + ir_variable *var = + add_variable(fields[i].name, fields[i].type, ir_var_shader_out, + fields[i].location); + var->init_interface_type(per_vertex_out_type); + } + } } diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index 912931a47..a1d593fab 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -1752,6 +1752,12 @@ struct_declarator: $$ = new(ctx) ast_declaration($1, false, NULL, NULL); $$->set_location(yylloc); } + | any_identifier '[' ']' + { + void *ctx = state; + $$ = new(ctx) ast_declaration($1, true, NULL, NULL); + $$->set_location(yylloc); + } | any_identifier '[' constant_expression ']' { void *ctx = state; diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index ad85db9e3..be17109e1 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -99,7 +99,6 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits; this->Const.MaxVertexAttribs = ctx->Const.VertexProgram.MaxAttribs; this->Const.MaxVertexUniformComponents = ctx->Const.VertexProgram.MaxUniformComponents; - this->Const.MaxVaryingFloats = ctx->Const.MaxVarying * 4; this->Const.MaxVertexTextureImageUnits = ctx->Const.VertexProgram.MaxTextureImageUnits; this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits; this->Const.MaxTextureImageUnits = ctx->Const.FragmentProgram.MaxTextureImageUnits; @@ -109,6 +108,16 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers; + /* 1.50 constants */ + this->Const.MaxVertexOutputComponents = ctx->Const.VertexProgram.MaxOutputComponents; + this->Const.MaxGeometryInputComponents = ctx->Const.GeometryProgram.MaxInputComponents; + this->Const.MaxGeometryOutputComponents = ctx->Const.GeometryProgram.MaxOutputComponents; + this->Const.MaxFragmentInputComponents = ctx->Const.FragmentProgram.MaxInputComponents; + this->Const.MaxGeometryTextureImageUnits = ctx->Const.GeometryProgram.MaxTextureImageUnits; + this->Const.MaxGeometryOutputVertices = ctx->Const.MaxGeometryOutputVertices; + this->Const.MaxGeometryTotalOutputComponents = ctx->Const.MaxGeometryTotalOutputComponents; + this->Const.MaxGeometryUniformComponents = ctx->Const.GeometryProgram.MaxUniformComponents; + this->current_function = NULL; this->toplevel_ir = NULL; this->found_return = false; diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index dba1a35e5..a67438412 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -208,7 +208,6 @@ struct _mesa_glsl_parse_state { unsigned MaxTextureCoords; unsigned MaxVertexAttribs; unsigned MaxVertexUniformComponents; - unsigned MaxVaryingFloats; unsigned MaxVertexTextureImageUnits; unsigned MaxCombinedTextureImageUnits; unsigned MaxTextureImageUnits; @@ -220,6 +219,16 @@ struct _mesa_glsl_parse_state { /* 3.00 ES */ int MinProgramTexelOffset; int MaxProgramTexelOffset; + + /* 1.50 */ + unsigned MaxVertexOutputComponents; + unsigned MaxGeometryInputComponents; + unsigned MaxGeometryOutputComponents; + unsigned MaxFragmentInputComponents; + unsigned MaxGeometryTextureImageUnits; + unsigned MaxGeometryOutputVertices; + unsigned MaxGeometryTotalOutputComponents; + unsigned MaxGeometryUniformComponents; } Const; /** diff --git a/mesalib/src/glsl/glsl_symbol_table.cpp b/mesalib/src/glsl/glsl_symbol_table.cpp index 6e916b458..11569f47e 100644 --- a/mesalib/src/glsl/glsl_symbol_table.cpp +++ b/mesalib/src/glsl/glsl_symbol_table.cpp @@ -256,3 +256,18 @@ symbol_table_entry *glsl_symbol_table::get_entry(const char *name) return (symbol_table_entry *) _mesa_symbol_table_find_symbol(table, -1, name); } + +void +glsl_symbol_table::disable_variable(const char *name) +{ + /* Ideally we would remove the variable's entry from the symbol table, but + * that would be difficult. Fortunately, since this is only used for + * built-in variables, it won't be possible for the shader to re-introduce + * the variable later, so all we really need to do is to make sure that + * further attempts to access it using get_variable() will return NULL. + */ + symbol_table_entry *entry = get_entry(name); + if (entry != NULL) { + entry->v = NULL; + } +} diff --git a/mesalib/src/glsl/glsl_symbol_table.h b/mesalib/src/glsl/glsl_symbol_table.h index 62d26b89a..0e62448e2 100644 --- a/mesalib/src/glsl/glsl_symbol_table.h +++ b/mesalib/src/glsl/glsl_symbol_table.h @@ -121,6 +121,14 @@ public: enum ir_variable_mode mode); /*@}*/ + /** + * Disable a previously-added variable so that it no longer appears to be + * in the symbol table. This is necessary when gl_PerVertex is redeclared, + * to ensure that previously-available built-in variables are no longer + * available. + */ + void disable_variable(const char *name); + private: symbol_table_entry *get_entry(const char *name); diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index 3c396dd89..80a6e71a7 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -100,6 +100,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, this->fields.structure[i].type = fields[i].type; this->fields.structure[i].name = ralloc_strdup(this->fields.structure, fields[i].name); + this->fields.structure[i].location = fields[i].location; this->fields.structure[i].row_major = fields[i].row_major; } } @@ -124,6 +125,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, this->fields.structure[i].type = fields[i].type; this->fields.structure[i].name = ralloc_strdup(this->fields.structure, fields[i].name); + this->fields.structure[i].location = fields[i].location; this->fields.structure[i].row_major = fields[i].row_major; } } @@ -450,6 +452,9 @@ glsl_type::record_key_compare(const void *a, const void *b) if (key1->fields.structure[i].row_major != key2->fields.structure[i].row_major) return 1; + if (key1->fields.structure[i].location + != key2->fields.structure[i].location) + return 1; } return 0; @@ -507,9 +512,9 @@ const glsl_type * glsl_type::get_interface_instance(const glsl_struct_field *fields, unsigned num_fields, enum glsl_interface_packing packing, - const char *name) + const char *block_name) { - const glsl_type key(fields, num_fields, packing, name); + const glsl_type key(fields, num_fields, packing, block_name); if (interface_types == NULL) { interface_types = hash_table_ctor(64, record_key_hash, record_key_compare); @@ -517,14 +522,14 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields, const glsl_type *t = (glsl_type *) hash_table_find(interface_types, & key); if (t == NULL) { - t = new glsl_type(fields, num_fields, packing, name); + t = new glsl_type(fields, num_fields, packing, block_name); hash_table_insert(interface_types, (void *) t, t); } assert(t->base_type == GLSL_TYPE_INTERFACE); assert(t->length == num_fields); - assert(strcmp(t->name, name) == 0); + assert(strcmp(t->name, block_name) == 0); return t; } diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h index 9f61eee78..e60c19132 100644 --- a/mesalib/src/glsl/glsl_types.h +++ b/mesalib/src/glsl/glsl_types.h @@ -234,7 +234,7 @@ struct glsl_type { static const glsl_type *get_interface_instance(const glsl_struct_field *fields, unsigned num_fields, enum glsl_interface_packing packing, - const char *name); + const char *block_name); /** * Query the total number of scalars that make up a scalar, vector or matrix @@ -581,6 +581,15 @@ struct glsl_struct_field { const struct glsl_type *type; const char *name; bool row_major; + + /** + * For interface blocks, gl_varying_slot corresponding to the input/output + * if this is a built-in input/output (i.e. a member of the built-in + * gl_PerVertex interface block); -1 otherwise. + * + * Ignored for structs. + */ + int location; }; static inline unsigned int diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index ae67d6bdd..de9613e8f 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -398,6 +398,9 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) this->type = glsl_type::uint_type; break; + case ir_binop_imul_high: + case ir_binop_carry: + case ir_binop_borrow: case ir_binop_lshift: case ir_binop_rshift: case ir_binop_bfm: @@ -527,7 +530,10 @@ static const char *const operator_strs[] = { "+", "-", "*", + "imul_high", "/", + "carry", + "borrow", "%", "<", ">", @@ -1578,7 +1584,8 @@ ir_swizzle::variable_referenced() const ir_variable::ir_variable(const struct glsl_type *type, const char *name, ir_variable_mode mode) - : max_array_access(0), read_only(false), centroid(false), invariant(false), + : max_array_access(0), max_ifc_array_access(NULL), + read_only(false), centroid(false), invariant(false), mode(mode), interpolation(INTERP_QUALIFIER_NONE) { this->ir_type = ir_type_variable; diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index 1a4a3a2e3..aac8cbb7d 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -391,6 +391,65 @@ public: || (t->is_array() && t->fields.array == this->interface_type); } + /** + * Set this->interface_type on a newly created variable. + */ + void init_interface_type(const struct glsl_type *type) + { + assert(this->interface_type == NULL); + this->interface_type = type; + if (this->is_interface_instance()) { + this->max_ifc_array_access = + rzalloc_array(this, unsigned, type->length); + } + } + + /** + * Change this->interface_type on a variable that previously had a + * different, but compatible, interface_type. This is used during linking + * to set the size of arrays in interface blocks. + */ + void change_interface_type(const struct glsl_type *type) + { + if (this->max_ifc_array_access != NULL) { + /* max_ifc_array_access has already been allocated, so make sure the + * new interface has the same number of fields as the old one. + */ + assert(this->interface_type->length == type->length); + } + this->interface_type = type; + } + + /** + * Change this->interface_type on a variable that previously had a + * different, and incompatible, interface_type. This is used during + * compilation to handle redeclaration of the built-in gl_PerVertex + * interface block. + */ + void reinit_interface_type(const struct glsl_type *type) + { + if (this->max_ifc_array_access != NULL) { +#ifndef _NDEBUG + /* Redeclaring gl_PerVertex is only allowed if none of the built-ins + * it defines have been accessed yet; so it's safe to throw away the + * old max_ifc_array_access pointer, since all of its values are + * zero. + */ + for (unsigned i = 0; i < this->interface_type->length; i++) + assert(this->max_ifc_array_access[i] == 0); +#endif + ralloc_free(this->max_ifc_array_access); + this->max_ifc_array_access = NULL; + } + this->interface_type = NULL; + init_interface_type(type); + } + + const glsl_type *get_interface_type() const + { + return this->interface_type; + } + /** * Declared type of the variable */ @@ -408,6 +467,19 @@ public: */ unsigned max_array_access; + /** + * For variables which satisfy the is_interface_instance() predicate, this + * points to an array of integers such that if the ith member of the + * interface block is an array, max_ifc_array_access[i] is the maximum + * array element of that member that has been accessed. If the ith member + * of the interface block is not an array, max_ifc_array_access[i] is + * unused. + * + * For variables whose type is not an interface block, this pointer is + * NULL. + */ + unsigned *max_ifc_array_access; + /** * Is the variable read-only? * @@ -582,6 +654,7 @@ public: */ ir_constant *constant_initializer; +private: /** * For variables that are in an interface block or are an instance of an * interface block, this is the \c GLSL_TYPE_INTERFACE type for that block. @@ -1091,9 +1164,25 @@ enum ir_expression_operation { ir_binop_add, ir_binop_sub, - ir_binop_mul, + ir_binop_mul, /**< Floating-point or low 32-bit integer multiply. */ + ir_binop_imul_high, /**< Calculates the high 32-bits of a 64-bit multiply. */ ir_binop_div, + /** + * Returns the carry resulting from the addition of the two arguments. + */ + /*@{*/ + ir_binop_carry, + /*@}*/ + + /** + * Returns the borrow resulting from the subtraction of the second argument + * from the first argument. + */ + /*@{*/ + ir_binop_borrow, + /*@}*/ + /** * Takes one of two combinations of arguments: * diff --git a/mesalib/src/glsl/ir_builder.cpp b/mesalib/src/glsl/ir_builder.cpp index 98b432295..6c49734be 100644 --- a/mesalib/src/glsl/ir_builder.cpp +++ b/mesalib/src/glsl/ir_builder.cpp @@ -216,11 +216,26 @@ ir_expression *mul(operand a, operand b) return expr(ir_binop_mul, a, b); } +ir_expression *imul_high(operand a, operand b) +{ + return expr(ir_binop_imul_high, a, b); +} + ir_expression *div(operand a, operand b) { return expr(ir_binop_div, a, b); } +ir_expression *carry(operand a, operand b) +{ + return expr(ir_binop_carry, a, b); +} + +ir_expression *borrow(operand a, operand b) +{ + return expr(ir_binop_borrow, a, b); +} + ir_expression *round_even(operand a) { return expr(ir_unop_round_even, a); diff --git a/mesalib/src/glsl/ir_builder.h b/mesalib/src/glsl/ir_builder.h index 6a5f77119..1f0778870 100644 --- a/mesalib/src/glsl/ir_builder.h +++ b/mesalib/src/glsl/ir_builder.h @@ -133,7 +133,10 @@ ir_expression *expr(ir_expression_operation op, operand a, operand b, operand c) ir_expression *add(operand a, operand b); ir_expression *sub(operand a, operand b); ir_expression *mul(operand a, operand b); +ir_expression *imul_high(operand a, operand b); ir_expression *div(operand a, operand b); +ir_expression *carry(operand a, operand b); +ir_expression *borrow(operand a, operand b); ir_expression *round_even(operand a); ir_expression *dot(operand a, operand b); ir_expression *dotlike(operand a, operand b); diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp index dde22e018..105f9063a 100644 --- a/mesalib/src/glsl/ir_clone.cpp +++ b/mesalib/src/glsl/ir_clone.cpp @@ -44,6 +44,12 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const (ir_variable_mode) this->mode); var->max_array_access = this->max_array_access; + if (this->is_interface_instance()) { + var->max_ifc_array_access = + rzalloc_array(var, unsigned, this->interface_type->length); + memcpy(var->max_ifc_array_access, this->max_ifc_array_access, + this->interface_type->length * sizeof(unsigned)); + } var->read_only = this->read_only; var->centroid = this->centroid; var->invariant = this->invariant; diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp index 2c64f4e58..13e41a089 100644 --- a/mesalib/src/glsl/ir_validate.cpp +++ b/mesalib/src/glsl/ir_validate.cpp @@ -429,6 +429,19 @@ ir_validate::visit_leave(ir_expression *ir) } break; + case ir_binop_imul_high: + assert(ir->type == ir->operands[0]->type); + assert(ir->type == ir->operands[1]->type); + assert(ir->type->is_integer()); + break; + + case ir_binop_carry: + case ir_binop_borrow: + assert(ir->type == ir->operands[0]->type); + assert(ir->type == ir->operands[1]->type); + assert(ir->type->base_type == GLSL_TYPE_UINT); + break; + case ir_binop_less: case ir_binop_greater: case ir_binop_lequal: @@ -674,6 +687,26 @@ ir_validate::visit(ir_variable *ir) } } + /* If a variable is an interface block (or an array of interface blocks), + * verify that the maximum array index for each interface member is in + * bounds. + */ + if (ir->is_interface_instance()) { + const glsl_struct_field *fields = + ir->get_interface_type()->fields.structure; + for (unsigned i = 0; i < ir->get_interface_type()->length; i++) { + if (fields[i].type->array_size() > 0) { + if (ir->max_ifc_array_access[i] >= fields[i].type->length) { + printf("ir_variable has maximum access out of bounds for " + "field %s (%d vs %d)\n", fields[i].name, + ir->max_ifc_array_access[i], fields[i].type->length); + ir->print(); + abort(); + } + } + } + } + if (ir->constant_initializer != NULL && !ir->has_initializer) { printf("ir_variable didn't have an initializer, but has a constant " "initializer value.\n"); diff --git a/mesalib/src/glsl/link_functions.cpp b/mesalib/src/glsl/link_functions.cpp index b1a68fd55..fd8009998 100644 --- a/mesalib/src/glsl/link_functions.cpp +++ b/mesalib/src/glsl/link_functions.cpp @@ -223,18 +223,31 @@ public: var = ir->var->clone(linked, NULL); linked->symbols->add_variable(var); linked->ir->push_head(var); - } else if (var->type->is_array()) { - /* It is possible to have a global array declared in multiple - * shaders without a size. The array is implicitly sized by the - * maximal access to it in *any* shader. Because of this, we - * need to track the maximal access to the array as linking pulls - * more functions in that access the array. - */ - var->max_array_access = - MAX2(var->max_array_access, ir->var->max_array_access); - - if (var->type->length == 0 && ir->var->type->length != 0) - var->type = ir->var->type; + } else { + if (var->type->is_array()) { + /* It is possible to have a global array declared in multiple + * shaders without a size. The array is implicitly sized by + * the maximal access to it in *any* shader. Because of this, + * we need to track the maximal access to the array as linking + * pulls more functions in that access the array. + */ + var->max_array_access = + MAX2(var->max_array_access, ir->var->max_array_access); + + if (var->type->length == 0 && ir->var->type->length != 0) + var->type = ir->var->type; + } + if (var->is_interface_instance()) { + /* Similarly, we need implicit sizes of arrays within interface + * blocks to be sized by the maximal access in *any* shader. + */ + for (unsigned i = 0; i < var->get_interface_type()->length; + i++) { + var->max_ifc_array_access[i] = + MAX2(var->max_ifc_array_access[i], + ir->var->max_ifc_array_access[i]); + } + } } ir->var = var; diff --git a/mesalib/src/glsl/link_interface_blocks.cpp b/mesalib/src/glsl/link_interface_blocks.cpp index 928a88ee2..4f1c9d396 100644 --- a/mesalib/src/glsl/link_interface_blocks.cpp +++ b/mesalib/src/glsl/link_interface_blocks.cpp @@ -47,7 +47,7 @@ validate_intrastage_interface_blocks(struct gl_shader_program *prog, if (!var) continue; - const glsl_type *iface_type = var->interface_type; + const glsl_type *iface_type = var->get_interface_type(); if (iface_type == NULL) continue; @@ -81,32 +81,33 @@ validate_interstage_interface_blocks(struct gl_shader_program *prog, /* Add non-output interfaces from the consumer to the symbol table. */ foreach_list(node, consumer->ir) { ir_variable *var = ((ir_instruction *) node)->as_variable(); - if (!var || !var->interface_type || var->mode == ir_var_shader_out) + if (!var || !var->get_interface_type() || var->mode == ir_var_shader_out) continue; - interfaces.add_interface(var->interface_type->name, - var->interface_type, + interfaces.add_interface(var->get_interface_type()->name, + var->get_interface_type(), (enum ir_variable_mode) var->mode); } /* Verify that the producer's interfaces match. */ foreach_list(node, producer->ir) { ir_variable *var = ((ir_instruction *) node)->as_variable(); - if (!var || !var->interface_type || var->mode == ir_var_shader_in) + if (!var || !var->get_interface_type() || var->mode == ir_var_shader_in) continue; enum ir_variable_mode consumer_mode = var->mode == ir_var_uniform ? ir_var_uniform : ir_var_shader_in; const glsl_type *expected_type = - interfaces.get_interface(var->interface_type->name, consumer_mode); + interfaces.get_interface(var->get_interface_type()->name, + consumer_mode); /* The consumer doesn't use this output block. Ignore it. */ if (expected_type == NULL) continue; - if (var->interface_type != expected_type) { + if (var->get_interface_type() != expected_type) { linker_error(prog, "definitions of interface block `%s' do not " - "match\n", var->interface_type->name); + "match\n", var->get_interface_type()->name); return; } } diff --git a/mesalib/src/glsl/link_uniform_block_active_visitor.cpp b/mesalib/src/glsl/link_uniform_block_active_visitor.cpp index 56a8384e9..f2f46a211 100644 --- a/mesalib/src/glsl/link_uniform_block_active_visitor.cpp +++ b/mesalib/src/glsl/link_uniform_block_active_visitor.cpp @@ -27,12 +27,12 @@ link_uniform_block_active * process_block(void *mem_ctx, struct hash_table *ht, ir_variable *var) { - const uint32_t h = _mesa_hash_string(var->interface_type->name); + const uint32_t h = _mesa_hash_string(var->get_interface_type()->name); const hash_entry *const existing_block = - _mesa_hash_table_search(ht, h, var->interface_type->name); + _mesa_hash_table_search(ht, h, var->get_interface_type()->name); const glsl_type *const block_type = var->is_interface_instance() - ? var->type : var->interface_type; + ? var->type : var->get_interface_type(); /* If a block with this block-name has not previously been seen, add it. @@ -46,7 +46,7 @@ process_block(void *mem_ctx, struct hash_table *ht, ir_variable *var) b->type = block_type; b->has_instance_name = var->is_interface_instance(); - _mesa_hash_table_insert(ht, h, var->interface_type->name, + _mesa_hash_table_insert(ht, h, var->get_interface_type()->name, (void *) b); return b; } else { @@ -90,7 +90,7 @@ link_uniform_block_active_visitor::visit_enter(ir_dereference_array *ir) if (b == NULL) { linker_error(prog, "uniform block `%s' has mismatching definitions", - var->interface_type->name); + var->get_interface_type()->name); this->success = false; return visit_stop; } @@ -149,7 +149,7 @@ link_uniform_block_active_visitor::visit(ir_dereference_variable *ir) if (b == NULL) { linker_error(this->prog, "uniform block `%s' has mismatching definitions", - var->interface_type->name); + var->get_interface_type()->name); this->success = false; return visit_stop; } diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp index 1cdd5a922..4bd4034a0 100644 --- a/mesalib/src/glsl/link_uniforms.cpp +++ b/mesalib/src/glsl/link_uniforms.cpp @@ -199,8 +199,8 @@ public: { this->is_ubo_var = var->is_in_uniform_block(); if (var->is_interface_instance()) - program_resource_visitor::process(var->interface_type, - var->interface_type->name); + program_resource_visitor::process(var->get_interface_type(), + var->get_interface_type()->name); else program_resource_visitor::process(var); } @@ -317,10 +317,10 @@ public: ubo_block_index = -1; if (var->is_in_uniform_block()) { if (var->is_interface_instance() && var->type->is_array()) { - unsigned l = strlen(var->interface_type->name); + unsigned l = strlen(var->get_interface_type()->name); for (unsigned i = 0; i < prog->NumUniformBlocks; i++) { - if (strncmp(var->interface_type->name, + if (strncmp(var->get_interface_type()->name, prog->UniformBlocks[i].Name, l) == 0 && prog->UniformBlocks[i].Name[l] == '[') { @@ -330,7 +330,7 @@ public: } } else { for (unsigned i = 0; i < prog->NumUniformBlocks; i++) { - if (strcmp(var->interface_type->name, + if (strcmp(var->get_interface_type()->name, prog->UniformBlocks[i].Name) == 0) { ubo_block_index = i; break; @@ -362,7 +362,8 @@ public: } if (var->is_interface_instance()) - process(var->interface_type, var->interface_type->name); + process(var->get_interface_type(), + var->get_interface_type()->name); else process(var); } else diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp index 905621daf..4ba6d8a20 100644 --- a/mesalib/src/glsl/link_varyings.cpp +++ b/mesalib/src/glsl/link_varyings.cpp @@ -972,8 +972,8 @@ public: this->toplevel_var = var; this->varying_floats = 0; if (var->is_interface_instance()) - program_resource_visitor::process(var->interface_type, - var->interface_type->name); + program_resource_visitor::process(var->get_interface_type(), + var->get_interface_type()->name); else program_resource_visitor::process(var); } @@ -1083,10 +1083,10 @@ assign_varying_locations(struct gl_context *ctx, ((ir_instruction *) node)->as_variable(); if ((input_var != NULL) && (input_var->mode == ir_var_shader_in)) { - if (input_var->interface_type != NULL) { + if (input_var->get_interface_type() != NULL) { char *const iface_field_name = ralloc_asprintf(mem_ctx, "%s.%s", - input_var->interface_type->name, + input_var->get_interface_type()->name, input_var->name); hash_table_insert(consumer_interface_inputs, input_var, iface_field_name); @@ -1108,10 +1108,10 @@ assign_varying_locations(struct gl_context *ctx, g.process(output_var); ir_variable *input_var; - if (output_var->interface_type != NULL) { + if (output_var->get_interface_type() != NULL) { char *const iface_field_name = ralloc_asprintf(mem_ctx, "%s.%s", - output_var->interface_type->name, + output_var->get_interface_type()->name, output_var->name); input_var = (ir_variable *) hash_table_find(consumer_interface_inputs, @@ -1220,39 +1220,98 @@ assign_varying_locations(struct gl_context *ctx, } bool -check_against_varying_limit(struct gl_context *ctx, - struct gl_shader_program *prog, - gl_shader *consumer) +check_against_output_limit(struct gl_context *ctx, + struct gl_shader_program *prog, + gl_shader *producer) { - unsigned varying_vectors = 0; + unsigned output_vectors = 0; + + foreach_list(node, producer->ir) { + ir_variable *const var = ((ir_instruction *) node)->as_variable(); + + if (var && var->mode == ir_var_shader_out && + is_varying_var(producer->Type, var)) { + output_vectors += var->type->count_attribute_slots(); + } + } + + unsigned max_output_components; + switch (producer->Type) { + case GL_VERTEX_SHADER: + max_output_components = ctx->Const.VertexProgram.MaxOutputComponents; + break; + case GL_GEOMETRY_SHADER: + max_output_components = ctx->Const.GeometryProgram.MaxOutputComponents; + break; + case GL_FRAGMENT_SHADER: + default: + assert(!"Should not get here."); + return false; + } + + const unsigned output_components = output_vectors * 4; + if (output_components > max_output_components) { + if (ctx->API == API_OPENGLES2 || prog->IsES) + linker_error(prog, "shader uses too many output vectors " + "(%u > %u)\n", + output_vectors, + max_output_components / 4); + else + linker_error(prog, "shader uses too many output components " + "(%u > %u)\n", + output_components, + max_output_components); + + return false; + } + + return true; +} + +bool +check_against_input_limit(struct gl_context *ctx, + struct gl_shader_program *prog, + gl_shader *consumer) +{ + unsigned input_vectors = 0; foreach_list(node, consumer->ir) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); if (var && var->mode == ir_var_shader_in && is_varying_var(consumer->Type, var)) { - /* The packing rules used for vertex shader inputs are also - * used for fragment shader inputs. - */ - varying_vectors += var->type->count_attribute_slots(); + input_vectors += var->type->count_attribute_slots(); } } - if (ctx->API == API_OPENGLES2 || prog->IsES) { - if (varying_vectors > ctx->Const.MaxVarying) { - linker_error(prog, "shader uses too many varying vectors " + unsigned max_input_components; + switch (consumer->Type) { + case GL_GEOMETRY_SHADER: + max_input_components = ctx->Const.GeometryProgram.MaxInputComponents; + break; + case GL_FRAGMENT_SHADER: + max_input_components = ctx->Const.FragmentProgram.MaxInputComponents; + break; + case GL_VERTEX_SHADER: + default: + assert(!"Should not get here."); + return false; + } + + const unsigned input_components = input_vectors * 4; + if (input_components > max_input_components) { + if (ctx->API == API_OPENGLES2 || prog->IsES) + linker_error(prog, "shader uses too many input vectors " "(%u > %u)\n", - varying_vectors, ctx->Const.MaxVarying); - return false; - } - } else { - const unsigned float_components = varying_vectors * 4; - if (float_components > ctx->Const.MaxVarying * 4) { - linker_error(prog, "shader uses too many varying components " + input_vectors, + max_input_components / 4); + else + linker_error(prog, "shader uses too many input components " "(%u > %u)\n", - float_components, ctx->Const.MaxVarying * 4); - return false; - } + input_components, + max_input_components); + + return false; } return true; diff --git a/mesalib/src/glsl/link_varyings.h b/mesalib/src/glsl/link_varyings.h index 6264ef05b..6fa268176 100644 --- a/mesalib/src/glsl/link_varyings.h +++ b/mesalib/src/glsl/link_varyings.h @@ -237,8 +237,13 @@ assign_varying_locations(struct gl_context *ctx, unsigned gs_input_vertices); bool -check_against_varying_limit(struct gl_context *ctx, - struct gl_shader_program *prog, - gl_shader *consumer); +check_against_output_limit(struct gl_context *ctx, + struct gl_shader_program *prog, + gl_shader *producer); + +bool +check_against_input_limit(struct gl_context *ctx, + struct gl_shader_program *prog, + gl_shader *consumer); #endif /* GLSL_LINK_VARYINGS_H */ diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index c54b7049b..9095a4015 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -1033,17 +1033,167 @@ get_main_function_signature(gl_shader *sh) */ class array_sizing_visitor : public ir_hierarchical_visitor { public: + array_sizing_visitor() + : mem_ctx(ralloc_context(NULL)), + unnamed_interfaces(hash_table_ctor(0, hash_table_pointer_hash, + hash_table_pointer_compare)) + { + } + + ~array_sizing_visitor() + { + hash_table_dtor(this->unnamed_interfaces); + ralloc_free(this->mem_ctx); + } + virtual ir_visitor_status visit(ir_variable *var) { - if (var->type->is_array() && (var->type->length == 0)) { - const glsl_type *type = - glsl_type::get_array_instance(var->type->fields.array, - var->max_array_access + 1); - assert(type != NULL); - var->type = type; + fixup_type(&var->type, var->max_array_access); + if (var->type->is_interface()) { + if (interface_contains_unsized_arrays(var->type)) { + const glsl_type *new_type = + resize_interface_members(var->type, var->max_ifc_array_access); + var->type = new_type; + var->change_interface_type(new_type); + } + } else if (var->type->is_array() && + var->type->fields.array->is_interface()) { + if (interface_contains_unsized_arrays(var->type->fields.array)) { + const glsl_type *new_type = + resize_interface_members(var->type->fields.array, + var->max_ifc_array_access); + var->change_interface_type(new_type); + var->type = + glsl_type::get_array_instance(new_type, var->type->length); + } + } else if (const glsl_type *ifc_type = var->get_interface_type()) { + /* Store a pointer to the variable in the unnamed_interfaces + * hashtable. + */ + ir_variable **interface_vars = (ir_variable **) + hash_table_find(this->unnamed_interfaces, ifc_type); + if (interface_vars == NULL) { + interface_vars = rzalloc_array(mem_ctx, ir_variable *, + ifc_type->length); + hash_table_insert(this->unnamed_interfaces, interface_vars, + ifc_type); + } + unsigned index = ifc_type->field_index(var->name); + assert(index < ifc_type->length); + assert(interface_vars[index] == NULL); + interface_vars[index] = var; } return visit_continue; } + + /** + * For each unnamed interface block that was discovered while running the + * visitor, adjust the interface type to reflect the newly assigned array + * sizes, and fix up the ir_variable nodes to point to the new interface + * type. + */ + void fixup_unnamed_interface_types() + { + hash_table_call_foreach(this->unnamed_interfaces, + fixup_unnamed_interface_type, NULL); + } + +private: + /** + * If the type pointed to by \c type represents an unsized array, replace + * it with a sized array whose size is determined by max_array_access. + */ + static void fixup_type(const glsl_type **type, unsigned max_array_access) + { + if ((*type)->is_array() && (*type)->length == 0) { + *type = glsl_type::get_array_instance((*type)->fields.array, + max_array_access + 1); + assert(*type != NULL); + } + } + + /** + * Determine whether the given interface type contains unsized arrays (if + * it doesn't, array_sizing_visitor doesn't need to process it). + */ + static bool interface_contains_unsized_arrays(const glsl_type *type) + { + for (unsigned i = 0; i < type->length; i++) { + const glsl_type *elem_type = type->fields.structure[i].type; + if (elem_type->is_array() && elem_type->length == 0) + return true; + } + return false; + } + + /** + * Create a new interface type based on the given type, with unsized arrays + * replaced by sized arrays whose size is determined by + * max_ifc_array_access. + */ + static const glsl_type * + resize_interface_members(const glsl_type *type, + const unsigned *max_ifc_array_access) + { + unsigned num_fields = type->length; + glsl_struct_field *fields = new glsl_struct_field[num_fields]; + memcpy(fields, type->fields.structure, + num_fields * sizeof(*fields)); + for (unsigned i = 0; i < num_fields; i++) { + fixup_type(&fields[i].type, max_ifc_array_access[i]); + } + glsl_interface_packing packing = + (glsl_interface_packing) type->interface_packing; + const glsl_type *new_ifc_type = + glsl_type::get_interface_instance(fields, num_fields, + packing, type->name); + delete [] fields; + return new_ifc_type; + } + + static void fixup_unnamed_interface_type(const void *key, void *data, + void *) + { + const glsl_type *ifc_type = (const glsl_type *) key; + ir_variable **interface_vars = (ir_variable **) data; + unsigned num_fields = ifc_type->length; + glsl_struct_field *fields = new glsl_struct_field[num_fields]; + memcpy(fields, ifc_type->fields.structure, + num_fields * sizeof(*fields)); + bool interface_type_changed = false; + for (unsigned i = 0; i < num_fields; i++) { + if (interface_vars[i] != NULL && + fields[i].type != interface_vars[i]->type) { + fields[i].type = interface_vars[i]->type; + interface_type_changed = true; + } + } + if (!interface_type_changed) { + delete [] fields; + return; + } + glsl_interface_packing packing = + (glsl_interface_packing) ifc_type->interface_packing; + const glsl_type *new_ifc_type = + glsl_type::get_interface_instance(fields, num_fields, packing, + ifc_type->name); + delete [] fields; + for (unsigned i = 0; i < num_fields; i++) { + if (interface_vars[i] != NULL) + interface_vars[i]->change_interface_type(new_ifc_type); + } + } + + /** + * Memory context used to allocate the data in \c unnamed_interfaces. + */ + void *mem_ctx; + + /** + * Hash table from const glsl_type * to an array of ir_variable *'s + * pointing to the ir_variables constituting each unnamed interface block. + */ + hash_table *unnamed_interfaces; }; /** @@ -1318,6 +1468,7 @@ link_intrastage_shaders(void *mem_ctx, */ array_sizing_visitor v; v.run(linked->ir); + v.fixup_unnamed_interface_types(); return linked; } @@ -2203,7 +2354,9 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) ; /* This must be done after all dead varyings are eliminated. */ - if (!check_against_varying_limit(ctx, prog, sh_next)) + if (!check_against_output_limit(ctx, prog, sh_i)) + goto done; + if (!check_against_input_limit(ctx, prog, sh_next)) goto done; next = i; diff --git a/mesalib/src/glsl/lower_clip_distance.cpp b/mesalib/src/glsl/lower_clip_distance.cpp index 9ddd64603..682c8fdcd 100644 --- a/mesalib/src/glsl/lower_clip_distance.cpp +++ b/mesalib/src/glsl/lower_clip_distance.cpp @@ -54,14 +54,17 @@ namespace { class lower_clip_distance_visitor : public ir_rvalue_visitor { public: - lower_clip_distance_visitor() - : progress(false), old_clip_distance_var(NULL), - new_clip_distance_var(NULL) + explicit lower_clip_distance_visitor(GLenum shader_type) + : progress(false), old_clip_distance_1d_var(NULL), + old_clip_distance_2d_var(NULL), new_clip_distance_1d_var(NULL), + new_clip_distance_2d_var(NULL), shader_type(shader_type) { } virtual ir_visitor_status visit(ir_variable *); void create_indices(ir_rvalue*, ir_rvalue *&, ir_rvalue *&); + bool is_clip_distance_vec8(ir_rvalue *ir); + ir_rvalue *lower_clip_distance_vec8(ir_rvalue *ir); virtual ir_visitor_status visit_leave(ir_assignment *); void visit_new_assignment(ir_assignment *ir); virtual ir_visitor_status visit_leave(ir_call *); @@ -74,13 +77,28 @@ public: /** * Pointer to the declaration of gl_ClipDistance, if found. + * + * Note: + * + * - the 2d_var is for geometry shader input only. + * + * - since gl_ClipDistance is available in geometry shaders as both an + * input and an output, it's possible for both old_clip_distance_1d_var + * and old_clip_distance_2d_var to be non-null. */ - ir_variable *old_clip_distance_var; + ir_variable *old_clip_distance_1d_var; + ir_variable *old_clip_distance_2d_var; /** * Pointer to the newly-created gl_ClipDistanceMESA variable. */ - ir_variable *new_clip_distance_var; + ir_variable *new_clip_distance_1d_var; + ir_variable *new_clip_distance_2d_var; + + /** + * Type of shader we are compiling (e.g. GL_VERTEX_SHADER) + */ + const GLenum shader_type; }; } /* anonymous namespace */ @@ -92,30 +110,61 @@ public: ir_visitor_status lower_clip_distance_visitor::visit(ir_variable *ir) { - /* No point in looking for the declaration of gl_ClipDistance if - * we've already found it. - */ - if (this->old_clip_distance_var) + if (!ir->name || strcmp(ir->name, "gl_ClipDistance") != 0) return visit_continue; + assert (ir->type->is_array()); + + if (!ir->type->element_type()->is_array()) { + /* 1D gl_ClipDistance (used for vertex and geometry output, and fragment + * input). + */ + if (this->old_clip_distance_1d_var) + return visit_continue; - if (ir->name && strcmp(ir->name, "gl_ClipDistance") == 0) { this->progress = true; - this->old_clip_distance_var = ir; - assert (ir->type->is_array()); + this->old_clip_distance_1d_var = ir; assert (ir->type->element_type() == glsl_type::float_type); unsigned new_size = (ir->type->array_size() + 3) / 4; /* Clone the old var so that we inherit all of its properties */ - this->new_clip_distance_var = ir->clone(ralloc_parent(ir), NULL); + this->new_clip_distance_1d_var = ir->clone(ralloc_parent(ir), NULL); /* And change the properties that we need to change */ - this->new_clip_distance_var->name - = ralloc_strdup(this->new_clip_distance_var, "gl_ClipDistanceMESA"); - this->new_clip_distance_var->type + this->new_clip_distance_1d_var->name + = ralloc_strdup(this->new_clip_distance_1d_var, + "gl_ClipDistanceMESA"); + this->new_clip_distance_1d_var->type = glsl_type::get_array_instance(glsl_type::vec4_type, new_size); - this->new_clip_distance_var->max_array_access = ir->max_array_access / 4; + this->new_clip_distance_1d_var->max_array_access + = ir->max_array_access / 4; + + ir->replace_with(this->new_clip_distance_1d_var); + } else { + /* 2D gl_ClipDistance (used for geometry input). */ + assert(ir->mode == ir_var_shader_in && + this->shader_type == GL_GEOMETRY_SHADER_ARB); + if (this->old_clip_distance_2d_var) + return visit_continue; + + this->progress = true; + this->old_clip_distance_2d_var = ir; + assert (ir->type->element_type()->element_type() == glsl_type::float_type); + unsigned new_size = (ir->type->element_type()->array_size() + 3) / 4; + + /* Clone the old var so that we inherit all of its properties */ + this->new_clip_distance_2d_var = ir->clone(ralloc_parent(ir), NULL); - ir->replace_with(this->new_clip_distance_var); + /* And change the properties that we need to change */ + this->new_clip_distance_2d_var->name + = ralloc_strdup(this->new_clip_distance_2d_var, "gl_ClipDistanceMESA"); + this->new_clip_distance_2d_var->type = glsl_type::get_array_instance( + glsl_type::get_array_instance(glsl_type::vec4_type, + new_size), + ir->type->array_size()); + this->new_clip_distance_2d_var->max_array_access + = ir->max_array_access / 4; + + ir->replace_with(this->new_clip_distance_2d_var); } return visit_continue; } @@ -180,39 +229,111 @@ lower_clip_distance_visitor::create_indices(ir_rvalue *old_index, } +/** + * Determine whether the given rvalue describes an array of 8 floats that + * needs to be lowered to an array of 2 vec4's; that is, determine whether it + * matches one of the following patterns: + * + * - gl_ClipDistance (if gl_ClipDistance is 1D) + * - gl_ClipDistance[i] (if gl_ClipDistance is 2D) + */ +bool +lower_clip_distance_visitor::is_clip_distance_vec8(ir_rvalue *ir) +{ + /* Note that geometry shaders contain gl_ClipDistance both as an input + * (which is a 2D array) and an output (which is a 1D array), so it's + * possible for both this->old_clip_distance_1d_var and + * this->old_clip_distance_2d_var to be non-NULL in the same shader. + */ + + if (this->old_clip_distance_1d_var) { + ir_dereference_variable *var_ref = ir->as_dereference_variable(); + if (var_ref && var_ref->var == this->old_clip_distance_1d_var) + return true; + } + if (this->old_clip_distance_2d_var) { + /* 2D clip distance is only possible as a geometry input */ + assert(this->shader_type == GL_GEOMETRY_SHADER_ARB); + + ir_dereference_array *array_ref = ir->as_dereference_array(); + if (array_ref) { + ir_dereference_variable *var_ref = + array_ref->array->as_dereference_variable(); + if (var_ref && var_ref->var == this->old_clip_distance_2d_var) + return true; + } + } + return false; +} + + +/** + * If the given ir satisfies is_clip_distance_vec8(), return new ir + * representing its lowered equivalent. That is, map: + * + * - gl_ClipDistance => gl_ClipDistanceMESA (if gl_ClipDistance is 1D) + * - gl_ClipDistance[i] => gl_ClipDistanceMESA[i] (if gl_ClipDistance is 2D) + * + * Otherwise return NULL. + */ +ir_rvalue * +lower_clip_distance_visitor::lower_clip_distance_vec8(ir_rvalue *ir) +{ + if (this->old_clip_distance_1d_var) { + ir_dereference_variable *var_ref = ir->as_dereference_variable(); + if (var_ref && var_ref->var == this->old_clip_distance_1d_var) { + return new(ralloc_parent(ir)) + ir_dereference_variable(this->new_clip_distance_1d_var); + } + } + if (this->old_clip_distance_2d_var) { + /* 2D clip distance is only possible as a geometry input */ + assert(this->shader_type == GL_GEOMETRY_SHADER_ARB); + + ir_dereference_array *array_ref = ir->as_dereference_array(); + if (array_ref) { + ir_dereference_variable *var_ref = + array_ref->array->as_dereference_variable(); + if (var_ref && var_ref->var == this->old_clip_distance_2d_var) { + return new(ralloc_parent(ir)) + ir_dereference_array(this->new_clip_distance_2d_var, + array_ref->array_index); + } + } + } + return NULL; +} + + void lower_clip_distance_visitor::handle_rvalue(ir_rvalue **rv) { - /* If the gl_ClipDistance var hasn't been declared yet, then - * there's no way this deref can refer to it. - */ - if (!this->old_clip_distance_var || *rv == NULL) + if (*rv == NULL) return; ir_dereference_array *const array_deref = (*rv)->as_dereference_array(); if (array_deref == NULL) return; - /* Replace any expression that indexes into the gl_ClipDistance array + /* Replace any expression that indexes one of the floats in gl_ClipDistance * with an expression that indexes into one of the vec4's in * gl_ClipDistanceMESA and accesses the appropriate component. */ - ir_dereference_variable *old_var_ref = - array_deref->array->as_dereference_variable(); - if (old_var_ref && old_var_ref->var == this->old_clip_distance_var) { + ir_rvalue *lowered_vec8 = + this->lower_clip_distance_vec8(array_deref->array); + if (lowered_vec8 != NULL) { this->progress = true; ir_rvalue *array_index; ir_rvalue *swizzle_index; this->create_indices(array_deref->array_index, array_index, swizzle_index); void *mem_ctx = ralloc_parent(array_deref); - ir_dereference_array *const ClipDistanceMESA_deref = - new(mem_ctx) ir_dereference_array(this->new_clip_distance_var, - array_index); + ir_dereference_array *const new_array_deref = + new(mem_ctx) ir_dereference_array(lowered_vec8, array_index); ir_expression *const expr = new(mem_ctx) ir_expression(ir_binop_vector_extract, - ClipDistanceMESA_deref, + new_array_deref, swizzle_index); *rv = expr; @@ -246,30 +367,34 @@ lower_clip_distance_visitor::fix_lhs(ir_assignment *ir) } /** - * Replace any assignment having gl_ClipDistance (undereferenced) as its LHS - * or RHS with a sequence of assignments, one for each component of the array. - * Each of these assignments is lowered to refer to gl_ClipDistanceMESA as - * appropriate. + * Replace any assignment having the 1D gl_ClipDistance (undereferenced) as + * its LHS or RHS with a sequence of assignments, one for each component of + * the array. Each of these assignments is lowered to refer to + * gl_ClipDistanceMESA as appropriate. + * + * We need to do a similar replacement for 2D gl_ClipDistance, however since + * it's an input, the only case we need to address is where a 1D slice of it + * is the entire RHS of an assignment, e.g.: + * + * foo = gl_in[i].gl_ClipDistance */ ir_visitor_status lower_clip_distance_visitor::visit_leave(ir_assignment *ir) { - ir_dereference_variable *lhs_var = ir->lhs->as_dereference_variable(); - ir_dereference_variable *rhs_var = ir->rhs->as_dereference_variable(); - if ((lhs_var && lhs_var->var == this->old_clip_distance_var) - || (rhs_var && rhs_var->var == this->old_clip_distance_var)) { - /* LHS or RHS of the assignment is the entire gl_ClipDistance array. - * Since we are reshaping gl_ClipDistance from an array of floats to an - * array of vec4's, this isn't going to work as a bulk assignment - * anymore, so unroll it to element-by-element assignments and lower - * each of them. + if (this->is_clip_distance_vec8(ir->lhs) || + this->is_clip_distance_vec8(ir->rhs)) { + /* LHS or RHS of the assignment is the entire 1D gl_ClipDistance array + * (or a 1D slice of a 2D gl_ClipDistance input array). Since we are + * reshaping gl_ClipDistance from an array of floats to an array of + * vec4's, this isn't going to work as a bulk assignment anymore, so + * unroll it to element-by-element assignments and lower each of them. * * Note: to unroll into element-by-element assignments, we need to make * clones of the LHS and RHS. This is safe because expressions and * l-values are side-effect free. */ void *ctx = ralloc_parent(ir); - int array_size = this->old_clip_distance_var->type->array_size(); + int array_size = ir->lhs->type->array_size(); for (int i = 0; i < array_size; ++i) { ir_dereference_array *new_lhs = new(ctx) ir_dereference_array( ir->lhs->clone(ctx, NULL), new(ctx) ir_constant(i)); @@ -329,11 +454,17 @@ lower_clip_distance_visitor::visit_new_assignment(ir_assignment *ir) /** - * If gl_ClipDistance appears as an argument in an ir_call expression, replace - * it with a temporary variable, and make sure the ir_call is preceded and/or - * followed by assignments that copy the contents of the temporary variable to - * and/or from gl_ClipDistance. Each of these assignments is then lowered to - * refer to gl_ClipDistanceMESA. + * If a 1D gl_ClipDistance variable appears as an argument in an ir_call + * expression, replace it with a temporary variable, and make sure the ir_call + * is preceded and/or followed by assignments that copy the contents of the + * temporary variable to and/or from gl_ClipDistance. Each of these + * assignments is then lowered to refer to gl_ClipDistanceMESA. + * + * We need to do a similar replacement for 2D gl_ClipDistance, however since + * it's an input, the only case we need to address is where a 1D slice of it + * is passed as an "in" parameter to an ir_call, e.g.: + * + * foo(gl_in[i].gl_ClipDistance) */ ir_visitor_status lower_clip_distance_visitor::visit_leave(ir_call *ir) @@ -352,12 +483,12 @@ lower_clip_distance_visitor::visit_leave(ir_call *ir) formal_param_node = formal_param_node->next; actual_param_node = actual_param_node->next; - ir_dereference_variable *deref = actual_param->as_dereference_variable(); - if (deref && deref->var == this->old_clip_distance_var) { - /* User is trying to pass the whole gl_ClipDistance array to a - * function call. Since we are reshaping gl_ClipDistance from an - * array of floats to an array of vec4's, this isn't going to work - * anymore, so use a temporary array instead. + if (this->is_clip_distance_vec8(actual_param)) { + /* User is trying to pass the whole 1D gl_ClipDistance array (or a 1D + * slice of a 2D gl_ClipDistance array) to a function call. Since we + * are reshaping gl_ClipDistance from an array of floats to an array + * of vec4's, this isn't going to work anymore, so use a temporary + * array instead. */ ir_variable *temp_clip_distance = new(ctx) ir_variable( actual_param->type, "temp_clip_distance", ir_var_temporary); @@ -373,7 +504,7 @@ lower_clip_distance_visitor::visit_leave(ir_call *ir) */ ir_assignment *new_assignment = new(ctx) ir_assignment( new(ctx) ir_dereference_variable(temp_clip_distance), - new(ctx) ir_dereference_variable(old_clip_distance_var)); + actual_param->clone(ctx, NULL)); this->base_ir->insert_before(new_assignment); this->visit_new_assignment(new_assignment); } @@ -385,7 +516,7 @@ lower_clip_distance_visitor::visit_leave(ir_call *ir) * afterwards to make sure it gets lowered. */ ir_assignment *new_assignment = new(ctx) ir_assignment( - new(ctx) ir_dereference_variable(old_clip_distance_var), + actual_param->clone(ctx, NULL), new(ctx) ir_dereference_variable(temp_clip_distance)); this->base_ir->insert_after(new_assignment); this->visit_new_assignment(new_assignment); @@ -400,12 +531,14 @@ lower_clip_distance_visitor::visit_leave(ir_call *ir) bool lower_clip_distance(gl_shader *shader) { - lower_clip_distance_visitor v; + lower_clip_distance_visitor v(shader->Type); visit_list_elements(&v, shader->ir); - if (v.new_clip_distance_var) - shader->symbols->add_variable(v.new_clip_distance_var); + if (v.new_clip_distance_1d_var) + shader->symbols->add_variable(v.new_clip_distance_1d_var); + if (v.new_clip_distance_2d_var) + shader->symbols->add_variable(v.new_clip_distance_2d_var); return v.progress; } diff --git a/mesalib/src/glsl/lower_named_interface_blocks.cpp b/mesalib/src/glsl/lower_named_interface_blocks.cpp index 7019185a2..f415252ba 100644 --- a/mesalib/src/glsl/lower_named_interface_blocks.cpp +++ b/mesalib/src/glsl/lower_named_interface_blocks.cpp @@ -150,8 +150,9 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions) var_name, (ir_variable_mode) var->mode); } + new_var->location = iface_t->fields.structure[i].location; - new_var->interface_type = iface_t; + new_var->init_interface_type(iface_t); hash_table_insert(interface_namespace, new_var, iface_field_name); insert_pos->insert_after(new_var); @@ -207,9 +208,9 @@ flatten_named_interface_blocks_declarations::handle_rvalue(ir_rvalue **rvalue) if (var->mode == ir_var_uniform) return; - if (var->interface_type != NULL) { + if (var->get_interface_type() != NULL) { char *iface_field_name = - ralloc_asprintf(mem_ctx, "%s.%s", var->interface_type->name, + ralloc_asprintf(mem_ctx, "%s.%s", var->get_interface_type()->name, ir->field); /* Find the variable in the set of flattened interface blocks */ ir_variable *found_var = diff --git a/mesalib/src/glsl/lower_ubo_reference.cpp b/mesalib/src/glsl/lower_ubo_reference.cpp index aade203e7..16b6801b8 100644 --- a/mesalib/src/glsl/lower_ubo_reference.cpp +++ b/mesalib/src/glsl/lower_ubo_reference.cpp @@ -132,7 +132,8 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue) mem_ctx = ralloc_parent(*rvalue); const char *const field_name = - interface_field_name(mem_ctx, (char *) var->interface_type->name, deref); + interface_field_name(mem_ctx, (char *) var->get_interface_type()->name, + deref); this->uniform_block = -1; for (unsigned i = 0; i < shader->NumUniformBlocks; i++) { diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp index 57bec44be..aa188b1f1 100644 --- a/mesalib/src/glsl/main.cpp +++ b/mesalib/src/glsl/main.cpp @@ -38,6 +38,8 @@ #include "loop_analysis.h" #include "standalone_scaffolding.h" +static int glsl_version = 330; + static void initialize_context(struct gl_context *ctx, gl_api api) { @@ -46,16 +48,150 @@ 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 = 330; + ctx->Const.GLSLVersion = glsl_version; ctx->Extensions.ARB_ES3_compatibility = true; - ctx->Const.MaxClipPlanes = 8; - ctx->Const.MaxDrawBuffers = 2; - - /* More than the 1.10 minimum to appease parser tests taken from - * apps that (hopefully) already checked the number of coords. - */ - ctx->Const.MaxTextureCoordUnits = 4; + switch (ctx->Const.GLSLVersion) { + case 100: + ctx->Const.MaxClipPlanes = 0; + ctx->Const.MaxCombinedTextureImageUnits = 8; + ctx->Const.MaxDrawBuffers = 2; + ctx->Const.MinProgramTexelOffset = 0; + ctx->Const.MaxProgramTexelOffset = 0; + ctx->Const.MaxLights = 0; + ctx->Const.MaxTextureCoordUnits = 0; + ctx->Const.MaxTextureUnits = 8; + + ctx->Const.VertexProgram.MaxAttribs = 8; + ctx->Const.VertexProgram.MaxTextureImageUnits = 0; + ctx->Const.VertexProgram.MaxUniformComponents = 128 * 4; + ctx->Const.VertexProgram.MaxInputComponents = 0; /* not used */ + ctx->Const.VertexProgram.MaxOutputComponents = 32; + + ctx->Const.FragmentProgram.MaxTextureImageUnits = + ctx->Const.MaxCombinedTextureImageUnits; + ctx->Const.FragmentProgram.MaxUniformComponents = 16 * 4; + ctx->Const.FragmentProgram.MaxInputComponents = + ctx->Const.VertexProgram.MaxOutputComponents; + ctx->Const.FragmentProgram.MaxOutputComponents = 0; /* not used */ + + ctx->Const.MaxVarying = ctx->Const.VertexProgram.MaxOutputComponents / 4; + break; + case 110: + case 120: + ctx->Const.MaxClipPlanes = 6; + ctx->Const.MaxCombinedTextureImageUnits = 2; + ctx->Const.MaxDrawBuffers = 1; + ctx->Const.MinProgramTexelOffset = 0; + ctx->Const.MaxProgramTexelOffset = 0; + ctx->Const.MaxLights = 8; + ctx->Const.MaxTextureCoordUnits = 2; + ctx->Const.MaxTextureUnits = 2; + + ctx->Const.VertexProgram.MaxAttribs = 16; + ctx->Const.VertexProgram.MaxTextureImageUnits = 0; + ctx->Const.VertexProgram.MaxUniformComponents = 512; + ctx->Const.VertexProgram.MaxInputComponents = 0; /* not used */ + ctx->Const.VertexProgram.MaxOutputComponents = 32; + + ctx->Const.FragmentProgram.MaxTextureImageUnits = + ctx->Const.MaxCombinedTextureImageUnits; + ctx->Const.FragmentProgram.MaxUniformComponents = 64; + ctx->Const.FragmentProgram.MaxInputComponents = + ctx->Const.VertexProgram.MaxOutputComponents; + ctx->Const.FragmentProgram.MaxOutputComponents = 0; /* not used */ + + ctx->Const.MaxVarying = ctx->Const.VertexProgram.MaxOutputComponents / 4; + break; + case 130: + case 140: + ctx->Const.MaxClipPlanes = 8; + ctx->Const.MaxCombinedTextureImageUnits = 16; + ctx->Const.MaxDrawBuffers = 8; + ctx->Const.MinProgramTexelOffset = -8; + ctx->Const.MaxProgramTexelOffset = 7; + ctx->Const.MaxLights = 8; + ctx->Const.MaxTextureCoordUnits = 8; + ctx->Const.MaxTextureUnits = 2; + + ctx->Const.VertexProgram.MaxAttribs = 16; + ctx->Const.VertexProgram.MaxTextureImageUnits = 16; + ctx->Const.VertexProgram.MaxUniformComponents = 1024; + ctx->Const.VertexProgram.MaxInputComponents = 0; /* not used */ + ctx->Const.VertexProgram.MaxOutputComponents = 64; + + ctx->Const.FragmentProgram.MaxTextureImageUnits = 16; + ctx->Const.FragmentProgram.MaxUniformComponents = 1024; + ctx->Const.FragmentProgram.MaxInputComponents = + ctx->Const.VertexProgram.MaxOutputComponents; + ctx->Const.FragmentProgram.MaxOutputComponents = 0; /* not used */ + + ctx->Const.MaxVarying = ctx->Const.VertexProgram.MaxOutputComponents / 4; + break; + case 150: + case 330: + ctx->Const.MaxClipPlanes = 8; + ctx->Const.MaxDrawBuffers = 8; + ctx->Const.MinProgramTexelOffset = -8; + ctx->Const.MaxProgramTexelOffset = 7; + ctx->Const.MaxLights = 8; + ctx->Const.MaxTextureCoordUnits = 8; + ctx->Const.MaxTextureUnits = 2; + + ctx->Const.VertexProgram.MaxAttribs = 16; + ctx->Const.VertexProgram.MaxTextureImageUnits = 16; + ctx->Const.VertexProgram.MaxUniformComponents = 1024; + ctx->Const.VertexProgram.MaxInputComponents = 0; /* not used */ + ctx->Const.VertexProgram.MaxOutputComponents = 64; + + ctx->Const.GeometryProgram.MaxTextureImageUnits = 16; + ctx->Const.GeometryProgram.MaxUniformComponents = 1024; + ctx->Const.GeometryProgram.MaxInputComponents = + ctx->Const.VertexProgram.MaxOutputComponents; + ctx->Const.GeometryProgram.MaxOutputComponents = 128; + + ctx->Const.FragmentProgram.MaxTextureImageUnits = 16; + ctx->Const.FragmentProgram.MaxUniformComponents = 1024; + ctx->Const.FragmentProgram.MaxInputComponents = + ctx->Const.GeometryProgram.MaxOutputComponents; + ctx->Const.FragmentProgram.MaxOutputComponents = 0; /* not used */ + + ctx->Const.MaxCombinedTextureImageUnits = + ctx->Const.VertexProgram.MaxTextureImageUnits + + ctx->Const.GeometryProgram.MaxTextureImageUnits + + ctx->Const.FragmentProgram.MaxTextureImageUnits; + + ctx->Const.MaxGeometryOutputVertices = 256; + ctx->Const.MaxGeometryTotalOutputComponents = 1024; + +// ctx->Const.MaxGeometryVaryingComponents = 64; + + ctx->Const.MaxVarying = 60 / 4; + break; + case 300: + ctx->Const.MaxClipPlanes = 8; + ctx->Const.MaxCombinedTextureImageUnits = 32; + ctx->Const.MaxDrawBuffers = 4; + ctx->Const.MinProgramTexelOffset = -8; + ctx->Const.MaxProgramTexelOffset = 7; + ctx->Const.MaxLights = 0; + ctx->Const.MaxTextureCoordUnits = 0; + ctx->Const.MaxTextureUnits = 0; + + ctx->Const.VertexProgram.MaxAttribs = 16; + ctx->Const.VertexProgram.MaxTextureImageUnits = 16; + ctx->Const.VertexProgram.MaxUniformComponents = 1024; + ctx->Const.VertexProgram.MaxInputComponents = 0; /* not used */ + ctx->Const.VertexProgram.MaxOutputComponents = 16 * 4; + + ctx->Const.FragmentProgram.MaxTextureImageUnits = 16; + ctx->Const.FragmentProgram.MaxUniformComponents = 224; + ctx->Const.FragmentProgram.MaxInputComponents = 15 * 4; + ctx->Const.FragmentProgram.MaxOutputComponents = 0; /* not used */ + + ctx->Const.MaxVarying = ctx->Const.FragmentProgram.MaxInputComponents / 4; + break; + } ctx->Driver.NewShader = _mesa_new_shader; } @@ -103,18 +239,17 @@ load_text_file(void *ctx, const char *file_name) return text; } -int glsl_es = 0; int dump_ast = 0; int dump_hir = 0; int dump_lir = 0; int do_link = 0; const struct option compiler_opts[] = { - { "glsl-es", 0, &glsl_es, 1 }, - { "dump-ast", 0, &dump_ast, 1 }, - { "dump-hir", 0, &dump_hir, 1 }, - { "dump-lir", 0, &dump_lir, 1 }, - { "link", 0, &do_link, 1 }, + { "dump-ast", no_argument, &dump_ast, 1 }, + { "dump-hir", no_argument, &dump_hir, 1 }, + { "dump-lir", no_argument, &dump_lir, 1 }, + { "link", no_argument, &do_link, 1 }, + { "version", required_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } }; @@ -159,11 +294,37 @@ main(int argc, char **argv) int status = EXIT_SUCCESS; struct gl_context local_ctx; struct gl_context *ctx = &local_ctx; + bool glsl_es = false; int c; int idx = 0; - while ((c = getopt_long(argc, argv, "", compiler_opts, &idx)) != -1) - /* empty */ ; + while ((c = getopt_long(argc, argv, "", compiler_opts, &idx)) != -1) { + switch (c) { + case 'v': + glsl_version = strtol(optarg, NULL, 10); + switch (glsl_version) { + case 100: + case 300: + glsl_es = true; + break; + case 110: + case 120: + case 130: + case 140: + case 150: + case 330: + glsl_es = false; + break; + default: + fprintf(stderr, "Unrecognized GLSL version `%s'\n", optarg); + usage_fail(argv[0]); + break; + } + break; + default: + break; + } + } if (argc <= optind) @@ -210,8 +371,10 @@ main(int argc, char **argv) compile_shader(ctx, shader); - if (!shader->CompileStatus) { + if (strlen(shader->InfoLog) > 0) printf("Info log for %s:\n%s\n", argv[optind], shader->InfoLog); + + if (!shader->CompileStatus) { status = EXIT_FAILURE; break; } diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp index 3b64f2cfc..7a1cf6877 100644 --- a/mesalib/src/glsl/standalone_scaffolding.cpp +++ b/mesalib/src/glsl/standalone_scaffolding.cpp @@ -90,23 +90,33 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api) ctx->Extensions.dummy_false = false; ctx->Extensions.dummy_true = true; - ctx->Extensions.ARB_ES2_compatibility = true; - ctx->Extensions.ARB_ES3_compatibility = false; + ctx->Extensions.ARB_conservative_depth = true; ctx->Extensions.ARB_draw_instanced = true; + ctx->Extensions.ARB_ES2_compatibility = true; + ctx->Extensions.ARB_ES3_compatibility = true; + ctx->Extensions.ARB_explicit_attrib_location = true; ctx->Extensions.ARB_fragment_coord_conventions = true; - ctx->Extensions.EXT_texture_array = true; - ctx->Extensions.NV_texture_rectangle = true; - ctx->Extensions.EXT_texture3D = true; - ctx->Extensions.OES_EGL_image_external = true; + ctx->Extensions.ARB_gpu_shader5 = true; ctx->Extensions.ARB_shader_bit_encoding = true; + ctx->Extensions.ARB_shader_stencil_export = true; + ctx->Extensions.ARB_shader_texture_lod = true; + ctx->Extensions.ARB_shading_language_420pack = true; ctx->Extensions.ARB_shading_language_packing = true; - ctx->Extensions.OES_standard_derivatives = true; ctx->Extensions.ARB_texture_cube_map_array = true; + ctx->Extensions.ARB_texture_gather = true; ctx->Extensions.ARB_texture_multisample = true; ctx->Extensions.ARB_texture_query_levels = true; ctx->Extensions.ARB_texture_query_lod = true; - ctx->Extensions.ARB_gpu_shader5 = true; - ctx->Extensions.ARB_texture_gather = true; + ctx->Extensions.ARB_uniform_buffer_object = true; + + ctx->Extensions.OES_EGL_image_external = true; + ctx->Extensions.OES_standard_derivatives = true; + + ctx->Extensions.EXT_shader_integer_mix = true; + ctx->Extensions.EXT_texture3D = true; + ctx->Extensions.EXT_texture_array = true; + + ctx->Extensions.NV_texture_rectangle = true; ctx->Const.GLSLVersion = 120; diff --git a/mesalib/src/mapi/glapi/gen/gl_API.xml b/mesalib/src/mapi/glapi/gen/gl_API.xml index 3ffa81787..48fce36ab 100644 --- a/mesalib/src/mapi/glapi/gen/gl_API.xml +++ b/mesalib/src/mapi/glapi/gen/gl_API.xml @@ -5495,7 +5495,7 @@ - + diff --git a/mesalib/src/mapi/glapi/gen/gl_gentable.py b/mesalib/src/mapi/glapi/gen/gl_gentable.py index 5c3527166..fa9626825 100644 --- a/mesalib/src/mapi/glapi/gen/gl_gentable.py +++ b/mesalib/src/mapi/glapi/gen/gl_gentable.py @@ -42,7 +42,7 @@ header = """/* GLXEXT is the define used in the xserver when the GLX extension i #endif #if (defined(GLXEXT) && defined(HAVE_BACKTRACE)) \\ - || (!defined(GLXEXT) && defined(DEBUG) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__OpenBSD__)) + || (!defined(GLXEXT) && defined(DEBUG) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__OpenBSD__) && !defined(__NetBSD__)) #define USE_BACKTRACE #endif diff --git a/mesalib/src/mesa/drivers/SConscript b/mesalib/src/mesa/drivers/SConscript index 6dcc50655..355e6807a 100644 --- a/mesalib/src/mesa/drivers/SConscript +++ b/mesalib/src/mesa/drivers/SConscript @@ -5,7 +5,7 @@ SConscript('osmesa/SConscript') if env['x11']: SConscript('x11/SConscript') -if env['drm']: +if env['dri']: SConscript('dri/common/xmlpool/SConscript') if env['platform'] == 'windows': diff --git a/mesalib/src/mesa/drivers/dri/Makefile.am b/mesalib/src/mesa/drivers/dri/Makefile.am index 48d36858b..7fa0ad73d 100644 --- a/mesalib/src/mesa/drivers/dri/Makefile.am +++ b/mesalib/src/mesa/drivers/dri/Makefile.am @@ -1,8 +1,6 @@ SUBDIRS = -if HAVE_COMMON_DRI SUBDIRS+=common -endif if HAVE_I915_DRI SUBDIRS+=i915 diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c index fa520ea90..db44eede6 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_util.c +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c @@ -39,11 +39,17 @@ */ +#include +#ifndef __NOT_HAVE_DRM_H #include +#endif #include "dri_util.h" #include "utils.h" #include "xmlpool.h" #include "../glsl/glsl_parser_extras.h" +#include "main/mtypes.h" +#include "main/version.h" +#include "main/macros.h" PUBLIC const char __dri2ConfigOptions[] = DRI_CONF_BEGIN @@ -70,9 +76,18 @@ setupLoaderExtensions(__DRIscreen *psp, psp->dri2.image = (__DRIimageLookupExtension *) extensions[i]; if (strcmp(extensions[i]->name, __DRI_USE_INVALIDATE) == 0) psp->dri2.useInvalidate = (__DRIuseInvalidateExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0) + psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i]; } } +/** + * This is the first entrypoint in the driver called by the DRI driver loader + * after dlopen()ing it. + * + * It's used to create global state for the driver across contexts on the same + * Display. + */ static __DRIscreen * dri2CreateNewScreen(int scrn, int fd, const __DRIextension **extensions, @@ -80,21 +95,26 @@ dri2CreateNewScreen(int scrn, int fd, { static const __DRIextension *emptyExtensionList[] = { NULL }; __DRIscreen *psp; - drmVersionPtr version; psp = calloc(1, sizeof(*psp)); if (!psp) return NULL; + psp->driver = &driDriverAPI; + setupLoaderExtensions(psp, extensions); - version = drmGetVersion(fd); - if (version) { - psp->drm_version.major = version->version_major; - psp->drm_version.minor = version->version_minor; - psp->drm_version.patch = version->version_patchlevel; - drmFreeVersion(version); +#ifndef __NOT_HAVE_DRM_H + if (fd != -1) { + drmVersionPtr version = drmGetVersion(fd); + if (version) { + psp->drm_version.major = version->version_major; + psp->drm_version.minor = version->version_minor; + psp->drm_version.patch = version->version_patchlevel; + drmFreeVersion(version); + } } +#endif psp->loaderPrivate = data; @@ -102,20 +122,46 @@ dri2CreateNewScreen(int scrn, int fd, psp->fd = fd; psp->myNum = scrn; - psp->api_mask = (1 << __DRI_API_OPENGL); - - *driver_configs = driDriverAPI.InitScreen(psp); + *driver_configs = psp->driver->InitScreen(psp); if (*driver_configs == NULL) { free(psp); return NULL; } + int gl_version_override = _mesa_get_gl_version_override(); + if (gl_version_override >= 31) { + psp->max_gl_core_version = MAX2(psp->max_gl_core_version, + gl_version_override); + } else { + psp->max_gl_compat_version = MAX2(psp->max_gl_compat_version, + gl_version_override); + } + + psp->api_mask = (1 << __DRI_API_OPENGL); + if (psp->max_gl_core_version > 0) + psp->api_mask |= (1 << __DRI_API_OPENGL_CORE); + if (psp->max_gl_es1_version > 0) + psp->api_mask |= (1 << __DRI_API_GLES); + if (psp->max_gl_es2_version > 0) + psp->api_mask |= (1 << __DRI_API_GLES2); + if (psp->max_gl_es2_version >= 30) + psp->api_mask |= (1 << __DRI_API_GLES3); + driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions); driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum, "dri2"); + return psp; } +/** swrast driver createNewScreen entrypoint. */ +static __DRIscreen * +driCreateNewScreen(int scrn, const __DRIextension **extensions, + const __DRIconfig ***driver_configs, void *data) +{ + return dri2CreateNewScreen(scrn, -1, extensions, driver_configs, data); +} + /** * Destroy the per-screen private information. * @@ -133,7 +179,7 @@ static void driDestroyScreen(__DRIscreen *psp) _mesa_destroy_shader_compiler(); - driDriverAPI.DestroyScreen(psp); + psp->driver->DestroyScreen(psp); driDestroyOptionCache(&psp->optionCache); driDestroyOptionInfo(&psp->optionInfo); @@ -150,6 +196,45 @@ static const __DRIextension **driGetExtensions(__DRIscreen *psp) /*@}*/ +static bool +validate_context_version(__DRIscreen *screen, + int mesa_api, + unsigned major_version, + unsigned minor_version, + unsigned *dri_ctx_error) +{ + unsigned req_version = 10 * major_version + minor_version; + unsigned max_version = 0; + + switch (mesa_api) { + case API_OPENGL_COMPAT: + max_version = screen->max_gl_compat_version; + break; + case API_OPENGL_CORE: + max_version = screen->max_gl_core_version; + break; + case API_OPENGLES: + max_version = screen->max_gl_es1_version; + break; + case API_OPENGLES2: + max_version = screen->max_gl_es2_version; + break; + default: + max_version = 0; + break; + } + + if (max_version == 0) { + *dri_ctx_error = __DRI_CTX_ERROR_BAD_API; + return false; + } else if (req_version > max_version) { + *dri_ctx_error = __DRI_CTX_ERROR_BAD_VERSION; + return false; + } + + return true; +} + /*****************************************************************/ /** \name Context handling functions */ /*****************************************************************/ @@ -271,6 +356,10 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api, return NULL; } + if (!validate_context_version(screen, mesa_api, + major_version, minor_version, error)) + return NULL; + context = calloc(1, sizeof *context); if (!context) { *error = __DRI_CTX_ERROR_NO_MEMORY; @@ -283,13 +372,21 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api, context->driDrawablePriv = NULL; context->driReadablePriv = NULL; - if (!driDriverAPI.CreateContext(mesa_api, modes, context, - major_version, minor_version, - flags, error, shareCtx) ) { + if (!screen->driver->CreateContext(mesa_api, modes, context, + major_version, minor_version, + flags, error, shareCtx) ) { free(context); return NULL; } + struct gl_context *ctx = context->driverPrivate; + if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0) + ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT; + if ((flags & __DRI_CTX_FLAG_DEBUG) != 0) { + ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT; + ctx->Debug.DebugOutput = GL_TRUE; + } + *error = __DRI_CTX_ERROR_SUCCESS; return context; } @@ -324,7 +421,7 @@ static void driDestroyContext(__DRIcontext *pcp) { if (pcp) { - driDriverAPI.DestroyContext(pcp); + pcp->driScreenPriv->driver->DestroyContext(pcp); free(pcp); } } @@ -377,7 +474,7 @@ static int driBindContext(__DRIcontext *pcp, dri_get_drawable(prp); } - return driDriverAPI.MakeCurrent(pcp, pdp, prp); + return pcp->driScreenPriv->driver->MakeCurrent(pcp, pdp, prp); } /** @@ -416,7 +513,7 @@ static int driUnbindContext(__DRIcontext *pcp) if (!pdp && !prp) return GL_TRUE; - driDriverAPI.UnbindContext(pcp); + pcp->driScreenPriv->driver->UnbindContext(pcp); assert(pdp); if (pdp->refcount == 0) { @@ -435,10 +532,6 @@ static int driUnbindContext(__DRIcontext *pcp) dri_put_drawable(prp); } - /* XXX this is disabled so that if we call SwapBuffers on an unbound - * window we can determine the last context bound to the window and - * use that context's lock. (BrianP, 2-Dec-2000) - */ pcp->driDrawablePriv = NULL; pcp->driReadablePriv = NULL; @@ -460,7 +553,7 @@ static void dri_put_drawable(__DRIdrawable *pdp) if (pdp->refcount) return; - driDriverAPI.DestroyBuffer(pdp); + pdp->driScreenPriv->driver->DestroyBuffer(pdp); free(pdp); } } @@ -487,7 +580,8 @@ dri2CreateNewDrawable(__DRIscreen *screen, dri_get_drawable(pdraw); - if (!driDriverAPI.CreateBuffer(screen, pdraw, &config->modes, GL_FALSE)) { + if (!screen->driver->CreateBuffer(screen, pdraw, &config->modes, + GL_FALSE)) { free(pdraw); return NULL; } @@ -508,14 +602,14 @@ dri2AllocateBuffer(__DRIscreen *screen, unsigned int attachment, unsigned int format, int width, int height) { - return driDriverAPI.AllocateBuffer(screen, attachment, format, - width, height); + return screen->driver->AllocateBuffer(screen, attachment, format, + width, height); } static void dri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer) { - driDriverAPI.ReleaseBuffer(screen, buffer); + screen->driver->ReleaseBuffer(screen, buffer); } @@ -559,6 +653,19 @@ dri2GetAPIMask(__DRIscreen *screen) return screen->api_mask; } +/** + * swrast swapbuffers entrypoint. + * + * DRI2 implements this inside the loader with only flushes handled by the + * driver. + */ +static void +driSwapBuffers(__DRIdrawable *pdp) +{ + assert(pdp->driScreenPriv->swrast_loader); + + pdp->driScreenPriv->driver->SwapBuffers(pdp); +} /** Core interface */ const __DRIcoreExtension driCoreExtension = { @@ -571,8 +678,8 @@ const __DRIcoreExtension driCoreExtension = { .indexConfigAttrib = driIndexConfigAttrib, .createNewDrawable = NULL, .destroyDrawable = driDestroyDrawable, - .swapBuffers = NULL, - .createNewContext = NULL, + .swapBuffers = driSwapBuffers, /* swrast */ + .createNewContext = dri2CreateNewContext, /* swrast */ .copyContext = driCopyContext, .destroyContext = driDestroyContext, .bindContext = driBindContext, @@ -593,6 +700,14 @@ const __DRIdri2Extension driDRI2Extension = { .createContextAttribs = dri2CreateContextAttribs }; +const __DRIswrastExtension driSWRastExtension = { + { __DRI_SWRAST, __DRI_SWRAST_VERSION }, + driCreateNewScreen, + dri2CreateNewDrawable, + dri2CreateNewContextForAPI, + dri2CreateContextAttribs +}; + const __DRI2configQueryExtension dri2ConfigQueryExtension = { .base = { __DRI2_CONFIG_QUERY, __DRI2_CONFIG_QUERY_VERSION }, diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.h b/mesalib/src/mesa/drivers/dri/common/dri_util.h index 900f04853..61c80bc45 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_util.h +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.h @@ -122,6 +122,12 @@ extern const struct __DriverAPIRec driDriverAPI; * Per-screen private driver information. */ struct __DRIscreenRec { + /** + * Driver-specific entrypoints provided by the driver's + * __DRIDriverVtableExtensionRec. + */ + const struct __DriverAPIRec *driver; + /** * Current screen's number */ @@ -151,6 +157,11 @@ struct __DRIscreenRec { void *loaderPrivate; + int max_gl_core_version; + int max_gl_compat_version; + int max_gl_es1_version; + int max_gl_es2_version; + const __DRIextension **extensions; const __DRIswrastLoaderExtension *swrast_loader; diff --git a/mesalib/src/mesa/drivers/dri/common/drisw_util.c b/mesalib/src/mesa/drivers/dri/common/drisw_util.c deleted file mode 100644 index 89f03c310..000000000 --- a/mesalib/src/mesa/drivers/dri/common/drisw_util.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. - * All Rights Reserved. - * Copyright 2010 George Sapountzis - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file drisw_util.c - * - * DRISW utility functions, i.e. dri_util.c stripped from drm-specific bits. - */ - -#include "dri_util.h" -#include "utils.h" - - -/** - * Screen functions - */ - -static void -setupLoaderExtensions(__DRIscreen *psp, - const __DRIextension **extensions) -{ - int i; - - for (i = 0; extensions[i]; i++) { - if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0) - psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i]; - } -} - -static __DRIscreen * -driCreateNewScreen(int scrn, const __DRIextension **extensions, - const __DRIconfig ***driver_configs, void *data) -{ - static const __DRIextension *emptyExtensionList[] = { NULL }; - __DRIscreen *psp; - - psp = CALLOC_STRUCT(__DRIscreenRec); - if (!psp) - return NULL; - - setupLoaderExtensions(psp, extensions); - - psp->loaderPrivate = data; - - psp->extensions = emptyExtensionList; - psp->fd = -1; - psp->myNum = scrn; - - *driver_configs = driDriverAPI.InitScreen(psp); - if (*driver_configs == NULL) { - free(psp); - return NULL; - } - - return psp; -} - -static void driDestroyScreen(__DRIscreen *psp) -{ - if (psp) { - driDriverAPI.DestroyScreen(psp); - free(psp); - } -} - -static const __DRIextension **driGetExtensions(__DRIscreen *psp) -{ - return psp->extensions; -} - - -/** - * Context functions - */ - -static __DRIcontext * -driCreateContextAttribs(__DRIscreen *screen, int api, - const __DRIconfig *config, - __DRIcontext *shared, - unsigned num_attribs, - const uint32_t *attribs, - unsigned *error, - void *data) -{ - __DRIcontext *pcp; - const struct gl_config *modes = (config != NULL) ? &config->modes : NULL; - void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL; - gl_api mesa_api; - unsigned major_version = 1; - unsigned minor_version = 0; - uint32_t flags = 0; - - /* Either num_attribs is zero and attribs is NULL, or num_attribs is not - * zero and attribs is not NULL. - */ - assert((num_attribs == 0) == (attribs == NULL)); - - switch (api) { - case __DRI_API_OPENGL: - mesa_api = API_OPENGL_COMPAT; - break; - case __DRI_API_GLES: - mesa_api = API_OPENGLES; - break; - case __DRI_API_GLES2: - case __DRI_API_GLES3: - mesa_api = API_OPENGLES2; - break; - case __DRI_API_OPENGL_CORE: - mesa_api = API_OPENGL_CORE; - break; - default: - *error = __DRI_CTX_ERROR_BAD_API; - return NULL; - } - - for (unsigned i = 0; i < num_attribs; i++) { - switch (attribs[i * 2]) { - case __DRI_CTX_ATTRIB_MAJOR_VERSION: - major_version = attribs[i * 2 + 1]; - break; - case __DRI_CTX_ATTRIB_MINOR_VERSION: - minor_version = attribs[i * 2 + 1]; - break; - case __DRI_CTX_ATTRIB_FLAGS: - flags = attribs[i * 2 + 1]; - break; - default: - /* We can't create a context that satisfies the requirements of an - * attribute that we don't understand. Return failure. - */ - return NULL; - } - } - - /* Mesa does not support the GL_ARB_compatibilty extension or the - * compatibility profile. This means that we treat a API_OPENGL_COMPAT 3.1 as - * API_OPENGL_CORE and reject API_OPENGL_COMPAT 3.2+. - */ - if (mesa_api == API_OPENGL_COMPAT && major_version == 3 && minor_version == 1) - mesa_api = API_OPENGL_CORE; - - if (mesa_api == API_OPENGL_COMPAT - && ((major_version > 3) - || (major_version == 3 && minor_version >= 2))) { - *error = __DRI_CTX_ERROR_BAD_API; - return NULL; - } - /* There are no forward-compatible contexts before OpenGL 3.0. The - * GLX_ARB_create_context spec says: - * - * "Forward-compatible contexts are defined only for OpenGL versions - * 3.0 and later." - * - * Moreover, Mesa can't fulfill the requirements of a forward-looking - * context. Return failure if a forward-looking context is requested. - * - * In Mesa, a debug context is the same as a regular context. - */ - if (major_version >= 3) { - if ((flags & ~__DRI_CTX_FLAG_DEBUG) != 0) - return NULL; - } - - pcp = CALLOC_STRUCT(__DRIcontextRec); - if (!pcp) - return NULL; - - pcp->loaderPrivate = data; - - pcp->driScreenPriv = screen; - pcp->driDrawablePriv = NULL; - pcp->driReadablePriv = NULL; - - if (!driDriverAPI.CreateContext(mesa_api, modes, pcp, - major_version, minor_version, - flags, error, shareCtx)) { - free(pcp); - return NULL; - } - - return pcp; -} - -static __DRIcontext * -driCreateNewContextForAPI(__DRIscreen *psp, int api, - const __DRIconfig *config, - __DRIcontext *shared, void *data) -{ - unsigned error; - - return driCreateContextAttribs(psp, api, config, shared, 0, NULL, - &error, data); -} - -static __DRIcontext * -driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config, - __DRIcontext *shared, void *data) -{ - return driCreateNewContextForAPI(psp, __DRI_API_OPENGL, - config, shared, data); -} - -static void -driDestroyContext(__DRIcontext *pcp) -{ - if (pcp) { - driDriverAPI.DestroyContext(pcp); - free(pcp); - } -} - -static int -driCopyContext(__DRIcontext *dst, __DRIcontext *src, unsigned long mask) -{ - return GL_FALSE; -} - -static void dri_get_drawable(__DRIdrawable *pdp); -static void dri_put_drawable(__DRIdrawable *pdp); - -static int driBindContext(__DRIcontext *pcp, - __DRIdrawable *pdp, - __DRIdrawable *prp) -{ - /* Bind the drawable to the context */ - if (pcp) { - pcp->driDrawablePriv = pdp; - pcp->driReadablePriv = prp; - if (pdp) { - pdp->driContextPriv = pcp; - dri_get_drawable(pdp); - } - if (prp && pdp != prp) { - dri_get_drawable(prp); - } - } - - return driDriverAPI.MakeCurrent(pcp, pdp, prp); -} - -static int driUnbindContext(__DRIcontext *pcp) -{ - __DRIdrawable *pdp; - __DRIdrawable *prp; - - if (pcp == NULL) - return GL_FALSE; - - pdp = pcp->driDrawablePriv; - prp = pcp->driReadablePriv; - - /* already unbound */ - if (!pdp && !prp) - return GL_TRUE; - - driDriverAPI.UnbindContext(pcp); - - dri_put_drawable(pdp); - - if (prp != pdp) { - dri_put_drawable(prp); - } - - pcp->driDrawablePriv = NULL; - pcp->driReadablePriv = NULL; - - return GL_TRUE; -} - - -/** - * Drawable functions - */ - -static void dri_get_drawable(__DRIdrawable *pdp) -{ - pdp->refcount++; -} - -static void dri_put_drawable(__DRIdrawable *pdp) -{ - if (pdp) { - pdp->refcount--; - if (pdp->refcount) - return; - - driDriverAPI.DestroyBuffer(pdp); - free(pdp); - } -} - -static __DRIdrawable * -driCreateNewDrawable(__DRIscreen *psp, - const __DRIconfig *config, void *data) -{ - __DRIdrawable *pdp; - - pdp = CALLOC_STRUCT(__DRIdrawableRec); - if (!pdp) - return NULL; - - pdp->loaderPrivate = data; - - pdp->driScreenPriv = psp; - pdp->driContextPriv = NULL; - - dri_get_drawable(pdp); - - if (!driDriverAPI.CreateBuffer(psp, pdp, &config->modes, GL_FALSE)) { - free(pdp); - return NULL; - } - - pdp->lastStamp = 1; /* const */ - - return pdp; -} - -static void -driDestroyDrawable(__DRIdrawable *pdp) -{ - dri_put_drawable(pdp); -} - -static void driSwapBuffers(__DRIdrawable *pdp) -{ - driDriverAPI.SwapBuffers(pdp); -} - -const __DRIcoreExtension driCoreExtension = { - { __DRI_CORE, __DRI_CORE_VERSION }, - NULL, /* driCreateNewScreen */ - driDestroyScreen, - driGetExtensions, - driGetConfigAttrib, - driIndexConfigAttrib, - NULL, /* driCreateNewDrawable */ - driDestroyDrawable, - driSwapBuffers, - driCreateNewContext, - driCopyContext, - driDestroyContext, - driBindContext, - driUnbindContext -}; - -const __DRIswrastExtension driSWRastExtension = { - { __DRI_SWRAST, __DRI_SWRAST_VERSION }, - driCreateNewScreen, - driCreateNewDrawable, - driCreateNewContextForAPI, - driCreateContextAttribs -}; diff --git a/mesalib/src/mesa/drivers/dri/common/utils.c b/mesalib/src/mesa/drivers/dri/common/utils.c index c9fc21891..f3780d9b6 100644 --- a/mesalib/src/mesa/drivers/dri/common/utils.c +++ b/mesalib/src/mesa/drivers/dri/common/utils.c @@ -189,6 +189,10 @@ driCreateConfigs(gl_format format, { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* MESA_FORMAT_ARGB8888 */ { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, + /* MESA_FORMAT_XRGB2101010_UNORM */ + { 0x3FF00000, 0x000FFC00, 0x000003FF, 0x00000000 }, + /* MESA_FORMAT_ARGB2101010 */ + { 0x3FF00000, 0x000FFC00, 0x000003FF, 0xC0000000 }, }; const uint32_t * masks; @@ -214,6 +218,12 @@ driCreateConfigs(gl_format format, case MESA_FORMAT_SARGB8: masks = masks_table[2]; break; + case MESA_FORMAT_XRGB2101010_UNORM: + masks = masks_table[3]; + break; + case MESA_FORMAT_ARGB2101010: + masks = masks_table[4]; + break; default: fprintf(stderr, "[%s:%u] Unknown framebuffer type %s (%d).\n", __FUNCTION__, __LINE__, diff --git a/mesalib/src/mesa/drivers/dri/swrast/Makefile.am b/mesalib/src/mesa/drivers/dri/swrast/Makefile.am index 9652583f2..c51ad2d87 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/Makefile.am +++ b/mesalib/src/mesa/drivers/dri/swrast/Makefile.am @@ -30,6 +30,7 @@ AM_CFLAGS = \ -I$(top_srcdir)/src/mapi \ -I$(top_srcdir)/src/mesa/ \ -I$(top_srcdir)/src/mesa/drivers/dri/common \ + -I$(top_builddir)/src/mesa/drivers/dri/common \ $(DEFINES) \ $(VISIBILITY_CFLAGS) diff --git a/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources b/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources index 7630dba4b..fc7ef32db 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources +++ b/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources @@ -3,7 +3,8 @@ SWRAST_DRIVER_FILES = \ SWRAST_COMMON_FILES = \ ../common/utils.c \ - ../common/drisw_util.c + ../common/dri_util.c \ + ../common/xmlconfig.c SWRAST_C_FILES = \ $(SWRAST_COMMON_FILES) \ diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c index 332c7b72f..4725a7f42 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c +++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c @@ -200,6 +200,10 @@ dri_init_screen(__DRIscreen * psp) TRACE; + psp->max_gl_compat_version = 21; + psp->max_gl_es1_version = 11; + psp->max_gl_es2_version = 20; + psp->extensions = dri_screen_extensions; configs16 = swrastFillInModes(psp, 16, 16, 0, 1); @@ -674,22 +678,6 @@ dri_create_context(gl_api api, */ (void) flags; - switch (api) { - case API_OPENGL_COMPAT: - if (major_version > 2 - || (major_version == 2 && minor_version > 1)) { - *error = __DRI_CTX_ERROR_BAD_VERSION; - return GL_FALSE; - } - break; - case API_OPENGLES: - case API_OPENGLES2: - break; - case API_OPENGL_CORE: - *error = __DRI_CTX_ERROR_BAD_API; - return GL_FALSE; - } - ctx = CALLOC_STRUCT(dri_context); if (ctx == NULL) { *error = __DRI_CTX_ERROR_NO_MEMORY; diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c index 002992186..f285c9748 100644 --- a/mesalib/src/mesa/main/api_validate.c +++ b/mesalib/src/mesa/main/api_validate.c @@ -330,26 +330,43 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name) if (_mesa_is_xfb_active_and_unpaused(ctx)) { GLboolean pass = GL_TRUE; - switch (mode) { - case GL_POINTS: - pass = ctx->TransformFeedback.Mode == GL_POINTS; - break; - case GL_LINES: - case GL_LINE_STRIP: - case GL_LINE_LOOP: - pass = ctx->TransformFeedback.Mode == GL_LINES; - break; - default: - pass = ctx->TransformFeedback.Mode == GL_TRIANGLES; - break; + if(ctx->Shader.CurrentGeometryProgram) { + switch (ctx->Shader.CurrentGeometryProgram->Geom.OutputType) { + case GL_POINTS: + pass = ctx->TransformFeedback.Mode == GL_POINTS; + break; + case GL_LINE_STRIP: + pass = ctx->TransformFeedback.Mode == GL_LINES; + break; + case GL_TRIANGLE_STRIP: + pass = ctx->TransformFeedback.Mode == GL_TRIANGLES; + break; + default: + pass = GL_FALSE; + } + } + else { + switch (mode) { + case GL_POINTS: + pass = ctx->TransformFeedback.Mode == GL_POINTS; + break; + case GL_LINES: + case GL_LINE_STRIP: + case GL_LINE_LOOP: + pass = ctx->TransformFeedback.Mode == GL_LINES; + break; + default: + pass = ctx->TransformFeedback.Mode == GL_TRIANGLES; + break; + } } if (!pass) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(mode=%s vs transform feedback %s)", - name, - _mesa_lookup_prim_by_nr(mode), - _mesa_lookup_prim_by_nr(ctx->TransformFeedback.Mode)); - return GL_FALSE; + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(mode=%s vs transform feedback %s)", + name, + _mesa_lookup_prim_by_nr(mode), + _mesa_lookup_prim_by_nr(ctx->TransformFeedback.Mode)); + return GL_FALSE; } } diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index 0806e41a0..29469ce33 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -575,7 +575,8 @@ struct dd_function_table { GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size ); - /* May return NULL if MESA_MAP_NOWAIT_BIT is set in access: + /* Returns pointer to the start of the mapped range. + * May return NULL if MESA_MAP_NOWAIT_BIT is set in access: */ void * (*MapBufferRange)( struct gl_context *ctx, GLintptr offset, GLsizeiptr length, GLbitfield access, diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 1034c7a71..9dd71612f 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -3585,6 +3585,7 @@ invalidate_framebuffer_storage(GLenum target, GLsizei numAttachments, "%s(attachment >= max. color attachments)", name); return; } + break; } default: goto invalid_enum; diff --git a/mesalib/src/mesa/main/imports.c b/mesalib/src/mesa/main/imports.c index ca6b1d53e..277e9476a 100644 --- a/mesalib/src/mesa/main/imports.c +++ b/mesalib/src/mesa/main/imports.c @@ -566,7 +566,8 @@ float _mesa_strtof( const char *s, char **end ) { #if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \ - !defined(ANDROID) && !defined(__HAIKU__) && !defined(__UCLIBC__) + !defined(ANDROID) && !defined(__HAIKU__) && !defined(__UCLIBC__) && \ + !defined(__NetBSD__) static locale_t loc = NULL; if (!loc) { loc = newlocale(LC_CTYPE_MASK, "C", NULL); diff --git a/mesalib/src/mesa/main/macros.h b/mesalib/src/mesa/main/macros.h index 1052f7560..880c6564e 100644 --- a/mesalib/src/mesa/main/macros.h +++ b/mesalib/src/mesa/main/macros.h @@ -184,6 +184,28 @@ static inline GLfloat UINT_AS_FLT(GLuint u) return tmp.f; } +/** + * Convert a floating point value to an unsigned fixed point value. + * + * \param frac_bits The number of bits used to store the fractional part. + */ +static INLINE uint32_t +U_FIXED(float value, uint32_t frac_bits) +{ + value *= (1 << frac_bits); + return value < 0 ? 0 : value; +} + +/** + * Convert a floating point value to an signed fixed point value. + * + * \param frac_bits The number of bits used to store the fractional part. + */ +static INLINE uint32_t +S_FIXED(float value, uint32_t frac_bits) +{ + return value * (1 << frac_bits); +} /*@}*/ @@ -673,8 +695,20 @@ minify(unsigned value, unsigned levels) * * \sa ROUND_DOWN_TO() */ -#define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1)) +#define ALIGN(value, alignment) (((value) + (alignment) - 1) & ~((alignment) - 1)) +/** + * Align a value down to an alignment value + * + * If \c value is not already aligned to the requested alignment value, it + * will be rounded down. + * + * \param value Value to be rounded + * \param alignment Alignment value to be used. This must be a power of two. + * + * \sa ALIGN() + */ +#define ROUND_DOWN_TO(value, alignment) ((value) & ~(alignment - 1)) /** Cross product of two 3-element vectors */ diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 4c0484aaf..d3677c851 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -743,12 +743,6 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) if (!sh) return; - /* Geometry shaders are not yet fully supported, so issue a warning message - * if we're compiling one. - */ - if (sh->Type == GL_GEOMETRY_SHADER) - printf("WARNING: Geometry shader support is currently experimental.\n"); - options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(sh->Type)]; /* set default pragma state for shader */ diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c index 7050f1080..d66ca1abc 100644 --- a/mesalib/src/mesa/main/texgetimage.c +++ b/mesalib/src/mesa/main/texgetimage.c @@ -319,7 +319,7 @@ get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions, * Return a base GL format given the user-requested format * for glGetTexImage(). */ -static GLenum +GLenum _mesa_base_pack_format(GLenum format) { switch (format) { diff --git a/mesalib/src/mesa/main/texgetimage.h b/mesalib/src/mesa/main/texgetimage.h index 91ae6e2e9..a292fabc0 100644 --- a/mesalib/src/mesa/main/texgetimage.h +++ b/mesalib/src/mesa/main/texgetimage.h @@ -33,6 +33,9 @@ struct gl_context; struct gl_texture_image; struct gl_texture_object; +extern GLenum +_mesa_base_pack_format(GLenum format); + extern void _mesa_get_teximage(struct gl_context *ctx, GLenum format, GLenum type, GLvoid *pixels, diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index 04385e1e9..76d8d9ba3 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -3961,6 +3961,7 @@ store_texsubimage(struct gl_context *ctx, case GL_TEXTURE_2D: case GL_TEXTURE_RECTANGLE: case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_EXTERNAL_OES: /* one image slice, nothing special needs to be done */ break; case GL_TEXTURE_1D: diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index 6b22b5074..cfad91bc4 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -1497,6 +1497,9 @@ ir_to_mesa_visitor::visit(ir_expression *ir) case ir_quadop_bitfield_insert: case ir_binop_ldexp: case ir_triop_csel: + case ir_binop_carry: + case ir_binop_borrow: + case ir_binop_imul_high: assert(!"not supported"); break; diff --git a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c index 25cc61aef..7fa4cbdc4 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * 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. @@ -22,7 +22,7 @@ * 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. - * + * **************************************************************************/ @@ -78,7 +78,7 @@ st_bufferobj_free(struct gl_context *ctx, struct gl_buffer_object *obj) assert(obj->RefCount == 0); assert(st_obj->transfer == NULL); - if (st_obj->buffer) + if (st_obj->buffer) pipe_resource_reference(&st_obj->buffer, NULL); free(st_obj->Base.Label); @@ -175,7 +175,7 @@ st_bufferobj_data(struct gl_context *ctx, GLenum target, GLsizeiptrARB size, const GLvoid * data, - GLenum usage, + GLenum usage, struct gl_buffer_object *obj) { struct st_context *st = st_context(ctx); @@ -200,8 +200,8 @@ st_bufferobj_data(struct gl_context *ctx, st_obj->Base.Size = size; st_obj->Base.Usage = usage; - - switch(target) { + + switch (target) { case GL_PIXEL_PACK_BUFFER_ARB: case GL_PIXEL_UNPACK_BUFFER_ARB: bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; @@ -302,7 +302,7 @@ st_bufferobj_map_range(struct gl_context *ctx, else flags |= PIPE_TRANSFER_DISCARD_RANGE; } - + if (access & GL_MAP_UNSYNCHRONIZED_BIT) flags |= PIPE_TRANSFER_UNSYNCHRONIZED; @@ -348,11 +348,11 @@ st_bufferobj_flush_mapped_range(struct gl_context *ctx, assert(length >= 0); assert(offset + length <= obj->Length); assert(obj->Pointer); - + if (!length) return; - pipe_buffer_flush_mapped_range(pipe, st_obj->transfer, + pipe_buffer_flush_mapped_range(pipe, st_obj->transfer, obj->Offset + offset, length); } @@ -392,7 +392,7 @@ st_copy_buffer_subdata(struct gl_context *ctx, struct st_buffer_object *dstObj = st_buffer_object(dst); struct pipe_box box; - if(!size) + if (!size) return; /* buffer should not already be mapped */ diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c index 64bfd1faa..33c2ca661 100644 --- a/mesalib/src/mesa/state_tracker/st_format.c +++ b/mesalib/src/mesa/state_tracker/st_format.c @@ -35,6 +35,8 @@ #include "main/imports.h" #include "main/context.h" #include "main/glformats.h" +#include "main/texgetimage.h" +#include "main/teximage.h" #include "main/texstore.h" #include "main/image.h" #include "main/macros.h" @@ -1745,6 +1747,40 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target, bindings |= PIPE_BIND_RENDER_TARGET; } + /* GLES allows the driver to choose any format which matches + * the format+type combo, because GLES only supports unsized internal + * formats and expects the driver to choose whatever suits it. + */ + if (_mesa_is_gles(ctx)) { + GLenum baseFormat = _mesa_base_tex_format(ctx, internalFormat); + GLenum basePackFormat = _mesa_base_pack_format(format); + GLenum iformat = internalFormat; + + /* Treat GL_BGRA as GL_RGBA. */ + if (iformat == GL_BGRA) + iformat = GL_RGBA; + + /* Check if the internalformat is unsized and compatible + * with the "format". + */ + if (iformat == baseFormat && iformat == basePackFormat) { + pFormat = st_choose_matching_format(st->pipe->screen, bindings, + format, type, + ctx->Unpack.SwapBytes); + + if (pFormat != PIPE_FORMAT_NONE) + return st_pipe_format_to_mesa_format(pFormat); + + /* try choosing format again, this time without render target bindings */ + pFormat = st_choose_matching_format(st->pipe->screen, + PIPE_BIND_SAMPLER_VIEW, + format, type, + ctx->Unpack.SwapBytes); + if (pFormat != PIPE_FORMAT_NONE) + return st_pipe_format_to_mesa_format(pFormat); + } + } + pFormat = st_choose_format(st, internalFormat, format, type, PIPE_TEXTURE_2D, 0, bindings, ctx->Mesa_DXTn); 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 d1706ca27..8d06ac6f7 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -1978,6 +1978,9 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) case ir_binop_vector_extract: case ir_triop_vector_insert: case ir_binop_ldexp: + case ir_binop_carry: + case ir_binop_borrow: + case ir_binop_imul_high: /* This operation is not supported, or should have already been handled. */ assert(!"Invalid ir opcode in glsl_to_tgsi_visitor::visit()"); @@ -2791,6 +2794,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) case ir_tg4: assert(!"Unexpected ir_tg4 opcode"); break; + case ir_query_levels: + assert(!"Unexpected ir_query_levels opcode"); + break; } if (ir->projector) { diff --git a/mesalib/src/mesa/vbo/vbo_exec.c b/mesalib/src/mesa/vbo/vbo_exec.c index aa2c7b07b..2f05e00c8 100644 --- a/mesalib/src/mesa/vbo/vbo_exec.c +++ b/mesalib/src/mesa/vbo/vbo_exec.c @@ -100,7 +100,7 @@ void vbo_exec_invalidate_state( struct gl_context *ctx, GLuint new_state ) } if (new_state & _NEW_EVAL) - exec->eval.recalculate_maps = 1; + exec->eval.recalculate_maps = GL_TRUE; _ae_invalidate_state(ctx, new_state); } diff --git a/mesalib/src/mesa/vbo/vbo_exec_eval.c b/mesalib/src/mesa/vbo/vbo_exec_eval.c index 71155ce77..2bd1b2150 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_eval.c +++ b/mesalib/src/mesa/vbo/vbo_exec_eval.c @@ -117,7 +117,7 @@ void vbo_exec_eval_update( struct vbo_exec_context *exec ) else if (ctx->Eval.Map2Vertex3) set_active_eval2( exec, VBO_ATTRIB_POS, 3, &ctx->EvalMap.Map2Vertex3 ); - exec->eval.recalculate_maps = 0; + exec->eval.recalculate_maps = GL_FALSE; } diff --git a/mesalib/src/mesa/vbo/vbo_save.h b/mesalib/src/mesa/vbo/vbo_save.h index aa075bb31..a810bef57 100644 --- a/mesalib/src/mesa/vbo/vbo_save.h +++ b/mesalib/src/mesa/vbo/vbo_save.h @@ -63,7 +63,7 @@ struct vbo_save_copied_vtx { struct vbo_save_vertex_list { GLubyte attrsz[VBO_ATTRIB_MAX]; GLenum attrtype[VBO_ATTRIB_MAX]; - GLuint vertex_size; + GLuint vertex_size; /**< size in GLfloats */ /* Copy of the final vertex from node->vertex_store->bufferobj. * Keep this in regular (non-VBO) memory to avoid repeated diff --git a/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c index 2028d8b2c..b5f951787 100644 --- a/mesalib/src/mesa/vbo/vbo_save_api.c +++ b/mesalib/src/mesa/vbo/vbo_save_api.c @@ -41,7 +41,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * example by building a list that consists of one very long primitive * (eg Begin(Triangles), 1000 vertices, End), and calling that list * from inside a different begin/end object (Begin(Lines), CallList, - * End). + * End). * * In that case the code will have to replay the list as individual * commands through the Exec dispatch table, or fix up the copied @@ -60,7 +60,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * * The list compiler currently doesn't attempt to compile lists * containing EvalCoord or EvalPoint commands. On encountering one of - * these, compilation falls back to opcodes. + * these, compilation falls back to opcodes. * * This could be improved to fallback only when a mix of EvalCoord and * Vertex commands are issued within a single primitive. @@ -289,15 +289,15 @@ _save_reset_counters(struct gl_context *ctx) assert(save->buffer == save->buffer_ptr); if (save->vertex_size) - save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) / - save->vertex_size); + save->max_vert = (VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) / + save->vertex_size; else save->max_vert = 0; save->vert_count = 0; save->prim_count = 0; save->prim_max = VBO_SAVE_PRIM_SIZE - save->prim_store->used; - save->dangling_attr_ref = 0; + save->dangling_attr_ref = GL_FALSE; } /** @@ -410,7 +410,7 @@ _save_compile_vertex_list(struct gl_context *ctx) save->vertex_store->used += save->vertex_size * node->count; save->prim_store->used += node->prim_count; - /* Copy duplicated vertices + /* Copy duplicated vertices */ save->copied.nr = _save_copy_vertices(ctx, node, save->buffer); @@ -514,7 +514,7 @@ _save_wrap_buffers(struct gl_context *ctx) /** * Called only when buffers are wrapped as the result of filling the - * vertex_store struct. + * vertex_store struct. */ static void _save_wrap_filled_vertex(struct gl_context *ctx) @@ -603,7 +603,7 @@ _save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz) /* Do a COPY_TO_CURRENT to ensure back-copying works for the case * when the attribute already exists in the vertex and is having - * its size increased. + * its size increased. */ _save_copy_to_current(ctx); @@ -856,7 +856,7 @@ dlist_fallback(struct gl_context *ctx) * unfortunately, otherwise this primitive won't be handled * properly: */ - save->dangling_attr_ref = 1; + save->dangling_attr_ref = GL_TRUE; _save_compile_vertex_list(ctx); } @@ -1433,13 +1433,13 @@ vbo_save_EndList(struct gl_context *ctx) GLint i = save->prim_count - 1; ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; save->prim[i].end = 0; - save->prim[i].count = (save->vert_count - save->prim[i].start); + save->prim[i].count = save->vert_count - save->prim[i].start; } /* Make sure this vertex list gets replayed by the "loopback" * mechanism: */ - save->dangling_attr_ref = 1; + save->dangling_attr_ref = GL_TRUE; vbo_save_SaveFlushVertices(ctx); /* Swap out this vertex format while outside begin/end. Any color, diff --git a/pixman/configure.ac b/pixman/configure.ac index 2dd477663..8a3b62268 100644 --- a/pixman/configure.ac +++ b/pixman/configure.ac @@ -183,6 +183,7 @@ AC_SUBST(LT_VERSION_INFO) # Check for dependencies PIXMAN_CHECK_CFLAG([-Wall]) +PIXMAN_CHECK_CFLAG([-Wdeclaration-after-statement]) PIXMAN_CHECK_CFLAG([-fno-strict-aliasing]) dnl ========================================================================= @@ -355,6 +356,12 @@ int main () { : "y" (v), "K" (5) ); + /* Some versions of clang will choke on this */ + asm ("pmulhuw %1, %0\n\t" + : "+y" (w) + : "y" (v) + ); + return _mm_cvtsi64_si32 (v); }]])], have_mmx_intrinsics=yes) CFLAGS=$xserver_save_CFLAGS diff --git a/pixman/demos/scale.c b/pixman/demos/scale.c index 869ada12b..d00307e44 100644 --- a/pixman/demos/scale.c +++ b/pixman/demos/scale.c @@ -103,8 +103,8 @@ compute_extents (pixman_f_transform_t *trans, double *sx, double *sy) typedef struct { - char name [20]; - pixman_kernel_t value; + char name [20]; + int value; } named_int_t; static const named_int_t filters[] = @@ -127,7 +127,7 @@ static const named_int_t repeats[] = { "Pad", PIXMAN_REPEAT_PAD }, }; -static pixman_kernel_t +static int get_value (app_t *app, const named_int_t table[], const char *box_name) { GtkComboBox *box = GTK_COMBO_BOX (get_widget (app, box_name)); diff --git a/pixman/pixman/Makefile.win32 b/pixman/pixman/Makefile.win32 index 57ed7a5dc..7b64033bc 100644 --- a/pixman/pixman/Makefile.win32 +++ b/pixman/pixman/Makefile.win32 @@ -14,8 +14,14 @@ ifeq ($(SSE2_VAR),) SSE2_VAR=on endif +SSSE3_VAR = $(SSSE3) +ifeq ($(SSSE3_VAR),) +SSSE3_VAR=on +endif + MMX_CFLAGS = -DUSE_X86_MMX -w14710 -w14714 SSE2_CFLAGS = -DUSE_SSE2 +SSSE3_CFLAGS = -DUSE_SSSE3 # MMX compilation flags ifeq ($(MMX_VAR),on) @@ -29,10 +35,16 @@ PIXMAN_CFLAGS += $(SSE2_CFLAGS) libpixman_sources += pixman-sse2.c endif +# SSSE3 compilation flags +ifeq ($(SSSE3_VAR),on) +PIXMAN_CFLAGS += $(SSSE3_CFLAGS) +libpixman_sources += pixman-ssse3.c +endif + OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(libpixman_sources)) # targets -all: inform informMMX informSSE2 $(CFG_VAR)/$(LIBRARY).lib +all: inform informMMX informSSE2 informSSSE3 $(CFG_VAR)/$(LIBRARY).lib informMMX: ifneq ($(MMX),off) @@ -60,9 +72,22 @@ endif endif endif +informSSSE3: +ifneq ($(SSSE3),off) +ifneq ($(SSSE3),on) +ifneq ($(SSSE3),) + @echo "Invalid specified SSE option : "$(SSSE3)"." + @echo + @echo "Possible choices for SSSE3 are 'on' or 'off'" + @exit 1 +endif + @echo "Setting SSSE3 flag to default value 'on'... (use SSSE3=on or SSSE3=off)" +endif +endif + # pixman linking $(CFG_VAR)/$(LIBRARY).lib: $(OBJECTS) @$(AR) $(PIXMAN_ARFLAGS) -OUT:$@ $^ -.PHONY: all informMMX informSSE2 +.PHONY: all informMMX informSSE2 informSSSE3 diff --git a/pixman/pixman/pixman-combine32.c b/pixman/pixman/pixman-combine32.c index 3ac7576bd..450114a52 100644 --- a/pixman/pixman/pixman-combine32.c +++ b/pixman/pixman/pixman-combine32.c @@ -142,12 +142,12 @@ combine_mask (const uint32_t *src, const uint32_t *mask, int i) static void combine_clear (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { - memset (dest, 0, width * sizeof(uint32_t)); + memset (dest, 0, width * sizeof (uint32_t)); } static void @@ -155,7 +155,7 @@ combine_dst (pixman_implementation_t *imp, pixman_op_t op, uint32_t * dest, const uint32_t * src, - const uint32_t * mask, + const uint32_t * mask, int width) { return; @@ -164,9 +164,9 @@ combine_dst (pixman_implementation_t *imp, static void combine_src_u (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -189,9 +189,9 @@ combine_src_u (pixman_implementation_t *imp, static void combine_over_u (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -254,9 +254,9 @@ combine_over_u (pixman_implementation_t *imp, static void combine_over_reverse_u (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -274,9 +274,9 @@ combine_over_reverse_u (pixman_implementation_t *imp, static void combine_in_u (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -293,9 +293,9 @@ combine_in_u (pixman_implementation_t *imp, static void combine_in_reverse_u (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -313,9 +313,9 @@ combine_in_reverse_u (pixman_implementation_t *imp, static void combine_out_u (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -332,9 +332,9 @@ combine_out_u (pixman_implementation_t *imp, static void combine_out_reverse_u (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -352,9 +352,9 @@ combine_out_reverse_u (pixman_implementation_t *imp, static void combine_atop_u (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -374,9 +374,9 @@ combine_atop_u (pixman_implementation_t *imp, static void combine_atop_reverse_u (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -396,9 +396,9 @@ combine_atop_reverse_u (pixman_implementation_t *imp, static void combine_xor_u (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -418,9 +418,9 @@ combine_xor_u (pixman_implementation_t *imp, static void combine_add_u (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -437,9 +437,9 @@ combine_add_u (pixman_implementation_t *imp, static void combine_saturate_u (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -463,39 +463,66 @@ combine_saturate_u (pixman_implementation_t *imp, } } + /* * PDF blend modes: + * * The following blend modes have been taken from the PDF ISO 32000 * specification, which at this point in time is available from - * http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf - * The relevant chapters are 11.3.5 and 11.3.6. + * + * http://www.adobe.com/devnet/pdf/pdf_reference.html + * + * The specific documents of interest are the PDF spec itself: + * + * http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf + * + * chapters 11.3.5 and 11.3.6 and a later supplement for Adobe Acrobat + * 9.1 and Reader 9.1: + * + * http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/adobe_supplement_iso32000_1.pdf + * + * that clarifies the specifications for blend modes ColorDodge and + * ColorBurn. + * * The formula for computing the final pixel color given in 11.3.6 is: - * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs) - * with B() being the blend function. - * Note that OVER is a special case of this operation, using B(Cb, Cs) = Cs - * - * These blend modes should match the SVG filter draft specification, as - * it has been designed to mirror ISO 32000. Note that at the current point - * no released draft exists that shows this, as the formulas have not been - * updated yet after the release of ISO 32000. - * - * The default implementation here uses the PDF_SEPARABLE_BLEND_MODE and - * PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an - * argument. Note that this implementation operates on premultiplied colors, - * while the PDF specification does not. Therefore the code uses the formula - * Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as) + * + * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs) + * + * with B() is the blend function. When B(Cb, Cs) = Cs, this formula + * reduces to the regular OVER operator. + * + * Cs and Cb are not premultiplied, so in our implementation we instead + * use: + * + * cr = (1 – αs) × cb + (1 – αb) × cs + αb × αs × B (cb/αb, cs/αs) + * + * where cr, cs, and cb are premultiplied colors, and where the + * + * αb × αs × B(cb/αb, cs/αs) + * + * part is first arithmetically simplified under the assumption that αb + * and αs are not 0, and then updated to produce a meaningful result when + * they are. + * + * For all the blend mode operators, the alpha channel is given by + * + * αr = αs + αb + αb × αs */ /* * Multiply - * B(Dca, ad, Sca, as) = Dca.Sca + * + * ad * as * B(d / ad, s / as) + * = ad * as * d/ad * s/as + * = d * s + * */ static void combine_multiply_u (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -519,9 +546,9 @@ combine_multiply_u (pixman_implementation_t *imp, static void combine_multiply_ca (pixman_implementation_t *imp, pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, + uint32_t * dest, + const uint32_t * src, + const uint32_t * mask, int width) { int i; @@ -548,13 +575,14 @@ combine_multiply_ca (pixman_implementation_t *imp, static void \ combine_ ## name ## _u (pixman_implementation_t *imp, \ pixman_op_t op, \ - uint32_t * dest, \ - const uint32_t * src, \ - const uint32_t * mask, \ + uint32_t * dest, \ + const uint32_t * src, \ + const uint32_t * mask, \ int width) \ { \ int i; \ - for (i = 0; i < width; ++i) { \ + for (i = 0; i < width; ++i) \ + { \ uint32_t s = combine_mask (src, mask, i); \ uint32_t d = *(dest + i); \ uint8_t sa = ALPHA_8 (s); \ @@ -577,13 +605,14 @@ combine_multiply_ca (pixman_implementation_t *imp, static void \ combine_ ## name ## _ca (pixman_implementation_t *imp, \ pixman_op_t op, \ - uint32_t * dest, \ - const uint32_t * src, \ - const uint32_t * mask, \ - int width) \ + uint32_t * dest, \ + const uint32_t * src, \ + const uint32_t * mask, \ + int width) \ { \ int i; \ - for (i = 0; i < width; ++i) { \ + for (i = 0; i < width; ++i) \ + { \ uint32_t m = *(mask + i); \ uint32_t s = *(src + i); \ uint32_t d = *(dest + i); \ @@ -608,49 +637,69 @@ combine_multiply_ca (pixman_implementation_t *imp, /* * Screen - * B(Dca, ad, Sca, as) = Dca.sa + Sca.da - Dca.Sca + * + * ad * as * B(d/ad, s/as) + * = ad * as * (d/ad + s/as - s/as * d/ad) + * = ad * s + as * d - s * d */ static inline uint32_t -blend_screen (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) +blend_screen (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) { - return DIV_ONE_UN8 (sca * da + dca * sa - sca * dca); + return DIV_ONE_UN8 (s * ad + d * as - s * d); } PDF_SEPARABLE_BLEND_MODE (screen) /* * Overlay - * B(Dca, Da, Sca, Sa) = - * if 2.Dca < Da - * 2.Sca.Dca - * otherwise - * Sa.Da - 2.(Da - Dca).(Sa - Sca) + * + * ad * as * B(d/ad, s/as) + * = ad * as * Hardlight (s, d) + * = if (d / ad < 0.5) + * as * ad * Multiply (s/as, 2 * d/ad) + * else + * as * ad * Screen (s/as, 2 * d / ad - 1) + * = if (d < 0.5 * ad) + * as * ad * s/as * 2 * d /ad + * else + * as * ad * (s/as + 2 * d / ad - 1 - s / as * (2 * d / ad - 1)) + * = if (2 * d < ad) + * 2 * s * d + * else + * ad * s + 2 * as * d - as * ad - ad * s * (2 * d / ad - 1) + * = if (2 * d < ad) + * 2 * s * d + * else + * as * ad - 2 * (ad - d) * (as - s) */ static inline uint32_t -blend_overlay (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) +blend_overlay (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) { - uint32_t rca; + uint32_t r; - if (2 * dca < da) - rca = 2 * sca * dca; + if (2 * d < ad) + r = 2 * s * d; else - rca = sa * da - 2 * (da - dca) * (sa - sca); - return DIV_ONE_UN8 (rca); + r = as * ad - 2 * (ad - d) * (as - s); + + return DIV_ONE_UN8 (r); } PDF_SEPARABLE_BLEND_MODE (overlay) /* * Darken - * B(Dca, Da, Sca, Sa) = min (Sca.Da, Dca.Sa) + * + * ad * as * B(d/ad, s/as) + * = ad * as * MIN(d/ad, s/as) + * = MIN (as * d, ad * s) */ static inline uint32_t -blend_darken (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) +blend_darken (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) { - uint32_t s, d; + s = ad * s; + d = as * d; - s = sca * da; - d = dca * sa; return DIV_ONE_UN8 (s > d ? d : s); } @@ -658,15 +707,17 @@ PDF_SEPARABLE_BLEND_MODE (darken) /* * Lighten - * B(Dca, Da, Sca, Sa) = max (Sca.Da, Dca.Sa) + * + * ad * as * B(d/ad, s/as) + * = ad * as * MAX(d/ad, s/as) + * = MAX (as * d, ad * s) */ static inline uint32_t -blend_lighten (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) +blend_lighten (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) { - uint32_t s, d; - - s = sca * da; - d = dca * sa; + s = ad * s; + d = as * d; + return DIV_ONE_UN8 (s > d ? s : d); } @@ -674,152 +725,197 @@ PDF_SEPARABLE_BLEND_MODE (lighten) /* * Color dodge - * B(Dca, Da, Sca, Sa) = - * if Dca == 0 - * 0 - * if Sca == Sa - * Sa.Da - * otherwise - * Sa.Da. min (1, Dca / Da / (1 - Sca/Sa)) + * + * ad * as * B(d/ad, s/as) + * = if d/ad = 0 + * ad * as * 0 + * else if (d/ad >= (1 - s/as) + * ad * as * 1 + * else + * ad * as * ((d/ad) / (1 - s/as)) + * = if d = 0 + * 0 + * elif as * d >= ad * (as - s) + * ad * as + * else + * as * (as * d / (as - s)) + * */ static inline uint32_t -blend_color_dodge (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) -{ - if (sca >= sa) - { - return dca == 0 ? 0 : DIV_ONE_UN8 (sa * da); - } +blend_color_dodge (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) +{ + if (d == 0) + return 0; + else if (as * d >= ad * (as - s)) + return DIV_ONE_UN8 (as * ad); + else if (as - s == 0) + return DIV_ONE_UN8 (as * ad); else - { - uint32_t rca = dca * sa / (sa - sca); - return DIV_ONE_UN8 (sa * MIN (rca, da)); - } + return DIV_ONE_UN8 (as * ((d * as) / ((as - s)))); } PDF_SEPARABLE_BLEND_MODE (color_dodge) /* * Color burn - * B(Dca, Da, Sca, Sa) = - * if Dca == Da - * Sa.Da - * if Sca == 0 - * 0 - * otherwise - * Sa.Da.(1 - min (1, (1 - Dca/Da).Sa / Sca)) + * + * We modify the first clause "if d = 1" to "if d >= 1" since with + * premultiplied colors d > 1 can actually happen. + * + * ad * as * B(d/ad, s/as) + * = if d/ad >= 1 + * ad * as * 1 + * elif (1 - d/ad) >= s/as + * ad * as * 0 + * else + * ad * as * (1 - ((1 - d/ad) / (s/as))) + * = if d >= ad + * ad * as + * elif as * ad - as * d >= ad * s + * 0 + * else + * ad * as - as * as * (ad - d) / s */ static inline uint32_t -blend_color_burn (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) -{ - if (sca == 0) - { - return dca < da ? 0 : DIV_ONE_UN8 (sa * da); - } +blend_color_burn (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) +{ + if (d >= ad) + return DIV_ONE_UN8 (ad * as); + else if (as * ad - as * d >= ad * s) + return 0; + else if (s == 0) + return 0; else - { - uint32_t rca = (da - dca) * sa / sca; - return DIV_ONE_UN8 (sa * (MAX (rca, da) - rca)); - } + return DIV_ONE_UN8 (ad * as - (as * as * (ad - d)) / s); } PDF_SEPARABLE_BLEND_MODE (color_burn) /* * Hard light - * B(Dca, Da, Sca, Sa) = - * if 2.Sca < Sa - * 2.Sca.Dca - * otherwise - * Sa.Da - 2.(Da - Dca).(Sa - Sca) + * + * ad * as * B(d/ad, s/as) + * = if (s/as <= 0.5) + * ad * as * Multiply (d/ad, 2 * s/as) + * else + * ad * as * Screen (d/ad, 2 * s/as - 1) + * = if 2 * s <= as + * ad * as * d/ad * 2 * s / as + * else + * ad * as * (d/ad + (2 * s/as - 1) + d/ad * (2 * s/as - 1)) + * = if 2 * s <= as + * 2 * s * d + * else + * as * ad - 2 * (ad - d) * (as - s) */ static inline uint32_t -blend_hard_light (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) +blend_hard_light (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) { - if (2 * sca < sa) - return DIV_ONE_UN8 (2 * sca * dca); + if (2 * s < as) + return DIV_ONE_UN8 (2 * s * d); else - return DIV_ONE_UN8 (sa * da - 2 * (da - dca) * (sa - sca)); + return DIV_ONE_UN8 (as * ad - 2 * (ad - d) * (as - s)); } PDF_SEPARABLE_BLEND_MODE (hard_light) /* * Soft light - * B(Dca, Da, Sca, Sa) = - * if (2.Sca <= Sa) - * Dca.(Sa - (1 - Dca/Da).(2.Sca - Sa)) - * otherwise if Dca.4 <= Da - * Dca.(Sa + (2.Sca - Sa).((16.Dca/Da - 12).Dca/Da + 3) - * otherwise - * (Dca.Sa + (SQRT (Dca/Da).Da - Dca).(2.Sca - Sa)) + * + * ad * as * B(d/ad, s/as) + * = if (s/as <= 0.5) + * ad * as * (d/ad - (1 - 2 * s/as) * d/ad * (1 - d/ad)) + * else if (d/ad <= 0.25) + * ad * as * (d/ad + (2 * s/as - 1) * ((((16 * d/ad - 12) * d/ad + 4) * d/ad) - d/ad)) + * else + * ad * as * (d/ad + (2 * s/as - 1) * sqrt (d/ad)) + * = if (2 * s <= as) + * d * as - d * (ad - d) * (as - 2 * s) / ad; + * else if (4 * d <= ad) + * (2 * s - as) * d * ((16 * d / ad - 12) * d / ad + 3); + * else + * d * as + (sqrt (d * ad) - d) * (2 * s - as); */ static inline uint32_t -blend_soft_light (uint32_t dca_org, - uint32_t da_org, - uint32_t sca_org, - uint32_t sa_org) -{ - double dca = dca_org * (1.0 / MASK); - double da = da_org * (1.0 / MASK); - double sca = sca_org * (1.0 / MASK); - double sa = sa_org * (1.0 / MASK); - double rca; - - if (2 * sca < sa) +blend_soft_light (uint32_t d_org, + uint32_t ad_org, + uint32_t s_org, + uint32_t as_org) +{ + double d = d_org * (1.0 / MASK); + double ad = ad_org * (1.0 / MASK); + double s = s_org * (1.0 / MASK); + double as = as_org * (1.0 / MASK); + double r; + + if (2 * s < as) { - if (da == 0) - rca = dca * sa; + if (ad == 0) + r = d * as; else - rca = dca * sa - dca * (da - dca) * (sa - 2 * sca) / da; + r = d * as - d * (ad - d) * (as - 2 * s) / ad; } - else if (da == 0) + else if (ad == 0) { - rca = 0; + r = 0; } - else if (4 * dca <= da) + else if (4 * d <= ad) { - rca = dca * sa + - (2 * sca - sa) * dca * ((16 * dca / da - 12) * dca / da + 3); + r = d * as + + (2 * s - as) * d * ((16 * d / ad - 12) * d / ad + 3); } else { - rca = dca * sa + (sqrt (dca * da) - dca) * (2 * sca - sa); + r = d * as + (sqrt (d * ad) - d) * (2 * s - as); } - return rca * MASK + 0.5; + return r * MASK + 0.5; } PDF_SEPARABLE_BLEND_MODE (soft_light) /* * Difference - * B(Dca, Da, Sca, Sa) = abs (Dca.Sa - Sca.Da) + * + * ad * as * B(s/as, d/ad) + * = ad * as * abs (s/as - d/ad) + * = if (s/as <= d/ad) + * ad * as * (d/ad - s/as) + * else + * ad * as * (s/as - d/ad) + * = if (ad * s <= as * d) + * as * d - ad * s + * else + * ad * s - as * d */ static inline uint32_t -blend_difference (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) +blend_difference (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) { - uint32_t dcasa = dca * sa; - uint32_t scada = sca * da; + uint32_t das = d * as; + uint32_t sad = s * ad; - if (scada < dcasa) - return DIV_ONE_UN8 (dcasa - scada); + if (sad < das) + return DIV_ONE_UN8 (das - sad); else - return DIV_ONE_UN8 (scada - dcasa); + return DIV_ONE_UN8 (sad - das); } PDF_SEPARABLE_BLEND_MODE (difference) /* * Exclusion - * B(Dca, Da, Sca, Sa) = (Sca.Da + Dca.Sa - 2.Sca.Dca) + * + * ad * as * B(s/as, d/ad) + * = ad * as * (d/ad + s/as - 2 * d/ad * s/as) + * = as * d + ad * s - 2 * s * d */ /* This can be made faster by writing it directly and not using * PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */ static inline uint32_t -blend_exclusion (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) +blend_exclusion (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) { - return DIV_ONE_UN8 (sca * da + dca * sa - 2 * dca * sca); + return DIV_ONE_UN8 (s * ad + d * as - 2 * d * s); } PDF_SEPARABLE_BLEND_MODE (exclusion) @@ -834,103 +930,70 @@ PDF_SEPARABLE_BLEND_MODE (exclusion) * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue * * clip_color (C): - * l = LUM (C) - * min = Cmin - * max = Cmax - * if n < 0.0 - * C = l + ( ( ( C – l ) × l ) ⁄ ( l – min ) ) - * if x > 1.0 - * C = l + ( ( ( C – l ) × ( 1 – l ) ) ⁄ ( max – l ) ) - * return C + * l = LUM (C) + * min = Cmin + * max = Cmax + * if n < 0.0 + * C = l + (((C – l) × l) ⁄ (l – min)) + * if x > 1.0 + * C = l + (((C – l) × (1 – l) ) ⁄ (max – l)) + * return C * * set_lum (C, l): - * d = l – LUM (C) - * C += d - * return clip_color (C) + * d = l – LUM (C) + * C += d + * return clip_color (C) * * SAT (C) = CH_MAX (C) - CH_MIN (C) * * set_sat (C, s): - * if Cmax > Cmin - * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) ) - * Cmax = s - * else - * Cmid = Cmax = 0.0 - * Cmin = 0.0 - * return C + * if Cmax > Cmin + * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) ) + * Cmax = s + * else + * Cmid = Cmax = 0.0 + * Cmin = 0.0 + * return C */ /* For premultiplied colors, we need to know what happens when C is * multiplied by a real number. LUM and SAT are linear: * - * LUM (r × C) = r × LUM (C) SAT (r * C) = r * SAT (C) + * LUM (r × C) = r × LUM (C) SAT (r * C) = r * SAT (C) * * If we extend clip_color with an extra argument a and change * - * if x >= 1.0 + * if x >= 1.0 * * into * - * if x >= a + * if x >= a * * then clip_color is also linear: * - * r * clip_color (C, a) = clip_color (r_c, ra); + * r * clip_color (C, a) = clip_color (r * C, r * a); * * for positive r. * * Similarly, we can extend set_lum with an extra argument that is just passed * on to clip_color: * - * r * set_lum ( C, l, a) + * r * set_lum (C, l, a) * - * = r × clip_color ( C + l - LUM (C), a) + * = r × clip_color (C + l - LUM (C), a) * - * = clip_color ( r * C + r × l - r * LUM (C), r * a) + * = clip_color (r * C + r × l - r * LUM (C), r * a) * - * = set_lum ( r * C, r * l, r * a) + * = set_lum (r * C, r * l, r * a) * * Finally, set_sat: * - * r * set_sat (C, s) = set_sat (x * C, r * s) + * r * set_sat (C, s) = set_sat (x * C, r * s) * * The above holds for all non-zero x, because the x'es in the fraction for * C_mid cancel out. Specifically, it holds for x = r: * - * r * set_sat (C, s) = set_sat (r_c, rs) - * - */ - -/* So, for the non-separable PDF blend modes, we have (using s, d for - * non-premultiplied colors, and S, D for premultiplied: - * - * Color: - * - * a_s * a_d * B(s, d) - * = a_s * a_d * set_lum (S/a_s, LUM (D/a_d), 1) - * = set_lum (S * a_d, a_s * LUM (D), a_s * a_d) - * - * - * Luminosity: - * - * a_s * a_d * B(s, d) - * = a_s * a_d * set_lum (D/a_d, LUM(S/a_s), 1) - * = set_lum (a_s * D, a_d * LUM(S), a_s * a_d) - * - * - * Saturation: - * - * a_s * a_d * B(s, d) - * = a_s * a_d * set_lum (set_sat (D/a_d, SAT (S/a_s)), LUM (D/a_d), 1) - * = set_lum (a_s * a_d * set_sat (D/a_d, SAT (S/a_s)), - * a_s * LUM (D), a_s * a_d) - * = set_lum (set_sat (a_s * D, a_d * SAT (S), a_s * LUM (D), a_s * a_d)) - * - * Hue: - * - * a_s * a_d * B(s, d) - * = a_s * a_d * set_lum (set_sat (S/a_s, SAT (D/a_d)), LUM (D/a_d), 1) - * = set_lum (set_sat (a_d * S, a_s * SAT (D)), a_s * LUM (D), a_s * a_d) + * r * set_sat (C, s) = set_sat (r * C, r * s) * */ @@ -942,11 +1005,11 @@ PDF_SEPARABLE_BLEND_MODE (exclusion) #define PDF_NON_SEPARABLE_BLEND_MODE(name) \ static void \ combine_ ## name ## _u (pixman_implementation_t *imp, \ - pixman_op_t op, \ - uint32_t *dest, \ - const uint32_t *src, \ - const uint32_t *mask, \ - int width) \ + pixman_op_t op, \ + uint32_t * dest, \ + const uint32_t * src, \ + const uint32_t * mask, \ + int width) \ { \ int i; \ for (i = 0; i < width; ++i) \ @@ -958,7 +1021,7 @@ PDF_SEPARABLE_BLEND_MODE (exclusion) uint8_t da = ALPHA_8 (d); \ uint8_t ida = ~da; \ uint32_t result; \ - uint32_t sc[3], dc[3], c[3]; \ + uint32_t sc[3], dc[3], c[3]; \ \ result = d; \ UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (result, isa, s, ida); \ @@ -1104,80 +1167,94 @@ set_sat (uint32_t dest[3], uint32_t src[3], uint32_t sat) } } -/* - * Hue: - * B(Cb, Cs) = set_lum (set_sat (Cs, SAT (Cb)), LUM (Cb)) +/* Hue: + * + * as * ad * B(s/as, d/as) + * = as * ad * set_lum (set_sat (s/as, SAT (d/ad)), LUM (d/ad), 1) + * = set_lum (set_sat (ad * s, as * SAT (d)), as * LUM (d), as * ad) + * */ static inline void -blend_hsl_hue (uint32_t c[3], - uint32_t dc[3], - uint32_t da, - uint32_t sc[3], - uint32_t sa) +blend_hsl_hue (uint32_t r[3], + uint32_t d[3], + uint32_t ad, + uint32_t s[3], + uint32_t as) { - c[0] = sc[0] * da; - c[1] = sc[1] * da; - c[2] = sc[2] * da; - set_sat (c, c, SAT (dc) * sa); - set_lum (c, c, sa * da, LUM (dc) * sa); + r[0] = s[0] * ad; + r[1] = s[1] * ad; + r[2] = s[2] * ad; + set_sat (r, r, SAT (d) * as); + set_lum (r, r, as * ad, LUM (d) * as); } PDF_NON_SEPARABLE_BLEND_MODE (hsl_hue) -/* - * Saturation: - * B(Cb, Cs) = set_lum (set_sat (Cb, SAT (Cs)), LUM (Cb)) +/* + * Saturation + * + * as * ad * B(s/as, d/ad) + * = as * ad * set_lum (set_sat (d/ad, SAT (s/as)), LUM (d/ad), 1) + * = set_lum (as * ad * set_sat (d/ad, SAT (s/as)), + * as * LUM (d), as * ad) + * = set_lum (set_sat (as * d, ad * SAT (s), as * LUM (d), as * ad)) */ static inline void -blend_hsl_saturation (uint32_t c[3], - uint32_t dc[3], - uint32_t da, - uint32_t sc[3], - uint32_t sa) +blend_hsl_saturation (uint32_t r[3], + uint32_t d[3], + uint32_t ad, + uint32_t s[3], + uint32_t as) { - c[0] = dc[0] * sa; - c[1] = dc[1] * sa; - c[2] = dc[2] * sa; - set_sat (c, c, SAT (sc) * da); - set_lum (c, c, sa * da, LUM (dc) * sa); + r[0] = d[0] * as; + r[1] = d[1] * as; + r[2] = d[2] * as; + set_sat (r, r, SAT (s) * ad); + set_lum (r, r, as * ad, LUM (d) * as); } PDF_NON_SEPARABLE_BLEND_MODE (hsl_saturation) -/* - * Color: - * B(Cb, Cs) = set_lum (Cs, LUM (Cb)) +/* + * Color + * + * as * ad * B(s/as, d/as) + * = as * ad * set_lum (s/as, LUM (d/ad), 1) + * = set_lum (s * ad, as * LUM (d), as * ad) */ static inline void -blend_hsl_color (uint32_t c[3], - uint32_t dc[3], - uint32_t da, - uint32_t sc[3], - uint32_t sa) +blend_hsl_color (uint32_t r[3], + uint32_t d[3], + uint32_t ad, + uint32_t s[3], + uint32_t as) { - c[0] = sc[0] * da; - c[1] = sc[1] * da; - c[2] = sc[2] * da; - set_lum (c, c, sa * da, LUM (dc) * sa); + r[0] = s[0] * ad; + r[1] = s[1] * ad; + r[2] = s[2] * ad; + set_lum (r, r, as * ad, LUM (d) * as); } PDF_NON_SEPARABLE_BLEND_MODE (hsl_color) /* - * Luminosity: - * B(Cb, Cs) = set_lum (Cb, LUM (Cs)) + * Luminosity + * + * as * ad * B(s/as, d/ad) + * = as * ad * set_lum (d/ad, LUM (s/as), 1) + * = set_lum (as * d, ad * LUM (s), as * ad) */ static inline void -blend_hsl_luminosity (uint32_t c[3], - uint32_t dc[3], - uint32_t da, - uint32_t sc[3], - uint32_t sa) +blend_hsl_luminosity (uint32_t r[3], + uint32_t d[3], + uint32_t ad, + uint32_t s[3], + uint32_t as) { - c[0] = dc[0] * sa; - c[1] = dc[1] * sa; - c[2] = dc[2] * sa; - set_lum (c, c, sa * da, LUM (sc) * da); + r[0] = d[0] * as; + r[1] = d[1] * as; + r[2] = d[2] * as; + set_lum (r, r, as * ad, LUM (s) * ad); } PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity) @@ -1194,7 +1271,7 @@ PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity) * come from each of the four areas of the picture -- areas covered by neither * A nor B, areas covered only by A, areas covered only by B and finally * areas covered by both A and B. - * + * * Disjoint Conjoint * Fa Fb Fa Fb * (0,0,0,0) 0 0 0 0 diff --git a/pixman/pixman/pixman-mmx.c b/pixman/pixman/pixman-mmx.c index a0f59ef11..f9a92ce09 100644 --- a/pixman/pixman/pixman-mmx.c +++ b/pixman/pixman/pixman-mmx.c @@ -3579,7 +3579,6 @@ do { \ __m64 b_lo = _mm_mullo_pi16 (_mm_unpacklo_pi8 (b, mm_zero), mm_wb); \ __m64 hi = _mm_add_pi16 (t_hi, b_hi); \ __m64 lo = _mm_add_pi16 (t_lo, b_lo); \ - vx += unit_x; \ /* calculate horizontal weights */ \ __m64 mm_wh = _mm_add_pi16 (mm_addc7, _mm_xor_si64 (mm_xorc7, \ _mm_srli_pi16 (mm_x, \ @@ -3587,6 +3586,7 @@ do { \ /* horizontal interpolation */ \ __m64 p = _mm_unpacklo_pi16 (lo, hi); \ __m64 q = _mm_unpackhi_pi16 (lo, hi); \ + vx += unit_x; \ lo = _mm_madd_pi16 (p, mm_wh); \ hi = _mm_madd_pi16 (q, mm_wh); \ mm_x = _mm_add_pi16 (mm_x, mm_ux); \ diff --git a/pixman/pixman/pixman-sse2.c b/pixman/pixman/pixman-sse2.c index 42c720938..a6e780815 100644 --- a/pixman/pixman/pixman-sse2.c +++ b/pixman/pixman/pixman-sse2.c @@ -5626,10 +5626,10 @@ do { \ #define BILINEAR_INTERPOLATE_ONE_PIXEL_HELPER(pix, phase) \ do { \ __m128i xmm_wh, xmm_a, xmm_b; \ - (void)xmm_ux4; /* suppress warning: unused variable 'xmm_ux4' */ \ /* fetch 2x2 pixel block into sse2 registers */ \ __m128i tltr = _mm_loadl_epi64 ((__m128i *)&src_top[vx >> 16]); \ __m128i blbr = _mm_loadl_epi64 ((__m128i *)&src_bottom[vx >> 16]); \ + (void)xmm_ux4; /* suppress warning: unused variable 'xmm_ux4' */ \ vx += unit_x; \ /* vertical interpolation */ \ xmm_a = _mm_mullo_epi16 (_mm_unpacklo_epi8 (tltr, xmm_zero), xmm_wt); \ @@ -5750,6 +5750,66 @@ FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_8888_normal_SRC, uint32_t, uint32_t, uint32_t, NORMAL, FLAG_NONE) +static force_inline void +scaled_bilinear_scanline_sse2_x888_8888_SRC (uint32_t * dst, + const uint32_t * mask, + const uint32_t * src_top, + const uint32_t * src_bottom, + int32_t w, + int wt, + int wb, + pixman_fixed_t vx_, + pixman_fixed_t unit_x_, + pixman_fixed_t max_vx, + pixman_bool_t zero_src) +{ + intptr_t vx = vx_; + intptr_t unit_x = unit_x_; + BILINEAR_DECLARE_VARIABLES; + uint32_t pix1, pix2; + + while (w && ((uintptr_t)dst & 15)) + { + BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); + *dst++ = pix1 | 0xFF000000; + w--; + } + + while ((w -= 4) >= 0) { + __m128i xmm_src; + BILINEAR_INTERPOLATE_FOUR_PIXELS (xmm_src); + _mm_store_si128 ((__m128i *)dst, _mm_or_si128 (xmm_src, mask_ff000000)); + dst += 4; + } + + if (w & 2) + { + BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); + BILINEAR_INTERPOLATE_ONE_PIXEL (pix2); + *dst++ = pix1 | 0xFF000000; + *dst++ = pix2 | 0xFF000000; + } + + if (w & 1) + { + BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); + *dst = pix1 | 0xFF000000; + } +} + +FAST_BILINEAR_MAINLOOP_COMMON (sse2_x888_8888_cover_SRC, + scaled_bilinear_scanline_sse2_x888_8888_SRC, + uint32_t, uint32_t, uint32_t, + COVER, FLAG_NONE) +FAST_BILINEAR_MAINLOOP_COMMON (sse2_x888_8888_pad_SRC, + scaled_bilinear_scanline_sse2_x888_8888_SRC, + uint32_t, uint32_t, uint32_t, + PAD, FLAG_NONE) +FAST_BILINEAR_MAINLOOP_COMMON (sse2_x888_8888_normal_SRC, + scaled_bilinear_scanline_sse2_x888_8888_SRC, + uint32_t, uint32_t, uint32_t, + NORMAL, FLAG_NONE) + static force_inline void scaled_bilinear_scanline_sse2_8888_8888_OVER (uint32_t * dst, const uint32_t * mask, @@ -6247,6 +6307,13 @@ static const pixman_fast_path_t sse2_fast_paths[] = SIMPLE_BILINEAR_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, sse2_8888_8888), SIMPLE_BILINEAR_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, sse2_8888_8888), + SIMPLE_BILINEAR_FAST_PATH_COVER (SRC, x8r8g8b8, a8r8g8b8, sse2_x888_8888), + SIMPLE_BILINEAR_FAST_PATH_COVER (SRC, x8b8g8r8, a8b8g8r8, sse2_x888_8888), + SIMPLE_BILINEAR_FAST_PATH_PAD (SRC, x8r8g8b8, a8r8g8b8, sse2_x888_8888), + SIMPLE_BILINEAR_FAST_PATH_PAD (SRC, x8b8g8r8, a8b8g8r8, sse2_x888_8888), + SIMPLE_BILINEAR_FAST_PATH_NORMAL (SRC, x8r8g8b8, a8r8g8b8, sse2_x888_8888), + SIMPLE_BILINEAR_FAST_PATH_NORMAL (SRC, x8b8g8r8, a8b8g8r8, sse2_x888_8888), + SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_8888), SIMPLE_BILINEAR_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_8888), SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_8888), diff --git a/pixman/test/Makefile.win32 b/pixman/test/Makefile.win32 index b6254a3cf..6cfb4a780 100644 --- a/pixman/test/Makefile.win32 +++ b/pixman/test/Makefile.win32 @@ -11,12 +11,12 @@ TEST_LDADD = \ libutils_OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(libutils_sources)) -SOURCES = $(patsubst %, %.c, $(TESTPROGRAMS) $(BENCHMARKS)) +SOURCES = $(patsubst %, %.c, $(TESTPROGRAMS) $(OTHERPROGRAMS)) OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(SOURCES)) TESTS = $(patsubst %, $(CFG_VAR)/%.exe, $(TESTPROGRAMS)) -BENCHS = $(patsubst %, $(CFG_VAR)/%.exe, $(BENCHMARKS)) +OTHERS = $(patsubst %, $(CFG_VAR)/%.exe, $(OTHERPROGRAMS)) -all: pixman inform $(TESTS) $(BENCHS) +all: pixman inform $(TESTS) $(OTHERS) check: pixman inform $(TESTS) @failures=0 ; \ diff --git a/pixman/test/blitters-test.c b/pixman/test/blitters-test.c index 920cbbbd7..ea03f475d 100644 --- a/pixman/test/blitters-test.c +++ b/pixman/test/blitters-test.c @@ -394,6 +394,6 @@ main (int argc, const char *argv[]) } return fuzzer_test_main("blitters", 2000000, - 0xAC8FDA98, + 0xE0A07495, test_composite, argc, argv); } diff --git a/pixman/test/thread-test.c b/pixman/test/thread-test.c index f24c31d06..fa2193302 100644 --- a/pixman/test/thread-test.c +++ b/pixman/test/thread-test.c @@ -18,6 +18,7 @@ typedef struct { int thread_no; uint32_t *dst_buf; + prng_t prng_state; } info_t; static const pixman_op_t operators[] = @@ -90,7 +91,7 @@ static const pixman_format_code_t formats[] = #define N_ROUNDS 8192 #define RAND_ELT(arr) \ - arr[prng_rand() % ARRAY_LENGTH (arr)] + arr[prng_rand_r(&info->prng_state) % ARRAY_LENGTH (arr)] #define DEST_WIDTH (7) @@ -103,15 +104,17 @@ thread (void *data) pixman_image_t *dst_img, *src_img; int i; - prng_srand (info->thread_no); + prng_srand_r (&info->prng_state, info->thread_no); for (i = 0; i < N_ROUNDS; ++i) { pixman_op_t op; int rand1, rand2; - prng_randmemset (info->dst_buf, DEST_WIDTH * sizeof (uint32_t), 0); - prng_randmemset (src_buf, sizeof (src_buf), 0); + prng_randmemset_r (&info->prng_state, info->dst_buf, + DEST_WIDTH * sizeof (uint32_t), 0); + prng_randmemset_r (&info->prng_state, src_buf, + sizeof (src_buf), 0); src_img = pixman_image_create_bits ( RAND_ELT (formats), 4, 4, src_buf, 16); @@ -122,8 +125,8 @@ thread (void *data) image_endian_swap (src_img); image_endian_swap (dst_img); - rand2 = prng_rand() % 4; - rand1 = prng_rand() % 4; + rand2 = prng_rand_r (&info->prng_state) % 4; + rand1 = prng_rand_r (&info->prng_state) % 4; op = RAND_ELT (operators); pixman_image_composite32 ( @@ -181,7 +184,7 @@ main (void) crc32 = compute_crc32 (0, crc32s, sizeof crc32s); -#define EXPECTED 0xFD497D8D +#define EXPECTED 0xE299B18E if (crc32 != EXPECTED) { diff --git a/pixman/test/utils.h b/pixman/test/utils.h index 28b7193ed..ebb14d9e4 100644 --- a/pixman/test/utils.h +++ b/pixman/test/utils.h @@ -6,6 +6,11 @@ #include "pixman-private.h" /* For 'inline' definition */ #include "utils-prng.h" +#if defined(_MSC_VER) +#define snprintf _snprintf +#define strcasecmp _stricmp +#endif + #define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0]))) /* A primitive pseudorandom number generator, diff --git a/xkbcomp/compat.c b/xkbcomp/compat.c index 2b0014244..f4d82a6de 100644 --- a/xkbcomp/compat.c +++ b/xkbcomp/compat.c @@ -274,7 +274,7 @@ AddGroupCompat(CompatInfo * info, unsigned group, GroupCompatInfo * newGC) { return True; } - if (((gc->fileID == newGC->fileID) && (warningLevel > 0)) + if (((gc->defined && gc->fileID == newGC->fileID) && (warningLevel > 0)) || (warningLevel > 9)) { WARN1("Compat map for group %d redefined\n", group + 1); diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 3df579a00..67ef3c24a 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -1035,12 +1035,14 @@ AM_CONDITIONAL(SCREENSAVER, [test "x$SCREENSAVER" = xyes]) if test "x$SCREENSAVER" = xyes; then AC_DEFINE(SCREENSAVER, 1, [Support MIT-SCREEN-SAVER extension]) REQUIRED_MODULES="$REQUIRED_MODULES $SCRNSAVERPROTO" + SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $SCRNSAVERPROTO" fi AM_CONDITIONAL(RES, [test "x$RES" = xyes]) if test "x$RES" = xyes; then AC_DEFINE(RES, 1, [Support X resource extension]) REQUIRED_MODULES="$REQUIRED_MODULES $RESOURCEPROTO" + SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $RESOURCEPROTO" fi # The XRes extension may support client ID tracking only if it has @@ -1184,6 +1186,7 @@ AM_CONDITIONAL(XF86BIGFONT, [test "x$XF86BIGFONT" = xyes]) if test "x$XF86BIGFONT" = xyes; then AC_DEFINE(XF86BIGFONT, 1, [Support XF86 Big font extension]) REQUIRED_MODULES="$REQUIRED_MODULES $BIGFONTPROTO" + SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $BIGFONTPROTO" fi AM_CONDITIONAL(DPMSExtension, [test "x$DPMSExtension" = xyes]) diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c index 086601a69..7a1b1c3c6 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -4142,6 +4142,9 @@ DeliverOneGrabbedEvent(InternalEvent *event, DeviceIntPtr dev, GrabPtr grab = grabinfo->grab; Mask filter; + if (grab->grabtype != level) + return 0; + switch (level) { case XI2: rc = EventToXI2(event, &xE); @@ -4253,22 +4256,17 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, sendCore = (IsMaster(thisDev) && thisDev->coreEvents); /* try core event */ - if (sendCore && grab->grabtype == CORE) { - deliveries = DeliverOneGrabbedEvent(event, thisDev, CORE); - } - - if (!deliveries) { - deliveries = DeliverOneGrabbedEvent(event, thisDev, XI2); - } - - if (!deliveries) { - deliveries = DeliverOneGrabbedEvent(event, thisDev, XI); - } + if ((sendCore && grab->grabtype == CORE) || grab->grabtype != CORE) + deliveries = DeliverOneGrabbedEvent(event, thisDev, grab->grabtype); if (deliveries && (event->any.type == ET_Motion)) thisDev->valuator->motionHintWindow = grab->window; } - if (deliveries && !deactivateGrab && event->any.type != ET_Motion) { + if (deliveries && !deactivateGrab && + (event->any.type == ET_KeyPress || + event->any.type == ET_KeyRelease || + event->any.type == ET_ButtonPress || + event->any.type == ET_ButtonRelease)) { switch (grabinfo->sync.state) { case FREEZE_BOTH_NEXT_EVENT: dev = GetPairedDevice(thisDev); diff --git a/xorg-server/dix/inpututils.c b/xorg-server/dix/inpututils.c index 9e38e1742..a10a7c761 100644 --- a/xorg-server/dix/inpututils.c +++ b/xorg-server/dix/inpututils.c @@ -960,8 +960,15 @@ XI2Mask * xi2mask_new_with_size(size_t nmasks, size_t size) { int i; + int alloc_size; + unsigned char *cursor; + XI2Mask *mask; - XI2Mask *mask = calloc(1, sizeof(*mask)); + alloc_size = sizeof(struct _XI2Mask) + + nmasks * sizeof(unsigned char *) + + nmasks * size; + + mask = calloc(1, alloc_size); if (!mask) return NULL; @@ -969,20 +976,14 @@ xi2mask_new_with_size(size_t nmasks, size_t size) mask->nmasks = nmasks; mask->mask_size = size; - mask->masks = calloc(mask->nmasks, sizeof(*mask->masks)); - if (!mask->masks) - goto unwind; + mask->masks = (unsigned char **)(mask + 1); + cursor = (unsigned char *)(mask + 1) + nmasks * sizeof(unsigned char *); - for (i = 0; i < mask->nmasks; i++) { - mask->masks[i] = calloc(1, mask->mask_size); - if (!mask->masks[i]) - goto unwind; + for (i = 0; i < nmasks; i++) { + mask->masks[i] = cursor; + cursor += size; } return mask; - - unwind: - xi2mask_free(&mask); - return NULL; } /** @@ -1003,14 +1004,9 @@ xi2mask_new(void) void xi2mask_free(XI2Mask **mask) { - int i; - if (!(*mask)) return; - for (i = 0; (*mask)->masks && i < (*mask)->nmasks; i++) - free((*mask)->masks[i]); - free((*mask)->masks); free((*mask)); *mask = NULL; } diff --git a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c index 13df60a5b..e2b33db03 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c @@ -343,7 +343,7 @@ ephyrDRIClipNotify(WindowPtr a_win, int a_x, int a_y) free(rects); rects = NULL; - EPHYR_LOG("leave. is_ok:%d\n", is_ok); + EPHYR_LOG("leave.\n"); /*do cleanup here */ } diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c index d98557147..5fa33b9db 100644 --- a/xorg-server/hw/kdrive/ephyr/hostx.c +++ b/xorg-server/hw/kdrive/ephyr/hostx.c @@ -28,6 +28,7 @@ #endif #include "hostx.h" +#include "input.h" #include #include @@ -436,6 +437,7 @@ hostx_init(void) xcb_change_gc(HostX.conn, HostX.gc, XCB_GC_FOREGROUND, &pixel); if (!hostx_want_host_cursor ()) { + CursorVisible = TRUE; /* Ditch the cursor, we provide our 'own' */ cursor_pxm = xcb_generate_id(HostX.conn); xcb_create_pixmap(HostX.conn, 1, cursor_pxm, HostX.winroot, 1, 1); diff --git a/xorg-server/hw/xquartz/GL/visualConfigs.c b/xorg-server/hw/xquartz/GL/visualConfigs.c index 92142cb0d..687bf80d8 100644 --- a/xorg-server/hw/xquartz/GL/visualConfigs.c +++ b/xorg-server/hw/xquartz/GL/visualConfigs.c @@ -140,8 +140,6 @@ __GLXconfig *__glXAquaCreateVisualConfigs(int *numConfigsPtr, int screenNumber) c->visualType = GLX_TRUE_COLOR; c->next = c + 1; - c->screen = screenNumber; - c->level = 0; c->indexBits = 0; diff --git a/xorg-server/hw/xwin/glx/indirect.c b/xorg-server/hw/xwin/glx/indirect.c index 02f9b0e75..b79f023cd 100644 --- a/xorg-server/hw/xwin/glx/indirect.c +++ b/xorg-server/hw/xwin/glx/indirect.c @@ -2014,9 +2014,6 @@ glxWinCreateConfigs(HDC hdc, glxWinScreen * screen) else c->base.swapMethod = GLX_SWAP_UNDEFINED_OML; - /* EXT_import_context */ - c->base.screen = screen->base.pScreen->myNum; - /* EXT_texture_from_pixmap */ c->base.bindToTextureRgb = -1; c->base.bindToTextureRgba = -1; @@ -2393,9 +2390,6 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen) c->base.swapMethod = GLX_SWAP_UNDEFINED_OML; } - /* EXT_import_context */ - c->base.screen = screen->base.pScreen->myNum; - /* EXT_texture_from_pixmap */ /* Mesa's DRI configs always have bindToTextureRgb/Rgba TRUE (see driCreateConfigs(), so setting diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h index 1745e9ade..350dabad4 100644 --- a/xorg-server/include/input.h +++ b/xorg-server/include/input.h @@ -113,9 +113,9 @@ SOFTWARE. #endif enum InputLevel { - CORE, - XI, - XI2, + CORE = 1, + XI = 2, + XI2 = 3, }; typedef unsigned long Leds; diff --git a/xorg-server/miext/rootless/rootlessWindow.c b/xorg-server/miext/rootless/rootlessWindow.c index cfcb6e558..7e3c28130 100644 --- a/xorg-server/miext/rootless/rootlessWindow.c +++ b/xorg-server/miext/rootless/rootlessWindow.c @@ -684,7 +684,7 @@ RootlessResizeCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, if (gResizeDeathCount == 1) { /* Simple case, we only have a single source pixmap. */ - fbCopyRegion(&gResizeDeathPix[0]->drawable, + miCopyRegion(&gResizeDeathPix[0]->drawable, &pScreen->GetWindowPixmap(pWin)->drawable, 0, &rgnDst, dx, dy, fbCopyWindowProc, 0, 0); } @@ -700,7 +700,7 @@ RootlessResizeCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionNull(&clipped); RegionIntersect(&rgnDst, &clip, &clipped); - fbCopyRegion(&gResizeDeathPix[i]->drawable, + miCopyRegion(&gResizeDeathPix[i]->drawable, &pScreen->GetWindowPixmap(pWin)->drawable, 0, &clipped, dx, dy, fbCopyWindowProc, 0, 0); @@ -778,7 +778,7 @@ RootlessCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) else { RootlessStartDrawing(pWin); - fbCopyRegion((DrawablePtr) pWin, (DrawablePtr) pWin, + miCopyRegion((DrawablePtr) pWin, (DrawablePtr) pWin, 0, &rgnDst, dx, dy, fbCopyWindowProc, 0, 0); /* prgnSrc has been translated to dst position */ -- cgit v1.2.3