diff options
56 files changed, 1136 insertions, 576 deletions
diff --git a/libX11/configure.ac b/libX11/configure.ac index aaec96810..af0f34e78 100644 --- a/libX11/configure.ac +++ b/libX11/configure.ac @@ -223,8 +223,12 @@ AC_CHECK_HEADERS([sys/select.h]) AC_CHECK_FUNCS([strtol seteuid]) # Used in lcFile.c (see also --enable-xlocaledir settings below) XLOCALEDIR_IS_SAFE="no" -AC_CHECK_FUNC([issetugid], [XLOCALEDIR_IS_SAFE="yes"] - AC_DEFINE(HASSETUGID,1,[Has issetugid() function])) +AC_CHECK_DECL([issetugid]) +AC_CHECK_FUNC([issetugid]) +if test "$ac_cv_have_decl_issetugid" = yes && test "$ac_cv_func_issetugid" = yes; then + XLOCALEDIR_IS_SAFE="yes" + AC_DEFINE(HASSETUGID,1,[Has issetugid() function]) +fi AC_CHECK_FUNC([getresuid], [XLOCALEDIR_IS_SAFE="yes"] AC_DEFINE(HASGETRESUID,1,[Has getresuid() & getresgid() functions])) # Used in Font.c diff --git a/libX11/nls/en_US.UTF-8/Compose.pre b/libX11/nls/en_US.UTF-8/Compose.pre index 2eae91239..e17c3ec88 100644 --- a/libX11/nls/en_US.UTF-8/Compose.pre +++ b/libX11/nls/en_US.UTF-8/Compose.pre @@ -5830,3 +5830,188 @@ XCOMM <Multi_key> <asciicircum> <Cyrillic_ER> : "ะ ฬ" # CYRILLIC CAPITAL LETTER ER WITH COMBINING CIRCUMFLEX ACCENT <Multi_key> <backslash> <o> <slash> : "๐" # PERSON RAISING BOTH HANDS IN CELEBRATION + +XCOMM APL support Geoff Streeter 2012-01-04 + +XCOMM APL was initially an overstruck language. The original APL terminal was an IBM golfball +XCOMM with a specially designed golfball. This meant that characters could be overstruck to +XCOMM produce other characters. This gave APL a richness of primitives which is still powerful +XCOMM today. Overstrikes were always independent of order. + +XCOMM APLs have extended this into a number of dialects. Let us try to support lots of them. +XCOMM Together with some that have not been used yet. Some traditional ones are not included. + +XCOMM Characters from "Mathematical Operators" + +<Multi_key> <v> <slash> : "โ" U221a # v / SQUARE ROOT +<Multi_key> <slash> <v> : "โ" U221a # / v SQUARE ROOT +<Multi_key> <8> <8> : "โ" U221e # 8 8 INFINITY +<Multi_key> <equal> <slash> : "โ " U2260 # = / NOT EQUAL TO +<Multi_key> <slash> <equal> : "โ " U2260 # / = NOT EQUAL TO +<Multi_key> <underscore> <equal> : "โก" U2261 # _ = IDENTICAL TO +<Multi_key> <equal> <underscore> : "โก" U2261 # = _ IDENTICAL TO +<Multi_key> <underscore> <U2260> : "โข" U2262 # _ โ NOT IDENTICAL TO +<Multi_key> <U2260> <underscore> : "โข" U2262 # โ _ NOT IDENTICAL TO +<Multi_key> <less> <underscore> : "โค" U2264 # < _ LESS-THAN OR EQUAL TO +<Multi_key> <underscore> <less> : "โค" U2264 # _ < LESS-THAN OR EQUAL TO +<Multi_key> <greater> <underscore> : "โฅ" U2265 # > _ GREATER-THAN OR EQUAL TO +<Multi_key> <underscore> <greater> : "โฅ" U2265 # _ > GREATER-THAN OR EQUAL TO +<Multi_key> <underscore> <U2282> : "โ" U2286 # _ โ SUBSET OF OR EQUAL TO +<Multi_key> <U2282> <underscore> : "โ" U2286 # โ _ SUBSET OF OR EQUAL TO +<Multi_key> <underscore> <U2283> : "โ" U2287 # _ โ SUPERSET OF OR EQUAL TO +<Multi_key> <U2283> <underscore> : "โ" U2287 # โ _ SUPERSET OF OR EQUAL TO +<Multi_key> <U25cb> <minus> : "โ" U2296 # โ - CIRCLED MINUS +<Multi_key> <minus> <U25cb> : "โ" U2296 # - โ CIRCLED MINUS +<Multi_key> <U25cb> <period> : "โ" U2299 # โ - CIRCLED DOT +<Multi_key> <period> <U25cb> : "โ" U2299 # - โ CIRCLED DOT +<Multi_key> <parenleft> <minus> : "โข" U22a2 # ( - RIGHT TACK +<Multi_key> <minus> <parenleft> : "โข" U22a2 # - ( RIGHT TACK +<Multi_key> <parenright> <minus> : "โฃ" U22a3 # ) - LEFT TACK +<Multi_key> <minus> <parenright> : "โฃ" U22a3 # - ) LEFT TACK +<Multi_key> <less> <greater> : "โ" U22c4 # < > DIAMOND OPERATOR +<Multi_key> <greater> <less> : "โ" U22c4 # > < DIAMOND OPERATOR +<Multi_key> <U2227> <U2228> : "โ" U22c4 # โง โจ DIAMOND OPERATOR +<Multi_key> <U2228> <U2227> : "โ" U22c4 # โจ โง DIAMOND OPERATOR + +XCOMM Characters from "Miscellaneous Technical" + +<Multi_key> <U22a5> <U22a4> : "โถ" U2336 # โฅ โค APL FUNCTIONAL SYMBOL I-BEAM +<Multi_key> <U22a4> <U22a5> : "โถ" U2336 # โฅ โค APL FUNCTIONAL SYMBOL I-BEAM +<Multi_key> <bracketleft> <bracketright> : "โท" U2337 # [ ] APL FUNCTIONAL SYMBOL SQUISH QUAD +<Multi_key> <bracketright> <bracketleft> : "โท" U2337 # ] [ APL FUNCTIONAL SYMBOL SQUISH QUAD +<Multi_key> <U2395> <equal> : "โธ" U2338 # โ = APL FUNCTIONAL SYMBOL QUAD EQUAL +<Multi_key> <equal> <U2395> : "โธ" U2338 # = โ APL FUNCTIONAL SYMBOL QUAD EQUAL +<Multi_key> <U2395> <division> : "โน" U2339 # โ รท APL FUNCTIONAL SYMBOL QUAD DIVIDE +<Multi_key> <division> <U2395> : "โน" U2339 # รท โ APL FUNCTIONAL SYMBOL QUAD DIVIDE +<Multi_key> <U2395> <U22c4> : "โบ" U233a # โ โ APL FUNCTIONAL SYMBOL QUAD DIAMOND +<Multi_key> <U22c4> <U2395> : "โบ" U233a # โ โ APL FUNCTIONAL SYMBOL QUAD DIAMOND +<Multi_key> <U2395> <U2218> : "โป" U233b # โ โ APL FUNCTIONAL SYMBOL QUAD JOT +<Multi_key> <U2218> <U2395> : "โป" U233b # โ โ APL FUNCTIONAL SYMBOL QUAD JOT +<Multi_key> <U2395> <U25cb> : "โผ" U233c # โ โ APL FUNCTIONAL SYMBOL QUAD CIRCLE +<Multi_key> <U25cb> <U2395> : "โผ" U233c # โ โ APL FUNCTIONAL SYMBOL QUAD CIRCLE +<Multi_key> <U25cb> <bar> : "โฝ" U233d # โ | APL FUNCTIONAL SYMBOL CIRCLE STILE +<Multi_key> <bar> <U25cb> : "โฝ" U233d # | โ APL FUNCTIONAL SYMBOL CIRCLE STILE +<Multi_key> <U25cb> <U2218> : "โพ" U233e # โ โ APL FUNCTIONAL SYMBOL CIRCLE JOT +<Multi_key> <U2218> <U25cb> : "โพ" U233e # โ โ APL FUNCTIONAL SYMBOL CIRCLE JOT +<Multi_key> <slash> <minus> : "โฟ" U233f # / - APL FUNCTIONAL SYMBOL SLASH BAR +<Multi_key> <minus> <slash> : "โฟ" U233f # - / APL FUNCTIONAL SYMBOL SLASH BAR +<Multi_key> <backslash> <minus> : "โ" U2340 # \ - APL FUNCTIONAL SYMBOL BACKSLASH BAR +<Multi_key> <minus> <backslash> : "โ" U2340 # - \ APL FUNCTIONAL SYMBOL BACKSLASH BAR +<Multi_key> <slash> <U2395> : "โ" U2341 # / โ APL FUNCTIONAL SYMBOL QUAD SLASH +<Multi_key> <U2395> <slash> : "โ" U2341 # โ / APL FUNCTIONAL SYMBOL QUAD SLASH +<Multi_key> <backslash> <U2395> : "โ" U2342 # \ โ APL FUNCTIONAL SYMBOL QUAD BACKSLASH +<Multi_key> <U2395> <backslash> : "โ" U2342 # โ \ APL FUNCTIONAL SYMBOL QUAD BACKSLASH +<Multi_key> <less> <U2395> : "โ" U2343 # < โ APL FUNCTIONAL SYMBOL QUAD LESS-THAN +<Multi_key> <U2395> <less> : "โ" U2343 # โ < APL FUNCTIONAL SYMBOL QUAD LESS-THAN +<Multi_key> <greater> <U2395> : "โ" U2344 # > โ APL FUNCTIONAL SYMBOL QUAD GREATER-THAN +<Multi_key> <U2395> <greater> : "โ" U2344 # โ > APL FUNCTIONAL SYMBOL QUAD GREATER-THAN +<Multi_key> <U2190> <bar> : "โ
" U2345 # โ | APL FUNCTIONAL SYMBOL LEFTWARDS VANE +<Multi_key> <bar> <U2190> : "โ
" U2345 # | โ APL FUNCTIONAL SYMBOL LEFTWARDS VANE +<Multi_key> <U2192> <bar> : "โ" U2346 # โ | APL FUNCTIONAL SYMBOL RIGHTWARDS VANE +<Multi_key> <bar> <U2192> : "โ" U2346 # | โ APL FUNCTIONAL SYMBOL RIGHTWARDS VANE +<Multi_key> <U2190> <U2395> : "โ" U2347 # โ โ APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW +<Multi_key> <U2395> <U2190> : "โ" U2347 # โ โ APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW +<Multi_key> <U2192> <U2395> : "โ" U2348 # โ โ APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW +<Multi_key> <U2395> <U2192> : "โ" U2348 # โ โ APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW +<Multi_key> <U25cb> <backslash> : "โ" U2349 # โ \ APL FUNCTIONAL SYMBOL CIRCLE SLOPE +<Multi_key> <backslash> <U25cb> : "โ" U2349 # \ โ APL FUNCTIONAL SYMBOL CIRCLE SLOPE +<Multi_key> <underscore> <U22a5> : "โ" U234a # _ โฅ APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR +<Multi_key> <U22a5> <underscore> : "โ" U234a # โฅ _ APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR +<Multi_key> <U2206> <bar> : "โ" U234b # โ | APL FUNCTIONAL SYMBOL DELTA STILE +<Multi_key> <bar> <U2206> : "โ" U234b # | โ APL FUNCTIONAL SYMBOL DELTA STILE +<Multi_key> <U2228> <U2395> : "โ" U234c # โจ โ APL FUNCTIONAL SYMBOL QUAD DOWN CARET +<Multi_key> <U2395> <U2228> : "โ" U234c # โ โจ APL FUNCTIONAL SYMBOL QUAD DOWN CARET +<Multi_key> <U2206> <U2395> : "โ" U234d # โ โ APL FUNCTIONAL SYMBOL QUAD DELTA +<Multi_key> <U2395> <U2206> : "โ" U234d # โ โ APL FUNCTIONAL SYMBOL QUAD DELTA +<Multi_key> <U2218> <U22a5> : "โ" U234e # โ โฅ APL FUNCTIONAL SYMBOL DOWN TACK JOT +<Multi_key> <U22a5> <U2218> : "โ" U234e # โฅ โ APL FUNCTIONAL SYMBOL DOWN TACK JOT +<Multi_key> <U2191> <minus> : "โ" U234f # โ - APL FUNCTIONAL SYMBOL UPWARDS VANE +<Multi_key> <minus> <U2191> : "โ" U234f # - โ APL FUNCTIONAL SYMBOL UPWARDS VANE +<Multi_key> <U2191> <U2395> : "โ" U2350 # โ โ APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW +<Multi_key> <U2395> <U2191> : "โ" U2350 # โ โ APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW +XCOMM I cannot get anything to work with <macron>. Given that no extant APLs use โ I will just leave the lines +XCOMM in place. +<Multi_key> <macron> <U22a4> : "โ" U2351 # ยฏ โค APL FUNCTIONAL SYMBOL UP TACK OVERBAR +<Multi_key> <U22a4> <macron> : "โ" U2351 # โค ยฏ APL FUNCTIONAL SYMBOL UP TACK OVERBAR +<Multi_key> <U2207> <bar> : "โ" U2352 # โ | APL FUNCTIONAL SYMBOL DEL STILE +<Multi_key> <bar> <U2207> : "โ" U2352 # | โ APL FUNCTIONAL SYMBOL DEL STILE +<Multi_key> <U2227> <U2395> : "โ" U2353 # โง โ APL FUNCTIONAL SYMBOL QUAD UP CARET +<Multi_key> <U2395> <U2227> : "โ" U2353 # โ โง APL FUNCTIONAL SYMBOL QUAD UP CARET +<Multi_key> <U2207> <U2395> : "โ" U2354 # โ โ APL FUNCTIONAL SYMBOL QUAD DEL +<Multi_key> <U2395> <U2207> : "โ" U2354 # โ โ APL FUNCTIONAL SYMBOL QUAD DEL +<Multi_key> <U2218> <U22a4> : "โ" U2355 # โ โค APL FUNCTIONAL SYMBOL UP TACK JOT +<Multi_key> <U22a4> <U2218> : "โ" U2355 # โค โ APL FUNCTIONAL SYMBOL UP TACK JOT +<Multi_key> <U2193> <minus> : "โ" U2356 # โ - APL FUNCTIONAL SYMBOL DOWNWARDS VANE +<Multi_key> <minus> <U2193> : "โ" U2356 # - โ APL FUNCTIONAL SYMBOL DOWNWARDS VANE +<Multi_key> <U2193> <U2395> : "โ" U2357 # โ โ APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW +<Multi_key> <U2395> <U2193> : "โ" U2357 # โ โ APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW +XCOMM This line clashes with the <apostrophe> <underscore> <E> (and similar) that appear to be there to provide +XCOMM a work around for the problems with <macron>. Or to cope with keyboards that do not have <macron> (more likely). +XCOMM All APL keyboards have <macron>, it is used as the -ve sign for numbers. +XCOMM I do not know of an extant APL using โ +<Multi_key> <apostrophe> <underscore> : "โ" U2358 # ' _ APL FUNCTIONAL SYMBOL QUOTE UNDERBAR +<Multi_key> <underscore> <apostrophe> : "โ" U2358 # _ ' APL FUNCTIONAL SYMBOL QUOTE UNDERBAR +<Multi_key> <U2206> <underscore> : "โ" U2359 # โ _ APL FUNCTIONAL SYMBOL DELTA UNDERBAR +<Multi_key> <underscore> <U2206> : "โ" U2359 # _ โ APL FUNCTIONAL SYMBOL DELTA UNDERBAR +<Multi_key> <U22c4> <underscore> : "โ" U235a # โ _ APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR +<Multi_key> <underscore> <U22c4> : "โ" U235a # _ โ APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR +<Multi_key> <U2218> <underscore> : "โ" U235b # โ _ APL FUNCTIONAL SYMBOL JOT UNDERBAR +<Multi_key> <underscore> <U2218> : "โ" U235b # _ โ APL FUNCTIONAL SYMBOL JOT UNDERBAR +<Multi_key> <U25cb> <underscore> : "โ" U235c # โ _ APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR +<Multi_key> <underscore> <U25cb> : "โ" U235c # _ โ APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR +<Multi_key> <U2218> <U2229> : "โ" U235d # โ โฉ APL FUNCTIONAL SYMBOL UP SHOE JOT +<Multi_key> <U2229> <U2218> : "โ" U235d # โฉ โ APL FUNCTIONAL SYMBOL UP SHOE JOT +<Multi_key> <U2395> <apostrophe> : "โ" U235e # * ยจ APL FUNCTIONAL SYMBOL QUOTE QUAD +<Multi_key> <apostrophe> <U2395> : "โ" U235e # ยจ * APL FUNCTIONAL SYMBOL QUOTE QUAD +<Multi_key> <U25cb> <asterisk> : "โ" U235f # โ * APL FUNCTIONAL SYMBOL CIRCLE STAR +<Multi_key> <asterisk> <U25cb> : "โ" U235f # * โ APL FUNCTIONAL SYMBOL CIRCLE STAR +<Multi_key> <colon> <U2395> : "โ " U2360 # : โ APL FUNCTIONAL SYMBOL QUAD COLON +<Multi_key> <U2395> <colon> : "โ " U2360 # โ : APL FUNCTIONAL SYMBOL QUAD COLON +<Multi_key> <diaeresis> <U22a4> : "โก" U2361 # ยจ โค APL FUNCTIONAL SYMBOL UP TACK DIAERESIS +<Multi_key> <U22a4> <diaeresis> : "โก" U2361 # โค ยจ APL FUNCTIONAL SYMBOL UP TACK DIAERESIS +<Multi_key> <diaeresis> <U2207> : "โข" U2362 # ยจ โ APL FUNCTIONAL SYMBOL DEL DIAERESIS +<Multi_key> <U2207> <diaeresis> : "โข" U2362 # โ ยจ APL FUNCTIONAL SYMBOL DEL DIAERESIS +<Multi_key> <asterisk> <diaeresis> : "โฃ" U2363 # * ยจ APL FUNCTIONAL SYMBOL STAR DIAERESIS +<Multi_key> <diaeresis> <asterisk> : "โฃ" U2363 # ยจ * APL FUNCTIONAL SYMBOL STAR DIAERESIS +<Multi_key> <U2218> <diaeresis> : "โค" U2364 # โ ยจ APL FUNCTIONAL SYMBOL JOT DIAERESIS +<Multi_key> <diaeresis> <U2218> : "โค" U2364 # ยจ โ APL FUNCTIONAL SYMBOL JOT DIAERESIS +<Multi_key> <U25cb> <diaeresis> : "โฅ" U2365 # โ ยจ APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS +<Multi_key> <diaeresis> <U25cb> : "โฅ" U2365 # ยจ โ APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS +<Multi_key> <U222a> <bar> : "โฆ" U2366 # โช | APL FUNCTIONAL SYMBOL DOWN SHOE STILE +<Multi_key> <bar> <U222a> : "โฆ" U2366 # | โช APL FUNCTIONAL SYMBOL DOWN SHOE STILE +<Multi_key> <U2282> <bar> : "โง" U2367 # โ | APL FUNCTIONAL SYMBOL LEFT SHOE STILE +<Multi_key> <bar> <U2282> : "โง" U2367 # | โ APL FUNCTIONAL SYMBOL LEFT SHOE STILE +<Multi_key> <diaeresis> <asciitilde> : "โจ" U2368 # ยจ ~ APL FUNCTIONAL SYMBOL TILDE DIAERESIS +<Multi_key> <asciitilde> <diaeresis> : "โจ" U2368 # ~ ยจ APL FUNCTIONAL SYMBOL TILDE DIAERESIS +<Multi_key> <diaeresis> <greater> : "โฉ" U2369 # ยจ > APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS +<Multi_key> <greater> <diaeresis> : "โฉ" U2369 # > ยจ APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS +<Multi_key> <comma> <minus> : "โช" U236a # , - APL FUNCTIONAL SYMBOL COMMA BAR +<Multi_key> <minus> <comma> : "โช" U236a # - , APL FUNCTIONAL SYMBOL COMMA BAR +<Multi_key> <U2207> <asciitilde> : "โซ" U236b # โ ~ APL FUNCTIONAL SYMBOL DEL TILDE +<Multi_key> <asciitilde> <U2207> : "โซ" U236b # ~ โ APL FUNCTIONAL SYMBOL DEL TILDE +<Multi_key> <0> <asciitilde> : "โฌ" U236c # 0 ~ APL FUNCTIONAL SYMBOL ZILDE +<Multi_key> <asciitilde> <0> : "โฌ" U236c # ~ 0 APL FUNCTIONAL SYMBOL ZILDE +<Multi_key> <bar> <asciitilde> : "โญ" U236d # | ~ APL FUNCTIONAL SYMBOL STILE TILDE +<Multi_key> <asciitilde> <bar> : "โญ" U236d # ~ | APL FUNCTIONAL SYMBOL STILE TILDE +XCOMM This line does not work. It clashes with +XCOMM <underscore> <semicolon> <O> for วฌ and +XCOMM <underscore> <semicolon> <o> for วญ. +XCOMM Given that no extant APLs use โฎ I will just leave the line in place. +<Multi_key> <underscore> <semicolon> : "โฎ" U236e # _ ; APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR +<Multi_key> <semicolon> <underscore> : "โฎ" U236e # ; _ APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR +<Multi_key> <U2260> <U2395> : "โฏ" U236f # โ โ APL FUNCTIONAL SYMBOL QUAD NOT EQUAL +<Multi_key> <U2395> <U2260> : "โฏ" U236f # โ โ APL FUNCTIONAL SYMBOL QUAD NOT EQUAL +<Multi_key> <question> <U2395> : "โฐ" U2370 # ? โ APL FUNCTIONAL SYMBOL QUAD QUESTION +<Multi_key> <U2395> <question> : "โฐ" U2370 # โ ? APL FUNCTIONAL SYMBOL QUAD QUESTION +<Multi_key> <U2228> <asciitilde> : "โฑ" U2371 # โจ ~ APL FUNCTIONAL SYMBOL DOWN CARET TILDE +<Multi_key> <asciitilde> <U2228> : "โฑ" U2371 # ~ โจ APL FUNCTIONAL SYMBOL DOWN CARET TILDE +<Multi_key> <U2227> <asciitilde> : "โฒ" U2372 # โง ~ APL FUNCTIONAL SYMBOL UP CARET TILDE +<Multi_key> <asciitilde> <U2227> : "โฒ" U2372 # ~ โง APL FUNCTIONAL SYMBOL UP CARET TILDE +<Multi_key> <U237a> <underscore> : "โถ" U2376 # โบ _ APL FUNCTIONAL SYMBOL ALPHA UNDERBAR +<Multi_key> <underscore> <U237a> : "โถ" U2376 # _ โบ APL FUNCTIONAL SYMBOL ALPHA UNDERBAR +<Multi_key> <U220a> <underscore> : "โท" U2377 # โ _ APL FUNCTIONAL SYMBOL EPSILON UNDERBAR +<Multi_key> <underscore> <U220a> : "โท" U2377 # _ โ APL FUNCTIONAL SYMBOL EPSILON UNDERBAR +<Multi_key> <U2373> <underscore> : "โธ" U2378 # โณ _ APL FUNCTIONAL SYMBOL IOTA UNDERBAR +<Multi_key> <underscore> <U2373> : "โธ" U2378 # _ โณ APL FUNCTIONAL SYMBOL IOTA UNDERBAR +<Multi_key> <U2375> <underscore> : "โน" U2379 # โต _ APL FUNCTIONAL SYMBOL OMEGA UNDERBAR +<Multi_key> <underscore> <U2375> : "โน" U2379 # _ โต APL FUNCTIONAL SYMBOL OMEGA UNDERBAR diff --git a/mesalib/configs/default b/mesalib/configs/default index cdaeec8b4..40fa5e31e 100644 --- a/mesalib/configs/default +++ b/mesalib/configs/default @@ -9,7 +9,7 @@ CONFIG_NAME = default # Version info MESA_MAJOR=8 -MESA_MINOR=0 +MESA_MINOR=1 MESA_TINY=0 MESA_VERSION = $(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY) diff --git a/mesalib/docs/GL3.txt b/mesalib/docs/GL3.txt index 0a860bb3c..5fc6c69ba 100644 --- a/mesalib/docs/GL3.txt +++ b/mesalib/docs/GL3.txt @@ -88,7 +88,7 @@ GL 4.0: GLSL 4.0 not started GL_ARB_texture_query_lod not started -GL_ARB_draw_buffers_blend DONE (r600, softpipe) +GL_ARB_draw_buffers_blend DONE (i965, r600, softpipe) GL_ARB_draw_indirect not started GL_ARB_gpu_shader_fp64 not started GL_ARB_sample_shading not started diff --git a/mesalib/docs/viewperf.html b/mesalib/docs/viewperf.html index 279625046..af351bc42 100644 --- a/mesalib/docs/viewperf.html +++ b/mesalib/docs/viewperf.html @@ -84,6 +84,11 @@ If the Mesa driver doesn't support this extension the rendering will be incorrect and the test will fail. </p> +<p> +Also, the color of the line drawings in test 2 seem to appear in a random +color. This is probably due to some uninitialized state somewhere. +</p> + <h2>sw-02 test 6</h2> diff --git a/mesalib/include/GL/internal/dri_interface.h b/mesalib/include/GL/internal/dri_interface.h index eb1b6f28d..fd29e8256 100644 --- a/mesalib/include/GL/internal/dri_interface.h +++ b/mesalib/include/GL/internal/dri_interface.h @@ -898,7 +898,7 @@ struct __DRIdri2ExtensionRec { * extensions. */ #define __DRI_IMAGE "DRI_IMAGE" -#define __DRI_IMAGE_VERSION 3 +#define __DRI_IMAGE_VERSION 4 /** * These formats correspond to the similarly named MESA_FORMAT_* @@ -915,6 +915,7 @@ struct __DRIdri2ExtensionRec { #define __DRI_IMAGE_USE_SHARE 0x0001 #define __DRI_IMAGE_USE_SCANOUT 0x0002 #define __DRI_IMAGE_USE_CURSOR 0x0004 +#define __DRI_IMAGE_USE_WRITE 0x0008 /** * queryImage attributes @@ -959,6 +960,13 @@ struct __DRIimageExtensionRec { * \since 2 */ GLboolean (*validateUsage)(__DRIimage *image, unsigned int use); + + /** + * Write data into image. + * + * \since 4 + */ + int (*write)(__DRIimage *image, const void *buf, size_t count); }; diff --git a/mesalib/src/SConscript b/mesalib/src/SConscript index ba6be0be1..777ad23f2 100644 --- a/mesalib/src/SConscript +++ b/mesalib/src/SConscript @@ -24,7 +24,7 @@ SConscript('mapi/vgapi/SConscript') if not env['embedded']: if env['platform'] not in ['windows', 'darwin', 'haiku']: SConscript('glx/SConscript') - if env['platform'] not in ['darwin', 'haiku']: + if env['platform'] not in ['darwin', 'haiku', 'sunos']: SConscript('egl/main/SConscript') if env['platform'] not in ['darwin']: SConscript('glu/sgi/SConscript') diff --git a/mesalib/src/gallium/auxiliary/util/u_format.h b/mesalib/src/gallium/auxiliary/util/u_format.h index bd4e51d27..1718fb5e2 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format.h +++ b/mesalib/src/gallium/auxiliary/util/u_format.h @@ -549,6 +549,19 @@ util_format_colormask(const struct util_format_description *desc) } +/** + * Checks if color mask covers every channel for the specified format + * + * @param desc a format description to check colormask with + * @param colormask a bit mask for channels, matches format of PIPE_MASK_RGBA + */ +static INLINE boolean +util_format_colormask_full(const struct util_format_description *desc, unsigned colormask) +{ + return (~colormask & util_format_colormask(desc)) == 0; +} + + boolean util_format_is_float(enum pipe_format format); diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp index 8bf0ba2a8..9e7c5995f 100644 --- a/mesalib/src/glsl/ast_function.cpp +++ b/mesalib/src/glsl/ast_function.cpp @@ -153,21 +153,21 @@ verify_parameter_modes(_mesa_glsl_parse_state *state, } ir_variable *var = actual->variable_referenced(); - if (var) { - if (var->read_only) { - _mesa_glsl_error(&loc, state, - "function parameter '%s %s' references the " - "read-only variable '%s'", - mode, formal->name, - actual->variable_referenced()->name); - return false; - } else if (!actual->is_lvalue()) { - _mesa_glsl_error(&loc, state, - "function parameter '%s %s' is not an lvalue", - mode, formal->name); - return false; - } + if (var) var->assigned = true; + + if (var && var->read_only) { + _mesa_glsl_error(&loc, state, + "function parameter '%s %s' references the " + "read-only variable '%s'", + mode, formal->name, + actual->variable_referenced()->name); + return false; + } else if (!actual->is_lvalue()) { + _mesa_glsl_error(&loc, state, + "function parameter '%s %s' is not an lvalue", + mode, formal->name); + return false; } } @@ -278,7 +278,7 @@ generate_call(exec_list *instructions, ir_function_signature *sig, * Function calls were first allowed to be constant expressions in GLSL 1.20. */ if (state->language_version >= 120) { - ir_constant *value = sig->constant_expression_value(actual_parameters); + ir_constant *value = sig->constant_expression_value(actual_parameters, NULL); if (value != NULL) { return value; } diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index e24914b83..86bb8741b 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -4039,13 +4039,13 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state, foreach_list(node, instructions) { ir_variable *var = ((ir_instruction *)node)->as_variable(); - if (!var) + if (!var || !var->assigned) continue; if (strcmp(var->name, "gl_FragColor") == 0) - gl_FragColor_assigned = var->assigned; + gl_FragColor_assigned = true; else if (strcmp(var->name, "gl_FragData") == 0) - gl_FragData_assigned = var->assigned; + gl_FragData_assigned = true; else if (strncmp(var->name, "gl_", 3) != 0) { if (state->target == fragment_shader && (var->mode == ir_var_out || var->mode == ir_var_inout)) { diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index ae7a365f4..6f1c86b43 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -36,8 +36,9 @@ extern "C" { #include "ir_optimization.h" #include "loop_analysis.h" -_mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *ctx, +_mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, GLenum target, void *mem_ctx) + : ctx(_ctx) { switch (target) { case GL_VERTEX_SHADER: this->target = vertex_shader; break; @@ -134,24 +135,49 @@ _mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target) return "unknown"; } +/* This helper function will append the given message to the shader's + info log and report it via GL_ARB_debug_output. Per that extension, + 'type' is one of the enum values classifying the message, and + 'id' is the implementation-defined ID of the given message. */ +static void +_mesa_glsl_msg(const YYLTYPE *locp, _mesa_glsl_parse_state *state, + GLenum type, GLuint id, const char *fmt, va_list ap) +{ + bool error = (type == GL_DEBUG_TYPE_ERROR_ARB); + + assert(state->info_log != NULL); + + /* Get the offset that the new message will be written to. */ + int msg_offset = strlen(state->info_log); + + ralloc_asprintf_append(&state->info_log, "%u:%u(%u): %s: ", + locp->source, + locp->first_line, + locp->first_column, + error ? "error" : "warning"); + ralloc_vasprintf_append(&state->info_log, fmt, ap); + + const char *const msg = &state->info_log[msg_offset]; + struct gl_context *ctx = state->ctx; + /* Report the error via GL_ARB_debug_output. */ + if (error) + _mesa_shader_debug(ctx, type, id, msg, strlen(msg)); + + ralloc_strcat(&state->info_log, "\n"); +} void _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state, const char *fmt, ...) { va_list ap; + GLenum type = GL_DEBUG_TYPE_ERROR_ARB; state->error = true; - assert(state->info_log != NULL); - ralloc_asprintf_append(&state->info_log, "%u:%u(%u): error: ", - locp->source, - locp->first_line, - locp->first_column); va_start(ap, fmt); - ralloc_vasprintf_append(&state->info_log, fmt, ap); + _mesa_glsl_msg(locp, state, type, SHADER_ERROR_UNKNOWN, fmt, ap); va_end(ap); - ralloc_strcat(&state->info_log, "\n"); } @@ -160,16 +186,11 @@ _mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state, const char *fmt, ...) { va_list ap; + GLenum type = GL_DEBUG_TYPE_OTHER_ARB; - assert(state->info_log != NULL); - ralloc_asprintf_append(&state->info_log, "%u:%u(%u): warning: ", - locp->source, - locp->first_line, - locp->first_column); va_start(ap, fmt); - ralloc_vasprintf_append(&state->info_log, fmt, ap); + _mesa_glsl_msg(locp, state, type, 0, fmt, ap); va_end(ap); - ralloc_strcat(&state->info_log, "\n"); } diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index 1d9409056..9c5d0a78f 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -57,7 +57,7 @@ struct glsl_switch_state { }; struct _mesa_glsl_parse_state { - _mesa_glsl_parse_state(struct gl_context *ctx, GLenum target, + _mesa_glsl_parse_state(struct gl_context *_ctx, GLenum target, void *mem_ctx); /* Callers of this ralloc-based new need not call delete. It's @@ -81,6 +81,7 @@ struct _mesa_glsl_parse_state { ralloc_free(mem); } + struct gl_context *const ctx; void *scanner; exec_list translation_unit; glsl_symbol_table *symbols; diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index 1ba87515e..970d8f3ba 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -716,12 +716,27 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) ir_constant * ir_constant::zero(void *mem_ctx, const glsl_type *type) { - assert(type->is_numeric() || type->is_boolean()); + assert(type->is_scalar() || type->is_vector() || type->is_matrix() + || type->is_record() || type->is_array()); ir_constant *c = new(mem_ctx) ir_constant; c->type = type; memset(&c->value, 0, sizeof(c->value)); + if (type->is_array()) { + c->array_elements = ralloc_array(c, ir_constant *, type->length); + + for (unsigned i = 0; i < type->length; i++) + c->array_elements[i] = ir_constant::zero(c, type->element_type()); + } + + if (type->is_record()) { + for (unsigned i = 0; i < type->length; i++) { + ir_constant *comp = ir_constant::zero(mem_ctx, type->fields.structure[i].type); + c->components.push_tail(comp); + } + } + return c; } @@ -841,6 +856,95 @@ ir_constant::get_record_field(const char *name) return (ir_constant *) node; } +void +ir_constant::copy_offset(ir_constant *src, int offset) +{ + switch (this->type->base_type) { + case GLSL_TYPE_UINT: + case GLSL_TYPE_INT: + case GLSL_TYPE_FLOAT: + case GLSL_TYPE_BOOL: { + unsigned int size = src->type->components(); + assert (size <= this->type->components() - offset); + for (unsigned int i=0; i<size; i++) { + switch (this->type->base_type) { + case GLSL_TYPE_UINT: + value.u[i+offset] = src->get_uint_component(i); + break; + case GLSL_TYPE_INT: + value.i[i+offset] = src->get_int_component(i); + break; + case GLSL_TYPE_FLOAT: + value.f[i+offset] = src->get_float_component(i); + break; + case GLSL_TYPE_BOOL: + value.b[i+offset] = src->get_bool_component(i); + break; + default: // Shut up the compiler + break; + } + } + break; + } + + case GLSL_TYPE_STRUCT: { + assert (src->type == this->type); + this->components.make_empty(); + foreach_list(node, &src->components) { + ir_constant *const orig = (ir_constant *) node; + + this->components.push_tail(orig->clone(this, NULL)); + } + break; + } + + case GLSL_TYPE_ARRAY: { + assert (src->type == this->type); + for (unsigned i = 0; i < this->type->length; i++) { + this->array_elements[i] = src->array_elements[i]->clone(this, NULL); + } + break; + } + + default: + assert(!"Should not get here."); + break; + } +} + +void +ir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask) +{ + assert (!type->is_array() && !type->is_record()); + + if (!type->is_vector() && !type->is_matrix()) { + offset = 0; + mask = 1; + } + + int id = 0; + for (int i=0; i<4; i++) { + if (mask & (1 << i)) { + switch (this->type->base_type) { + case GLSL_TYPE_UINT: + value.u[i+offset] = src->get_uint_component(id++); + break; + case GLSL_TYPE_INT: + value.i[i+offset] = src->get_int_component(id++); + break; + case GLSL_TYPE_FLOAT: + value.f[i+offset] = src->get_float_component(id++); + break; + case GLSL_TYPE_BOOL: + value.b[i+offset] = src->get_bool_component(id++); + break; + default: + assert(!"Should not get here."); + return; + } + } + } +} bool ir_constant::has_value(const ir_constant *c) const @@ -1377,6 +1481,7 @@ ir_function_signature::ir_function_signature(const glsl_type *return_type) { this->ir_type = ir_type_function_signature; this->is_builtin = false; + this->origin = NULL; } diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index ddfaf3614..9c7961ab9 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -146,7 +146,7 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual ir_rvalue * as_rvalue() { @@ -502,10 +502,11 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); /** - * Attempt to evaluate this function as a constant expression, given - * a list of the actual parameters. Returns NULL for non-built-ins. + * Attempt to evaluate this function as a constant expression, + * given a list of the actual parameters and the variable context. + * Returns NULL for non-built-ins. */ - ir_constant *constant_expression_value(exec_list *actual_parameters); + ir_constant *constant_expression_value(exec_list *actual_parameters, struct hash_table *variable_context); /** * Get the name of the function for which this is a signature @@ -571,7 +572,25 @@ private: /** Function of which this signature is one overload. */ class ir_function *_function; + /** Function signature of which this one is a prototype clone */ + const ir_function_signature *origin; + friend class ir_function; + + /** + * Helper function to run a list of instructions for constant + * expression evaluation. + * + * The hash table represents the values of the visible variables. + * There are no scoping issues because the table is indexed on + * ir_variable pointers, not variable names. + * + * Returns false if the expression is not constant, true otherwise, + * and the value in *result if result is non-NULL. + */ + bool constant_expression_evaluate_expression_list(const struct exec_list &body, + struct hash_table *variable_context, + ir_constant **result); }; @@ -763,7 +782,7 @@ public: virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual void accept(ir_visitor *v) { @@ -999,10 +1018,14 @@ public: /** * Attempt to constant-fold the expression * + * The "variable_context" hash table links ir_variable * to ir_constant * + * that represent the variables' values. \c NULL represents an empty + * context. + * * If the expression cannot be constant folded, this method will return * \c NULL. */ - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); /** * Determine the number of operands used by an expression @@ -1065,7 +1088,7 @@ public: virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual ir_call *as_call() { @@ -1297,7 +1320,7 @@ public: virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual void accept(ir_visitor *v) { @@ -1389,7 +1412,7 @@ public: virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual ir_swizzle *as_swizzle() { @@ -1446,6 +1469,15 @@ public: * Get the variable that is ultimately referenced by an r-value */ virtual ir_variable *variable_referenced() const = 0; + + /** + * Get the constant that is ultimately referenced by an r-value, + * in a constant expression evaluation context. + * + * The offset is used when the reference is to a specific column of + * a matrix. + */ + virtual void constant_referenced(struct hash_table *variable_context, ir_constant *&store, int &offset) const = 0; }; @@ -1456,7 +1488,7 @@ public: virtual ir_dereference_variable *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual ir_dereference_variable *as_dereference_variable() { @@ -1471,6 +1503,15 @@ public: return this->var; } + /** + * Get the constant that is ultimately referenced by an r-value, + * in a constant expression evaluation context. + * + * The offset is used when the reference is to a specific column of + * a matrix. + */ + virtual void constant_referenced(struct hash_table *variable_context, ir_constant *&store, int &offset) const; + virtual ir_variable *whole_variable_referenced() { /* ir_dereference_variable objects always dereference the entire @@ -1505,7 +1546,7 @@ public: virtual ir_dereference_array *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual ir_dereference_array *as_dereference_array() { @@ -1520,6 +1561,15 @@ public: return this->array->variable_referenced(); } + /** + * Get the constant that is ultimately referenced by an r-value, + * in a constant expression evaluation context. + * + * The offset is used when the reference is to a specific column of + * a matrix. + */ + virtual void constant_referenced(struct hash_table *variable_context, ir_constant *&store, int &offset) const; + virtual void accept(ir_visitor *v) { v->visit(this); @@ -1544,7 +1594,7 @@ public: virtual ir_dereference_record *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); /** * Get the variable that is ultimately referenced by an r-value @@ -1554,6 +1604,15 @@ public: return this->record->variable_referenced(); } + /** + * Get the constant that is ultimately referenced by an r-value, + * in a constant expression evaluation context. + * + * The offset is used when the reference is to a specific column of + * a matrix. + */ + virtual void constant_referenced(struct hash_table *variable_context, ir_constant *&store, int &offset) const; + virtual void accept(ir_visitor *v) { v->visit(this); @@ -1609,7 +1668,7 @@ public: virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(); + virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); virtual ir_constant *as_constant() { @@ -1642,6 +1701,31 @@ public: ir_constant *get_record_field(const char *name); /** + * Copy the values on another constant at a given offset. + * + * The offset is ignored for array or struct copies, it's only for + * scalars or vectors into vectors or matrices. + * + * With identical types on both sides and zero offset it's clone() + * without creating a new object. + */ + + void copy_offset(ir_constant *src, int offset); + + /** + * Copy the values on another constant at a given offset and + * following an assign-like mask. + * + * The mask is ignored for scalars. + * + * Note that this function only handles what assign can handle, + * i.e. at most a vector as source and a column of a matrix as + * destination. + */ + + void copy_masked_offset(ir_constant *src, int offset, unsigned int mask); + + /** * Determine whether a constant has the same value as another constant * * \sa ir_constant::is_zero, ir_constant::is_one, diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp index 5a7a71cf6..591fe7b77 100644 --- a/mesalib/src/glsl/ir_clone.cpp +++ b/mesalib/src/glsl/ir_clone.cpp @@ -53,6 +53,7 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const var->invariant = this->invariant; var->interpolation = this->interpolation; var->location = this->location; + var->index = this->index; var->warn_extension = this->warn_extension; var->origin_upper_left = this->origin_upper_left; var->pixel_center_integer = this->pixel_center_integer; @@ -72,12 +73,6 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const sizeof(this->state_slots[0]) * var->num_state_slots); } - if (this->explicit_location) - var->location = this->location; - - if (this->explicit_index) - var->index = this->index; - if (this->constant_value) var->constant_value = this->constant_value->clone(mem_ctx, ht); @@ -329,6 +324,7 @@ ir_function_signature::clone_prototype(void *mem_ctx, struct hash_table *ht) con copy->is_defined = false; copy->is_builtin = this->is_builtin; + copy->origin = this; /* Clone the parameter list, but NOT the body. */ diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp index 4e1714a84..08a33285b 100644 --- a/mesalib/src/glsl/ir_constant_expression.cpp +++ b/mesalib/src/glsl/ir_constant_expression.cpp @@ -38,6 +38,7 @@ #include "ir.h" #include "ir_visitor.h" #include "glsl_types.h" +#include "program/hash_table.h" /* Using C99 rounding functions for roundToEven() implementation is * difficult, because round(), rint, and nearbyint() are affected by @@ -71,14 +72,14 @@ dot(ir_constant *op0, ir_constant *op1) } ir_constant * -ir_rvalue::constant_expression_value() +ir_rvalue::constant_expression_value(struct hash_table *variable_context) { assert(this->type->is_error()); return NULL; } ir_constant * -ir_expression::constant_expression_value() +ir_expression::constant_expression_value(struct hash_table *variable_context) { if (this->type->is_error()) return NULL; @@ -89,7 +90,7 @@ ir_expression::constant_expression_value() memset(&data, 0, sizeof(data)); for (unsigned operand = 0; operand < this->get_num_operands(); operand++) { - op[operand] = this->operands[operand]->constant_expression_value(); + op[operand] = this->operands[operand]->constant_expression_value(variable_context); if (!op[operand]) return NULL; } @@ -640,13 +641,13 @@ ir_expression::constant_expression_value() for (unsigned c = 0; c < op[0]->type->components(); c++) { switch (op[0]->type->base_type) { case GLSL_TYPE_UINT: - data.b[0] = op[0]->value.u[0] < op[1]->value.u[0]; + data.b[c] = op[0]->value.u[c] < op[1]->value.u[c]; break; case GLSL_TYPE_INT: - data.b[0] = op[0]->value.i[0] < op[1]->value.i[0]; + data.b[c] = op[0]->value.i[c] < op[1]->value.i[c]; break; case GLSL_TYPE_FLOAT: - data.b[0] = op[0]->value.f[0] < op[1]->value.f[0]; + data.b[c] = op[0]->value.f[c] < op[1]->value.f[c]; break; default: assert(0); @@ -676,13 +677,13 @@ ir_expression::constant_expression_value() for (unsigned c = 0; c < op[0]->type->components(); c++) { switch (op[0]->type->base_type) { case GLSL_TYPE_UINT: - data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0]; + data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c]; break; case GLSL_TYPE_INT: - data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0]; + data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c]; break; case GLSL_TYPE_FLOAT: - data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0]; + data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c]; break; default: assert(0); @@ -694,13 +695,13 @@ ir_expression::constant_expression_value() for (unsigned c = 0; c < op[0]->type->components(); c++) { switch (op[0]->type->base_type) { case GLSL_TYPE_UINT: - data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0]; + data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c]; break; case GLSL_TYPE_INT: - data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0]; + data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c]; break; case GLSL_TYPE_FLOAT: - data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0]; + data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c]; break; default: assert(0); @@ -886,7 +887,7 @@ ir_expression::constant_expression_value() ir_constant * -ir_texture::constant_expression_value() +ir_texture::constant_expression_value(struct hash_table *variable_context) { /* texture lookups aren't constant expressions */ return NULL; @@ -894,9 +895,9 @@ ir_texture::constant_expression_value() ir_constant * -ir_swizzle::constant_expression_value() +ir_swizzle::constant_expression_value(struct hash_table *variable_context) { - ir_constant *v = this->val->constant_expression_value(); + ir_constant *v = this->val->constant_expression_value(variable_context); if (v != NULL) { ir_constant_data data = { { 0 } }; @@ -922,13 +923,33 @@ ir_swizzle::constant_expression_value() } +void +ir_dereference_variable::constant_referenced(struct hash_table *variable_context, + ir_constant *&store, int &offset) const +{ + if (variable_context) { + store = (ir_constant *)hash_table_find(variable_context, var); + offset = 0; + } else { + store = NULL; + offset = 0; + } +} + ir_constant * -ir_dereference_variable::constant_expression_value() +ir_dereference_variable::constant_expression_value(struct hash_table *variable_context) { /* This may occur during compile and var->type is glsl_type::error_type */ if (!var) return NULL; + /* Give priority to the context hashtable, if it exists */ + if (variable_context) { + ir_constant *value = (ir_constant *)hash_table_find(variable_context, var); + if(value) + return value; + } + /* The constant_value of a uniform variable is its initializer, * not the lifetime constant value of the uniform. */ @@ -942,11 +963,65 @@ ir_dereference_variable::constant_expression_value() } +void +ir_dereference_array::constant_referenced(struct hash_table *variable_context, + ir_constant *&store, int &offset) const +{ + ir_constant *index_c = array_index->constant_expression_value(variable_context); + + if (!index_c || !index_c->type->is_scalar() || !index_c->type->is_integer()) { + store = 0; + offset = 0; + return; + } + + int index = index_c->type->base_type == GLSL_TYPE_INT ? + index_c->get_int_component(0) : + index_c->get_uint_component(0); + + ir_constant *substore; + int suboffset; + const ir_dereference *deref = array->as_dereference(); + if (!deref) { + store = 0; + offset = 0; + return; + } + + deref->constant_referenced(variable_context, substore, suboffset); + + if (!substore) { + store = 0; + offset = 0; + return; + } + + const glsl_type *vt = substore->type; + if (vt->is_array()) { + store = substore->get_array_element(index); + offset = 0; + return; + } + if (vt->is_matrix()) { + store = substore; + offset = index * vt->vector_elements; + return; + } + if (vt->is_vector()) { + store = substore; + offset = suboffset + index; + return; + } + + store = 0; + offset = 0; +} + ir_constant * -ir_dereference_array::constant_expression_value() +ir_dereference_array::constant_expression_value(struct hash_table *variable_context) { - ir_constant *array = this->array->constant_expression_value(); - ir_constant *idx = this->array_index->constant_expression_value(); + ir_constant *array = this->array->constant_expression_value(variable_context); + ir_constant *idx = this->array_index->constant_expression_value(variable_context); if ((array != NULL) && (idx != NULL)) { void *ctx = ralloc_parent(this); @@ -997,8 +1072,33 @@ ir_dereference_array::constant_expression_value() } +void +ir_dereference_record::constant_referenced(struct hash_table *variable_context, + ir_constant *&store, int &offset) const +{ + ir_constant *substore; + int suboffset; + const ir_dereference *deref = record->as_dereference(); + if (!deref) { + store = 0; + offset = 0; + return; + } + + deref->constant_referenced(variable_context, substore, suboffset); + + if (!substore) { + store = 0; + offset = 0; + return; + } + + store = substore->get_record_field(field); + offset = 0; +} + ir_constant * -ir_dereference_record::constant_expression_value() +ir_dereference_record::constant_expression_value(struct hash_table *variable_context) { ir_constant *v = this->record->constant_expression_value(); @@ -1007,7 +1107,7 @@ ir_dereference_record::constant_expression_value() ir_constant * -ir_assignment::constant_expression_value() +ir_assignment::constant_expression_value(struct hash_table *variable_context) { /* FINISHME: Handle CEs involving assignment (return RHS) */ return NULL; @@ -1015,21 +1115,130 @@ ir_assignment::constant_expression_value() ir_constant * -ir_constant::constant_expression_value() +ir_constant::constant_expression_value(struct hash_table *variable_context) { return this; } ir_constant * -ir_call::constant_expression_value() +ir_call::constant_expression_value(struct hash_table *variable_context) { - return this->callee->constant_expression_value(&this->actual_parameters); + return this->callee->constant_expression_value(&this->actual_parameters, variable_context); } +bool ir_function_signature::constant_expression_evaluate_expression_list(const struct exec_list &body, + struct hash_table *variable_context, + ir_constant **result) +{ + foreach_list(n, &body) { + ir_instruction *inst = (ir_instruction *)n; + switch(inst->ir_type) { + + /* (declare () type symbol) */ + case ir_type_variable: { + ir_variable *var = inst->as_variable(); + hash_table_insert(variable_context, ir_constant::zero(this, var->type), var); + break; + } + + /* (assign [condition] (write-mask) (ref) (value)) */ + case ir_type_assignment: { + ir_assignment *asg = inst->as_assignment(); + if (asg->condition) { + ir_constant *cond = asg->condition->constant_expression_value(variable_context); + if (!cond) + return false; + if (!cond->get_bool_component(0)) + break; + } + + ir_constant *store = NULL; + int offset = 0; + asg->lhs->constant_referenced(variable_context, store, offset); + + if (!store) + return false; + + ir_constant *value = asg->rhs->constant_expression_value(variable_context); + + if (!value) + return false; + + store->copy_masked_offset(value, offset, asg->write_mask); + break; + } + + /* (return (expression)) */ + case ir_type_return: + assert (result); + *result = inst->as_return()->value->constant_expression_value(variable_context); + return *result != NULL; + + /* (call name (ref) (params))*/ + case ir_type_call: { + ir_call *call = inst->as_call(); + + /* Just say no to void functions in constant expressions. We + * don't need them at that point. + */ + + if (!call->return_deref) + return false; + + ir_constant *store = NULL; + int offset = 0; + call->return_deref->constant_referenced(variable_context, store, offset); + + if (!store) + return false; + + ir_constant *value = call->constant_expression_value(variable_context); + + if(!value) + return false; + + store->copy_offset(value, offset); + break; + } + + /* (if condition (then-instructions) (else-instructions)) */ + case ir_type_if: { + ir_if *iif = inst->as_if(); + + ir_constant *cond = iif->condition->constant_expression_value(variable_context); + if (!cond || !cond->type->is_boolean()) + return false; + + exec_list &branch = cond->get_bool_component(0) ? iif->then_instructions : iif->else_instructions; + + *result = NULL; + if (!constant_expression_evaluate_expression_list(branch, variable_context, result)) + return false; + + /* If there was a return in the branch chosen, drop out now. */ + if (*result) + return true; + + break; + } + + /* Every other expression type, we drop out. */ + default: + return false; + } + } + + /* Reaching the end of the block is not an error condition */ + if (result) + *result = NULL; + + return true; +} + ir_constant * -ir_function_signature::constant_expression_value(exec_list *actual_parameters) +ir_function_signature::constant_expression_value(exec_list *actual_parameters, struct hash_table *variable_context) { const glsl_type *type = this->return_type; if (type == glsl_type::void_type) @@ -1042,396 +1251,48 @@ ir_function_signature::constant_expression_value(exec_list *actual_parameters) if (!this->is_builtin) return NULL; - unsigned num_parameters = 0; + /* + * Of the builtin functions, only the texture lookups and the noise + * ones must not be used in constant expressions. They all include + * specific opcodes so they don't need to be special-cased at this + * point. + */ + + /* Initialize the table of dereferencable names with the function + * parameters. Verify their const-ness on the way. + * + * We expect the correctness of the number of parameters to have + * been checked earlier. + */ + hash_table *deref_hash = hash_table_ctor(8, hash_table_pointer_hash, + hash_table_pointer_compare); + + /* If "origin" is non-NULL, then the function body is there. So we + * have to use the variable objects from the object with the body, + * but the parameter instanciation on the current object. + */ + const exec_node *parameter_info = origin ? origin->parameters.head : parameters.head; - /* Check if all parameters are constant */ - ir_constant *op[3]; foreach_list(n, actual_parameters) { - ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value(); + ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value(variable_context); if (constant == NULL) return NULL; - op[num_parameters] = constant; + ir_variable *var = (ir_variable *)parameter_info; + hash_table_insert(deref_hash, constant, var); - assert(num_parameters < 3); - num_parameters++; + parameter_info = parameter_info->next; } - /* Individual cases below can either: - * - Assign "expr" a new ir_expression to evaluate (for basic opcodes) - * - Fill "data" with appopriate constant data - * - Return an ir_constant directly. - */ - void *mem_ctx = ralloc_parent(this); - ir_expression *expr = NULL; - - ir_constant_data data; - memset(&data, 0, sizeof(data)); - - const char *callee = this->function_name(); - if (strcmp(callee, "abs") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL); - } else if (strcmp(callee, "all") == 0) { - assert(op[0]->type->is_boolean()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - if (!op[0]->value.b[c]) - return new(mem_ctx) ir_constant(false); - } - return new(mem_ctx) ir_constant(true); - } else if (strcmp(callee, "any") == 0) { - assert(op[0]->type->is_boolean()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - if (op[0]->value.b[c]) - return new(mem_ctx) ir_constant(true); - } - return new(mem_ctx) ir_constant(false); - } else if (strcmp(callee, "acos") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = acosf(op[0]->value.f[c]); - } else if (strcmp(callee, "acosh") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = acoshf(op[0]->value.f[c]); - } else if (strcmp(callee, "asin") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = asinf(op[0]->value.f[c]); - } else if (strcmp(callee, "asinh") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = asinhf(op[0]->value.f[c]); - } else if (strcmp(callee, "atan") == 0) { - assert(op[0]->type->is_float()); - if (num_parameters == 2) { - assert(op[1]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]); - } else { - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = atanf(op[0]->value.f[c]); - } - } else if (strcmp(callee, "atanh") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = atanhf(op[0]->value.f[c]); - } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) { - return ir_constant::zero(mem_ctx, type); - } else if (strcmp(callee, "ceil") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL); - } else if (strcmp(callee, "clamp") == 0) { - assert(num_parameters == 3); - unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1; - unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1; - for (unsigned c = 0, c1 = 0, c2 = 0; - c < op[0]->type->components(); - c1 += c1_inc, c2 += c2_inc, c++) { - - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1], - op[2]->value.u[c2]); - break; - case GLSL_TYPE_INT: - data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1], - op[2]->value.i[c2]); - break; - case GLSL_TYPE_FLOAT: - data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1], - op[2]->value.f[c2]); - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "cos") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL); - } else if (strcmp(callee, "cosh") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = coshf(op[0]->value.f[c]); - } else if (strcmp(callee, "cross") == 0) { - assert(op[0]->type == glsl_type::vec3_type); - assert(op[1]->type == glsl_type::vec3_type); - data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] - - op[1]->value.f[1] * op[0]->value.f[2]); - data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] - - op[1]->value.f[2] * op[0]->value.f[0]); - data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] - - op[1]->value.f[0] * op[0]->value.f[1]); - } else if (strcmp(callee, "degrees") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = 180.0F / M_PI * op[0]->value.f[c]; - } else if (strcmp(callee, "distance") == 0) { - assert(op[0]->type->is_float() && op[1]->type->is_float()); - float length_squared = 0.0; - for (unsigned c = 0; c < op[0]->type->components(); c++) { - float t = op[0]->value.f[c] - op[1]->value.f[c]; - length_squared += t * t; - } - return new(mem_ctx) ir_constant(sqrtf(length_squared)); - } else if (strcmp(callee, "dot") == 0) { - return new(mem_ctx) ir_constant(dot(op[0], op[1])); - } else if (strcmp(callee, "equal") == 0) { - assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] == op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] == op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] == op[1]->value.f[c]; - break; - case GLSL_TYPE_BOOL: - data.b[c] = op[0]->value.b[c] == op[1]->value.b[c]; - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "exp") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL); - } else if (strcmp(callee, "exp2") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL); - } else if (strcmp(callee, "faceforward") == 0) { - if (dot(op[2], op[1]) < 0) - return op[0]; - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = -op[0]->value.f[c]; - } else if (strcmp(callee, "floor") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL); - } else if (strcmp(callee, "fract") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL); - } else if (strcmp(callee, "fwidth") == 0) { - return ir_constant::zero(mem_ctx, type); - } else if (strcmp(callee, "greaterThan") == 0) { - assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] > op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] > op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] > op[1]->value.f[c]; - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "greaterThanEqual") == 0) { - assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c]; - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "inversesqrt") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL); - } else if (strcmp(callee, "length") == 0) { - return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0]))); - } else if (strcmp(callee, "lessThan") == 0) { - assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] < op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] < op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] < op[1]->value.f[c]; - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "lessThanEqual") == 0) { - assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c]; - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "log") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL); - } else if (strcmp(callee, "log2") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL); - } else if (strcmp(callee, "matrixCompMult") == 0) { - assert(op[0]->type->is_float() && op[1]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = op[0]->value.f[c] * op[1]->value.f[c]; - } else if (strcmp(callee, "max") == 0) { - expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]); - } else if (strcmp(callee, "min") == 0) { - expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]); - } else if (strcmp(callee, "mix") == 0) { - assert(op[0]->type->is_float() && op[1]->type->is_float()); - if (op[2]->type->is_float()) { - unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1; - unsigned components = op[0]->type->components(); - for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) { - data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) + - op[1]->value.f[c] * op[2]->value.f[c2]; - } - } else { - assert(op[2]->type->is_boolean()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c]; - } - } else if (strcmp(callee, "mod") == 0) { - expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]); - } else if (strcmp(callee, "normalize") == 0) { - assert(op[0]->type->is_float()); - float length = sqrtf(dot(op[0], op[0])); - - if (length == 0) - return ir_constant::zero(mem_ctx, type); + ir_constant *result = NULL; - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = op[0]->value.f[c] / length; - } else if (strcmp(callee, "not") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL); - } else if (strcmp(callee, "notEqual") == 0) { - assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); - for (unsigned c = 0; c < op[0]->type->components(); c++) { - switch (op[0]->type->base_type) { - case GLSL_TYPE_UINT: - data.b[c] = op[0]->value.u[c] != op[1]->value.u[c]; - break; - case GLSL_TYPE_INT: - data.b[c] = op[0]->value.i[c] != op[1]->value.i[c]; - break; - case GLSL_TYPE_FLOAT: - data.b[c] = op[0]->value.f[c] != op[1]->value.f[c]; - break; - case GLSL_TYPE_BOOL: - data.b[c] = op[0]->value.b[c] != op[1]->value.b[c]; - break; - default: - assert(!"Should not get here."); - } - } - } else if (strcmp(callee, "outerProduct") == 0) { - assert(op[0]->type->is_vector() && op[1]->type->is_vector()); - const unsigned m = op[0]->type->vector_elements; - const unsigned n = op[1]->type->vector_elements; - for (unsigned j = 0; j < n; j++) { - for (unsigned i = 0; i < m; i++) { - data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j]; - } - } - } else if (strcmp(callee, "pow") == 0) { - expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]); - } else if (strcmp(callee, "radians") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = M_PI / 180.0F * op[0]->value.f[c]; - } else if (strcmp(callee, "reflect") == 0) { - assert(op[0]->type->is_float()); - float dot_NI = dot(op[1], op[0]); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c]; - } else if (strcmp(callee, "refract") == 0) { - const float eta = op[2]->value.f[0]; - const float dot_NI = dot(op[1], op[0]); - const float k = 1.0F - eta * eta * (1.0F - dot_NI * dot_NI); - if (k < 0.0) { - return ir_constant::zero(mem_ctx, type); - } else { - for (unsigned c = 0; c < type->components(); c++) { - data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k)) - * op[1]->value.f[c]; - } - } - } else if (strcmp(callee, "round") == 0 || - strcmp(callee, "roundEven") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_round_even, op[0]); - } else if (strcmp(callee, "sign") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL); - } else if (strcmp(callee, "sin") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL); - } else if (strcmp(callee, "sinh") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = sinhf(op[0]->value.f[c]); - } else if (strcmp(callee, "smoothstep") == 0) { - assert(num_parameters == 3); - assert(op[1]->type == op[0]->type); - unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1; - for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) { - const float edge0 = op[0]->value.f[e]; - const float edge1 = op[1]->value.f[e]; - if (edge0 == edge1) { - data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */ - } else { - const float numerator = op[2]->value.f[c] - edge0; - const float denominator = edge1 - edge0; - const float t = CLAMP(numerator/denominator, 0, 1); - data.f[c] = t * t * (3 - 2 * t); - } - } - } else if (strcmp(callee, "sqrt") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL); - } else if (strcmp(callee, "step") == 0) { - assert(op[0]->type->is_float() && op[1]->type->is_float()); - /* op[0] (edge) may be either a scalar or a vector */ - const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1; - for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++) - data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0F : 1.0F; - } else if (strcmp(callee, "tan") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = tanf(op[0]->value.f[c]); - } else if (strcmp(callee, "tanh") == 0) { - assert(op[0]->type->is_float()); - for (unsigned c = 0; c < op[0]->type->components(); c++) - data.f[c] = tanhf(op[0]->value.f[c]); - } else if (strcmp(callee, "transpose") == 0) { - assert(op[0]->type->is_matrix()); - const unsigned n = op[0]->type->vector_elements; - const unsigned m = op[0]->type->matrix_columns; - for (unsigned j = 0; j < m; j++) { - for (unsigned i = 0; i < n; i++) { - data.f[m*i+j] += op[0]->value.f[i+n*j]; - } - } - } else if (strcmp(callee, "trunc") == 0) { - expr = new(mem_ctx) ir_expression(ir_unop_trunc, op[0]); - } else { - /* Unsupported builtin - some are not allowed in constant expressions. */ - return NULL; - } + /* Now run the builtin function until something non-constant + * happens or we get the result. + */ + if (constant_expression_evaluate_expression_list(origin ? origin->body : body, deref_hash, &result) && result) + result = result->clone(ralloc_parent(this), NULL); - if (expr != NULL) - return expr->constant_expression_value(); + hash_table_dtor(deref_hash); - return new(mem_ctx) ir_constant(type, &data); + return result; } diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp index 24cc64ad9..f15f2d882 100644 --- a/mesalib/src/glsl/standalone_scaffolding.cpp +++ b/mesalib/src/glsl/standalone_scaffolding.cpp @@ -41,6 +41,12 @@ _mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr, *ptr = sh; } +void +_mesa_shader_debug(struct gl_context *, GLenum, GLuint, + const char *, int) +{ +} + struct gl_shader * _mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type) { diff --git a/mesalib/src/glsl/standalone_scaffolding.h b/mesalib/src/glsl/standalone_scaffolding.h index 877332006..41ce35bef 100644 --- a/mesalib/src/glsl/standalone_scaffolding.h +++ b/mesalib/src/glsl/standalone_scaffolding.h @@ -40,6 +40,10 @@ _mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr, extern "C" struct gl_shader * _mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type); +extern "C" void +_mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint id, + const char *msg, int len); + /** * Initialize the given gl_context structure to a reasonable set of * defaults representing the minimum capabilities required by the diff --git a/mesalib/src/mesa/main/api_arrayelt.c b/mesalib/src/mesa/main/api_arrayelt.c index 7bf55f319..6de6de2b7 100644 --- a/mesalib/src/mesa/main/api_arrayelt.c +++ b/mesalib/src/mesa/main/api_arrayelt.c @@ -1643,12 +1643,20 @@ void GLAPIENTRY _ae_ArrayElement( GLint elt ) const struct _glapi_table * const disp = GET_DISPATCH(); GLboolean do_map; + /* If PrimitiveRestart is enabled and the index is the RestartIndex + * then we call PrimitiveRestartNV and return. + */ + if (ctx->Array.PrimitiveRestart && (elt == ctx->Array.RestartIndex)) { + CALL_PrimitiveRestartNV((struct _glapi_table *)disp, ()); + return; + } + if (actx->NewState) { assert(!actx->mapped_vbos); _ae_update_state( ctx ); } - /* Determine if w need to map/unmap VBOs */ + /* Determine if we need to map/unmap VBOs */ do_map = actx->nr_vbos && !actx->mapped_vbos; if (do_map) diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index d75351c85..7e2ac98b9 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -792,6 +792,7 @@ init_attrib_groups(struct gl_context *ctx) /* Miscellaneous */ ctx->NewState = _NEW_ALL; + ctx->NewDriverState = ~0; ctx->ErrorValue = (GLenum) GL_NO_ERROR; ctx->ResetStatus = (GLenum) GL_NO_ERROR; ctx->varying_vp_inputs = VERT_BIT_ALL; @@ -1290,6 +1291,7 @@ _mesa_copy_context( const struct gl_context *src, struct gl_context *dst, /* XXX FIXME: Call callbacks? */ dst->NewState = _NEW_ALL; + dst->NewDriverState = ~0; } #endif diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c index 8cfb97c26..c1c65ea25 100644 --- a/mesalib/src/mesa/main/dlist.c +++ b/mesalib/src/mesa/main/dlist.c @@ -134,7 +134,7 @@ do { \ do { \ if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \ ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \ - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \ + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" ); \ return retval; \ } \ } while (0) @@ -149,7 +149,7 @@ do { \ do { \ if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \ ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \ - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \ + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" ); \ return; \ } \ } while (0) @@ -5673,17 +5673,25 @@ save_Indexfv(const GLfloat * v) static void GLAPIENTRY save_EdgeFlag(GLboolean x) { - save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? (GLfloat)1.0 : (GLfloat)0.0); + save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? 1.0f : 0.0f); } -static inline GLboolean compare4fv( const GLfloat *a, - const GLfloat *b, - GLuint count ) + +/** + * Compare 'count' elements of vectors 'a' and 'b'. + * \return GL_TRUE if equal, GL_FALSE if different. + */ +static inline GLboolean +compare_vec(const GLfloat *a, const GLfloat *b, GLuint count) { return memcmp( a, b, count * sizeof(GLfloat) ) == 0; } - + +/** + * This glMaterial function is used for glMaterial calls that are outside + * a glBegin/End pair. For glMaterial inside glBegin/End, see the VBO code. + */ static void GLAPIENTRY save_Materialfv(GLenum face, GLenum pname, const GLfloat * param) { @@ -5698,7 +5706,7 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param) case GL_FRONT_AND_BACK: break; default: - _mesa_compile_error(ctx, GL_INVALID_ENUM, "material(face)"); + _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(face)"); return; } @@ -5717,7 +5725,7 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param) args = 3; break; default: - _mesa_compile_error(ctx, GL_INVALID_ENUM, "material(pname)"); + _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(pname)"); return; } @@ -5734,7 +5742,8 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param) for (i = 0; i < MAT_ATTRIB_MAX; i++) { if (bitmask & (1 << i)) { if (ctx->ListState.ActiveMaterialSize[i] == args && - compare4fv(ctx->ListState.CurrentMaterial[i], param, args)) { + compare_vec(ctx->ListState.CurrentMaterial[i], param, args)) { + /* no change in material value */ bitmask &= ~(1 << i); } else { @@ -5744,8 +5753,7 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param) } } - /* If this call has effect, return early: - */ + /* If this call has no effect, return early */ if (bitmask == 0) return; diff --git a/mesalib/src/mesa/main/errors.c b/mesalib/src/mesa/main/errors.c index fcf873f18..4a187b7b0 100644 --- a/mesalib/src/mesa/main/errors.c +++ b/mesalib/src/mesa/main/errors.c @@ -1062,4 +1062,47 @@ _mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) (void) fmtString; } + +/** + * Report debug information from the shader compiler via GL_ARB_debug_output. + * + * \param ctx GL context. + * \param type The namespace to which this message belongs. + * \param id The message ID within the given namespace. + * \param msg The message to output. Need not be null-terminated. + * \param len The length of 'msg'. If negative, 'msg' must be null-terminated. + */ +void +_mesa_shader_debug( struct gl_context *ctx, GLenum type, GLuint id, + const char *msg, int len ) +{ + GLenum source = GL_DEBUG_SOURCE_SHADER_COMPILER_ARB, + severity; + + switch (type) { + case GL_DEBUG_TYPE_ERROR_ARB: + assert(id < SHADER_ERROR_COUNT); + severity = GL_DEBUG_SEVERITY_HIGH_ARB; + break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: + case GL_DEBUG_TYPE_PORTABILITY_ARB: + case GL_DEBUG_TYPE_PERFORMANCE_ARB: + case GL_DEBUG_TYPE_OTHER_ARB: + assert(0 && "other categories not implemented yet"); + default: + _mesa_problem(ctx, "bad enum in _mesa_shader_debug()"); + return; + } + + if (len < 0) + len = strlen(msg); + + /* Truncate the message if necessary. */ + if (len >= MAX_DEBUG_MESSAGE_LENGTH) + len = MAX_DEBUG_MESSAGE_LENGTH - 1; + + _mesa_log_msg(ctx, source, type, id, severity, len, msg); +} + /*@}*/ diff --git a/mesalib/src/mesa/main/errors.h b/mesalib/src/mesa/main/errors.h index ed1c6fc7f..b4490fac9 100644 --- a/mesalib/src/mesa/main/errors.h +++ b/mesalib/src/mesa/main/errors.h @@ -68,6 +68,9 @@ _mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... ) extern void _mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) PRINTFLIKE(2, 3); +extern void +_mesa_shader_debug( struct gl_context *ctx, GLenum type, GLuint id, const char *msg, int len ); + #ifdef __cplusplus } #endif diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index 5f2c74a75..a843a4092 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -754,7 +754,7 @@ get_extension_override( struct gl_context *ctx ) /* Remove trailing space. */ len = strlen(extra_exts); - if (extra_exts[len - 1] == ' ') + if (len > 0 && extra_exts[len - 1] == ' ') extra_exts[len - 1] = '\0'; return extra_exts; diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 26ae1087c..f56369483 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -2023,7 +2023,11 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, _glthread_LOCK_MUTEX(fb->Mutex); if (texObj) { if (attachment == GL_DEPTH_ATTACHMENT && - texObj == fb->Attachment[BUFFER_STENCIL].Texture) { + texObj == fb->Attachment[BUFFER_STENCIL].Texture && + level == fb->Attachment[BUFFER_STENCIL].TextureLevel && + _mesa_tex_target_to_face(textarget) == + fb->Attachment[BUFFER_STENCIL].CubeMapFace && + zoffset == fb->Attachment[BUFFER_STENCIL].Zoffset) { /* The texture object is already attached to the stencil attachment * point. Don't create a new renderbuffer; just reuse the stencil * attachment's. This is required to prevent a GL error in @@ -2032,8 +2036,12 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, reuse_framebuffer_texture_attachment(fb, BUFFER_DEPTH, BUFFER_STENCIL); } else if (attachment == GL_STENCIL_ATTACHMENT && - texObj == fb->Attachment[BUFFER_DEPTH].Texture) { - /* As above, but with depth and stencil juxtaposed. */ + texObj == fb->Attachment[BUFFER_DEPTH].Texture && + level == fb->Attachment[BUFFER_DEPTH].TextureLevel && + _mesa_tex_target_to_face(textarget) == + fb->Attachment[BUFFER_DEPTH].CubeMapFace && + zoffset == fb->Attachment[BUFFER_DEPTH].Zoffset) { + /* As above, but with depth and stencil transposed. */ reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL, BUFFER_DEPTH); } else { diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 2b709ded6..06ca0d5df 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1636,6 +1636,11 @@ struct gl_array_attrib /* GL_ARB_vertex_buffer_object */ struct gl_buffer_object *ArrayBufferObj; + + /** + * Vertex arrays as consumed by a driver. + * The array pointer is set up only by the VBO module. */ + const struct gl_client_array **_DrawArrays; /**< 0..VERT_ATTRIB_MAX-1 */ }; @@ -3252,6 +3257,17 @@ typedef enum API_OPENGLES2 } gl_api; +/** + * Driver-specific state flags. + * + * These are or'd with gl_context::NewDriverState to notify a driver about + * a state change. The driver sets the flags at context creation and + * the meaning of the bits set is opaque to core Mesa. + */ +struct gl_driver_flags +{ + GLbitfield NewArray; /**< Vertex array state */ +}; /** * Mesa rendering context. @@ -3411,6 +3427,9 @@ struct gl_context GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */ GLbitfield NewState; /**< bitwise-or of _NEW_* flags */ + GLbitfield NewDriverState;/**< bitwise-or of flags from DriverFlags */ + + struct gl_driver_flags DriverFlags; GLboolean ViewportInitialized; /**< has viewport size been initialized? */ diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 50095d2c6..694f6fa00 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -531,6 +531,32 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) /** + * Is the given texture format a generic compressed format? + */ +static GLboolean +is_generic_compressed_format(GLenum format) +{ + switch (format) { + case GL_COMPRESSED_RED: + case GL_COMPRESSED_RG: + case GL_COMPRESSED_RGB: + case GL_COMPRESSED_RGBA: + case GL_COMPRESSED_ALPHA: + case GL_COMPRESSED_LUMINANCE: + case GL_COMPRESSED_LUMINANCE_ALPHA: + case GL_COMPRESSED_INTENSITY: + case GL_COMPRESSED_SRGB: + case GL_COMPRESSED_SRGB_ALPHA: + case GL_COMPRESSED_SLUMINANCE: + case GL_COMPRESSED_SLUMINANCE_ALPHA: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/** * For cube map faces, return a face index in [0,5]. * For other targets return 0; */ @@ -1705,7 +1731,8 @@ texture_error_check( struct gl_context *ctx, } /* additional checks for compressed textures */ - if (_mesa_is_compressed_format(ctx, internalFormat)) { + if (_mesa_is_compressed_format(ctx, internalFormat) || + is_generic_compressed_format(internalFormat)) { if (!target_can_be_compressed(ctx, target, internalFormat)) { if (!isProxy) _mesa_error(ctx, GL_INVALID_ENUM, @@ -2036,7 +2063,8 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, return GL_TRUE; } - if (_mesa_is_compressed_format(ctx, internalFormat)) { + if (_mesa_is_compressed_format(ctx, internalFormat) || + is_generic_compressed_format(internalFormat)) { if (!target_can_be_compressed(ctx, target, internalFormat)) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%dD(target)", dimensions); diff --git a/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c b/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c index 2c21dc9a7..8337f4624 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/mesalib/src/mesa/state_tracker/st_cb_rasterpos.c @@ -225,6 +225,7 @@ st_RasterPos(struct gl_context *ctx, const GLfloat v[4]) struct st_context *st = st_context(ctx); struct draw_context *draw = st->draw; struct rastpos_stage *rs; + const struct gl_client_array **saved_arrays = ctx->Array._DrawArrays; if (st->rastpos_stage) { /* get rastpos stage info */ @@ -250,9 +251,14 @@ st_RasterPos(struct gl_context *ctx, const GLfloat v[4]) */ rs->array[0].Ptr = (GLubyte *) v; - /* draw the point */ - st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1, + /* Draw the point. + * + * Don't set DriverFlags.NewArray. + * st_feedback_draw_vbo doesn't check for that flag. */ + ctx->Array._DrawArrays = rs->arrays; + st_feedback_draw_vbo(ctx, &rs->prim, 1, NULL, GL_TRUE, 0, 1, NULL); + ctx->Array._DrawArrays = saved_arrays; /* restore draw's rasterization stage depending on rendermode */ if (ctx->RenderMode == GL_FEEDBACK) { diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c index 19d9da131..ce7dbb3f3 100644 --- a/mesalib/src/mesa/state_tracker/st_context.c +++ b/mesalib/src/mesa/state_tracker/st_context.c @@ -203,6 +203,10 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe ) return st; } +static void st_init_driver_flags(struct gl_driver_flags *f) +{ + f->NewArray = ST_NEW_VERTEX_ARRAYS; +} struct st_context *st_create_context(gl_api api, struct pipe_context *pipe, const struct gl_config *visual, @@ -225,6 +229,8 @@ struct st_context *st_create_context(gl_api api, struct pipe_context *pipe, return NULL; } + st_init_driver_flags(&ctx->DriverFlags); + /* XXX: need a capability bit in gallium to query if the pipe * driver prefers DP4 or MUL/MAD for vertex transformation. */ diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index 3ec98ada1..4786ed22f 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -50,6 +50,7 @@ struct u_vbuf; #define ST_NEW_FRAMEBUFFER (1 << 3) #define ST_NEW_EDGEFLAGS_DATA (1 << 4) #define ST_NEW_GEOMETRY_PROGRAM (1 << 5) +#define ST_NEW_VERTEX_ARRAYS (1 << 6) struct st_state_flags { diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c index edab76bf5..42dc37576 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.c +++ b/mesalib/src/mesa/state_tracker/st_draw.c @@ -966,7 +966,6 @@ st_validate_varrays(struct gl_context *ctx, */ void st_draw_vbo(struct gl_context *ctx, - const struct gl_client_array **arrays, const struct _mesa_prim *prims, GLuint nr_prims, const struct _mesa_index_buffer *ib, @@ -979,15 +978,22 @@ st_draw_vbo(struct gl_context *ctx, struct pipe_context *pipe = st->pipe; struct pipe_index_buffer ibuffer; struct pipe_draw_info info; + const struct gl_client_array **arrays = ctx->Array._DrawArrays; unsigned i, num_instances = 1; unsigned max_index_plus_base; - GLboolean new_array = - st->dirty.st && - (st->dirty.mesa & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0; + GLboolean new_array; /* Mesa core state should have been validated already */ assert(ctx->NewState == 0x0); + /* Get Mesa driver state. */ + st->dirty.st |= ctx->NewDriverState; + ctx->NewDriverState = 0; + + new_array = + (st->dirty.st & (ST_NEW_VERTEX_ARRAYS | ST_NEW_VERTEX_PROGRAM)) || + (st->dirty.mesa & (_NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0; + if (ib) { int max_base_vertex = 0; diff --git a/mesalib/src/mesa/state_tracker/st_draw.h b/mesalib/src/mesa/state_tracker/st_draw.h index 47bdb11f8..c608051eb 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.h +++ b/mesalib/src/mesa/state_tracker/st_draw.h @@ -49,7 +49,6 @@ void st_destroy_draw( struct st_context *st ); extern void st_draw_vbo(struct gl_context *ctx, - const struct gl_client_array **arrays, const struct _mesa_prim *prims, GLuint nr_prims, const struct _mesa_index_buffer *ib, @@ -60,7 +59,6 @@ st_draw_vbo(struct gl_context *ctx, extern void st_feedback_draw_vbo(struct gl_context *ctx, - const struct gl_client_array **arrays, const struct _mesa_prim *prims, GLuint nr_prims, const struct _mesa_index_buffer *ib, diff --git a/mesalib/src/mesa/state_tracker/st_draw_feedback.c b/mesalib/src/mesa/state_tracker/st_draw_feedback.c index a559b733a..257618aa9 100644 --- a/mesalib/src/mesa/state_tracker/st_draw_feedback.c +++ b/mesalib/src/mesa/state_tracker/st_draw_feedback.c @@ -91,7 +91,6 @@ set_feedback_vertex_format(struct gl_context *ctx) */ void st_feedback_draw_vbo(struct gl_context *ctx, - const struct gl_client_array **arrays, const struct _mesa_prim *prims, GLuint nr_prims, const struct _mesa_index_buffer *ib, @@ -110,6 +109,7 @@ st_feedback_draw_vbo(struct gl_context *ctx, struct pipe_index_buffer ibuffer; struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; struct pipe_transfer *ib_transfer = NULL; + const struct gl_client_array **arrays = ctx->Array._DrawArrays; GLuint attr, i; const GLubyte *low_addr = NULL; const void *mapped_indices = NULL; diff --git a/mesalib/src/mesa/tnl/t_draw.c b/mesalib/src/mesa/tnl/t_draw.c index 17042cf8f..6a3c9662e 100644 --- a/mesalib/src/mesa/tnl/t_draw.c +++ b/mesalib/src/mesa/tnl/t_draw.c @@ -408,7 +408,6 @@ static void unmap_vbos( struct gl_context *ctx, void _tnl_vbo_draw_prims(struct gl_context *ctx, - const struct gl_client_array *arrays[], const struct _mesa_prim *prim, GLuint nr_prims, const struct _mesa_index_buffer *ib, @@ -417,6 +416,8 @@ void _tnl_vbo_draw_prims(struct gl_context *ctx, GLuint max_index, struct gl_transform_feedback_object *tfb_vertcount) { + const struct gl_client_array **arrays = ctx->Array._DrawArrays; + if (!index_bounds_valid) vbo_get_minmax_indices(ctx, prim, ib, &min_index, &max_index, nr_prims); diff --git a/mesalib/src/mesa/tnl/tnl.h b/mesalib/src/mesa/tnl/tnl.h index 434bd7fcd..f6b70e323 100644 --- a/mesalib/src/mesa/tnl/tnl.h +++ b/mesalib/src/mesa/tnl/tnl.h @@ -86,7 +86,6 @@ _tnl_draw_prims( struct gl_context *ctx, void _tnl_vbo_draw_prims( struct gl_context *ctx, - const struct gl_client_array *arrays[], const struct _mesa_prim *prim, GLuint nr_prims, const struct _mesa_index_buffer *ib, diff --git a/mesalib/src/mesa/vbo/vbo.h b/mesalib/src/mesa/vbo/vbo.h index 2d01d9823..3cff8987e 100644 --- a/mesalib/src/mesa/vbo/vbo.h +++ b/mesalib/src/mesa/vbo/vbo.h @@ -72,7 +72,6 @@ void _vbo_InvalidateState( struct gl_context *ctx, GLuint new_state ); typedef void (*vbo_draw_func)( struct gl_context *ctx, - const struct gl_client_array **arrays, const struct _mesa_prim *prims, GLuint nr_prims, const struct _mesa_index_buffer *ib, diff --git a/mesalib/src/mesa/vbo/vbo_context.h b/mesalib/src/mesa/vbo/vbo_context.h index b9a8affa5..1c49de0ca 100644 --- a/mesalib/src/mesa/vbo/vbo_context.h +++ b/mesalib/src/mesa/vbo/vbo_context.h @@ -58,6 +58,18 @@ #include "vbo_save.h" +/** Used to signal when transitioning from one kind of drawing method + * to another. + */ +enum draw_method +{ + DRAW_NONE, /**< Initial value only */ + DRAW_BEGIN_END, + DRAW_DISPLAY_LIST, + DRAW_ARRAYS +}; + + struct vbo_context { struct gl_client_array currval[VBO_ATTRIB_MAX]; @@ -74,6 +86,8 @@ struct vbo_context { * is responsible for initiating any fallback actions required: */ vbo_draw_func draw_prims; + + enum draw_method last_draw_method; }; @@ -101,4 +115,40 @@ get_program_mode( struct gl_context *ctx ) } +/** + * This is called by glBegin, glDrawArrays and glDrawElements (and + * variations of those calls). When we transition from immediate mode + * drawing to array drawing we need to invalidate the array state. + * + * glBegin/End builds vertex arrays. Those arrays may look identical + * to glDrawArrays arrays except that the position of the elements may + * be different. For example, arrays of (position3v, normal3f) vs. arrays + * of (normal3f, position3f). So we need to make sure we notify drivers + * that arrays may be changing. + */ +static inline void +vbo_draw_method(struct vbo_context *vbo, enum draw_method method) +{ + if (vbo->last_draw_method != method) { + struct gl_context *ctx = vbo->exec.ctx; + + switch (method) { + case DRAW_ARRAYS: + ctx->Array._DrawArrays = vbo->exec.array.inputs; + break; + case DRAW_BEGIN_END: + ctx->Array._DrawArrays = vbo->exec.vtx.inputs; + break; + case DRAW_DISPLAY_LIST: + ctx->Array._DrawArrays = vbo->save.inputs; + break; + default: + ASSERT(0); + } + + ctx->NewDriverState |= ctx->DriverFlags.NewArray; + vbo->last_draw_method = method; + } +} + #endif diff --git a/mesalib/src/mesa/vbo/vbo_exec.h b/mesalib/src/mesa/vbo/vbo_exec.h index be9f3d78d..4ac7d168d 100644 --- a/mesalib/src/mesa/vbo/vbo_exec.h +++ b/mesalib/src/mesa/vbo/vbo_exec.h @@ -78,26 +78,12 @@ struct vbo_exec_copied_vtx { }; -/** Used to signal when transitioning from one kind of drawing method - * to another. - */ -enum draw_method -{ - DRAW_NONE, /**< Initial value only */ - DRAW_BEGIN_END, - DRAW_DISPLAY_LIST, - DRAW_ARRAYS -}; - - struct vbo_exec_context { struct gl_context *ctx; GLvertexformat vtxfmt; GLvertexformat vtxfmt_noop; - enum draw_method last_draw_method; - struct { struct gl_buffer_object *bufferobj; @@ -174,28 +160,6 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec ); void vbo_exec_vtx_destroy( struct vbo_exec_context *exec ); -/** - * This is called by glBegin, glDrawArrays and glDrawElements (and - * variations of those calls). When we transition from immediate mode - * drawing to array drawing we need to invalidate the array state. - * - * glBegin/End builds vertex arrays. Those arrays may look identical - * to glDrawArrays arrays except that the position of the elements may - * be different. For example, arrays of (position3v, normal3f) vs. arrays - * of (normal3f, position3f). So we need to make sure we notify drivers - * that arrays may be changing. - */ -static inline void -vbo_draw_method(struct vbo_exec_context *exec, enum draw_method method) -{ - if (exec->last_draw_method != method) { - struct gl_context *ctx = exec->ctx; - ctx->Driver.UpdateState(ctx, _NEW_ARRAY); - exec->last_draw_method = method; - } -} - - #if FEATURE_beginend void vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap ); diff --git a/mesalib/src/mesa/vbo/vbo_exec_api.c b/mesalib/src/mesa/vbo/vbo_exec_api.c index 3f9541089..b87da18f3 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_api.c +++ b/mesalib/src/mesa/vbo/vbo_exec_api.c @@ -700,7 +700,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) return; } - vbo_draw_method(exec, DRAW_BEGIN_END); + vbo_draw_method(vbo_context(ctx), DRAW_BEGIN_END); if (ctx->Driver.PrepareExecBegin) ctx->Driver.PrepareExecBegin(ctx); diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c index 2dcfb8e5b..cc94e761b 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_array.c +++ b/mesalib/src/mesa/vbo/vbo_exec_array.c @@ -506,7 +506,7 @@ recalculate_input_bindings(struct gl_context *ctx) } _mesa_set_varying_vp_inputs( ctx, VERT_BIT_ALL & (~const_inputs) ); - ctx->Driver.UpdateState(ctx, _NEW_ARRAY); + ctx->NewDriverState |= ctx->DriverFlags.NewArray; } @@ -523,7 +523,7 @@ vbo_bind_arrays(struct gl_context *ctx) struct vbo_context *vbo = vbo_context(ctx); struct vbo_exec_context *exec = &vbo->exec; - vbo_draw_method(exec, DRAW_ARRAYS); + vbo_draw_method(vbo, DRAW_ARRAYS); if (exec->array.recalculate_inputs) { recalculate_input_bindings(ctx); @@ -600,7 +600,7 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, if (primCount > 0) { /* draw one or two prims */ check_buffers_are_unmapped(exec->array.inputs); - vbo->draw_prims(ctx, exec->array.inputs, prim, primCount, NULL, + vbo->draw_prims(ctx, prim, primCount, NULL, GL_TRUE, start, start + count - 1, NULL); } } @@ -610,7 +610,7 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, prim[0].count = count; check_buffers_are_unmapped(exec->array.inputs); - vbo->draw_prims(ctx, exec->array.inputs, prim, 1, NULL, + vbo->draw_prims(ctx, prim, 1, NULL, GL_TRUE, start, start + count - 1, NULL); } @@ -801,7 +801,7 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, */ check_buffers_are_unmapped(exec->array.inputs); - vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, + vbo->draw_prims( ctx, prim, 1, &ib, index_bounds_valid, start, end, NULL ); } @@ -1096,7 +1096,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, } check_buffers_are_unmapped(exec->array.inputs); - vbo->draw_prims(ctx, exec->array.inputs, prim, primcount, &ib, + vbo->draw_prims(ctx, prim, primcount, &ib, GL_FALSE, ~0, ~0, NULL); } else { /* render one prim at a time */ @@ -1121,7 +1121,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, prim[0].basevertex = 0; check_buffers_are_unmapped(exec->array.inputs); - vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib, + vbo->draw_prims(ctx, prim, 1, &ib, GL_FALSE, ~0, ~0, NULL); } } @@ -1199,7 +1199,7 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode, * will be rendered. */ check_buffers_are_unmapped(exec->array.inputs); - vbo->draw_prims(ctx, exec->array.inputs, prim, 1, NULL, + vbo->draw_prims(ctx, prim, 1, NULL, GL_TRUE, 0, 0, obj); } diff --git a/mesalib/src/mesa/vbo/vbo_exec_draw.c b/mesalib/src/mesa/vbo/vbo_exec_draw.c index da5ca695e..77db8ec7f 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_draw.c +++ b/mesalib/src/mesa/vbo/vbo_exec_draw.c @@ -257,7 +257,7 @@ vbo_exec_bind_arrays( struct gl_context *ctx ) } _mesa_set_varying_vp_inputs( ctx, varying_inputs ); - ctx->Driver.UpdateState(ctx, _NEW_ARRAY); + ctx->NewDriverState |= ctx->DriverFlags.NewArray; } @@ -407,8 +407,7 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped) exec->vtx.vert_count); vbo_context(ctx)->draw_prims( ctx, - exec->vtx.inputs, - exec->vtx.prim, + exec->vtx.prim, exec->vtx.prim_count, NULL, GL_TRUE, diff --git a/mesalib/src/mesa/vbo/vbo_rebase.c b/mesalib/src/mesa/vbo/vbo_rebase.c index 597a8f469..fff9df0c2 100644 --- a/mesalib/src/mesa/vbo/vbo_rebase.c +++ b/mesalib/src/mesa/vbo/vbo_rebase.c @@ -129,6 +129,7 @@ void vbo_rebase_prims( struct gl_context *ctx, struct _mesa_index_buffer tmp_ib; struct _mesa_prim *tmp_prims = NULL; + const struct gl_client_array **saved_arrays = ctx->Array._DrawArrays; void *tmp_indices = NULL; GLuint i; @@ -226,15 +227,20 @@ void vbo_rebase_prims( struct gl_context *ctx, /* Re-issue the draw call. */ + ctx->Array._DrawArrays = tmp_array_pointers; + ctx->NewDriverState |= ctx->DriverFlags.NewArray; + draw( ctx, - tmp_array_pointers, - prim, + prim, nr_prims, ib, GL_TRUE, 0, max_index - min_index, NULL ); + + ctx->Array._DrawArrays = saved_arrays; + ctx->NewDriverState |= ctx->DriverFlags.NewArray; if (tmp_indices) free(tmp_indices); diff --git a/mesalib/src/mesa/vbo/vbo_save.c b/mesalib/src/mesa/vbo/vbo_save.c index 040c9b7a9..7a97d3c65 100644 --- a/mesalib/src/mesa/vbo/vbo_save.c +++ b/mesalib/src/mesa/vbo/vbo_save.c @@ -49,6 +49,9 @@ static void vbo_save_callback_init( struct gl_context *ctx ) +/** + * Called at context creation time. + */ void vbo_save_init( struct gl_context *ctx ) { struct vbo_context *vbo = vbo_context(ctx); diff --git a/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c index 13604333e..74f5dc9ce 100644 --- a/mesalib/src/mesa/vbo/vbo_save_api.c +++ b/mesalib/src/mesa/vbo/vbo_save_api.c @@ -1506,6 +1506,9 @@ vbo_print_vertex_list(struct gl_context *ctx, void *data) } +/** + * Called during context creation/init. + */ static void _save_current_init(struct gl_context *ctx) { @@ -1529,7 +1532,7 @@ _save_current_init(struct gl_context *ctx) /** - * Initialize the display list compiler + * Initialize the display list compiler. Called during context creation. */ void vbo_save_api_init(struct vbo_save_context *save) diff --git a/mesalib/src/mesa/vbo/vbo_save_draw.c b/mesalib/src/mesa/vbo/vbo_save_draw.c index 88a9a7e34..c6425ab1b 100644 --- a/mesalib/src/mesa/vbo/vbo_save_draw.c +++ b/mesalib/src/mesa/vbo/vbo_save_draw.c @@ -213,7 +213,7 @@ static void vbo_bind_vertex_list(struct gl_context *ctx, } _mesa_set_varying_vp_inputs( ctx, varying_inputs ); - ctx->Driver.UpdateState(ctx, _NEW_ARRAY); + ctx->NewDriverState |= ctx->DriverFlags.NewArray; } @@ -250,7 +250,6 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data) const struct vbo_save_vertex_list *node = (const struct vbo_save_vertex_list *) data; struct vbo_save_context *save = &vbo_context(ctx)->save; - struct vbo_exec_context *exec = &vbo_context(ctx)->exec; GLboolean remap_vertex_store = GL_FALSE; if (save->vertex_store->buffer) { @@ -304,7 +303,7 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data) vbo_bind_vertex_list( ctx, node ); - vbo_draw_method(exec, DRAW_DISPLAY_LIST); + vbo_draw_method(vbo_context(ctx), DRAW_DISPLAY_LIST); /* Again... */ @@ -313,8 +312,7 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data) if (node->count > 0) { vbo_context(ctx)->draw_prims(ctx, - save->inputs, - node->prim, + node->prim, node->prim_count, NULL, GL_TRUE, diff --git a/mesalib/src/mesa/vbo/vbo_split_copy.c b/mesalib/src/mesa/vbo/vbo_split_copy.c index b53293c31..528fcfd7f 100644 --- a/mesalib/src/mesa/vbo/vbo_split_copy.c +++ b/mesalib/src/mesa/vbo/vbo_split_copy.c @@ -171,6 +171,8 @@ dump_draw_info(struct gl_context *ctx, static void flush( struct copy_context *copy ) { + struct gl_context *ctx = copy->ctx; + const struct gl_client_array **saved_arrays = ctx->Array._DrawArrays; GLuint i; /* Set some counters: @@ -189,8 +191,10 @@ flush( struct copy_context *copy ) (void) dump_draw_info; #endif - copy->draw( copy->ctx, - copy->dstarray_ptr, + ctx->Array._DrawArrays = copy->dstarray_ptr; + ctx->NewDriverState |= ctx->DriverFlags.NewArray; + + copy->draw( ctx, copy->dstprim, copy->dstprim_nr, ©->dstib, @@ -199,6 +203,9 @@ flush( struct copy_context *copy ) copy->dstbuf_nr - 1, NULL ); + ctx->Array._DrawArrays = saved_arrays; + ctx->NewDriverState |= ctx->DriverFlags.NewArray; + /* Reset all pointers: */ copy->dstprim_nr = 0; diff --git a/mesalib/src/mesa/vbo/vbo_split_inplace.c b/mesalib/src/mesa/vbo/vbo_split_inplace.c index 9e596f668..00464049d 100644 --- a/mesalib/src/mesa/vbo/vbo_split_inplace.c +++ b/mesalib/src/mesa/vbo/vbo_split_inplace.c @@ -62,6 +62,8 @@ struct split_context { static void flush_vertex( struct split_context *split ) { + struct gl_context *ctx = split->ctx; + const struct gl_client_array **saved_arrays = ctx->Array._DrawArrays; struct _mesa_index_buffer ib; GLuint i; @@ -82,8 +84,10 @@ static void flush_vertex( struct split_context *split ) assert(split->max_index >= split->min_index); - split->draw(split->ctx, - split->array, + ctx->Array._DrawArrays = split->array; + ctx->NewDriverState |= ctx->DriverFlags.NewArray; + + split->draw(ctx, split->dstprim, split->dstprim_nr, split->ib ? &ib : NULL, @@ -92,6 +96,9 @@ static void flush_vertex( struct split_context *split ) split->max_index, NULL); + ctx->Array._DrawArrays = saved_arrays; + ctx->NewDriverState |= ctx->DriverFlags.NewArray; + split->dstprim_nr = 0; split->min_index = ~0; split->max_index = 0; diff --git a/xorg-server/Xi/xiquerypointer.c b/xorg-server/Xi/xiquerypointer.c index a2e7442e0..169436e14 100644 --- a/xorg-server/Xi/xiquerypointer.c +++ b/xorg-server/Xi/xiquerypointer.c @@ -79,10 +79,21 @@ ProcXIQueryPointer(ClientPtr client) XkbStatePtr state; char *buttons = NULL; int buttons_size = 0; /* size of buttons array */ + XIClientPtr xi_client; + Bool have_xi22 = FALSE; REQUEST(xXIQueryPointerReq); REQUEST_SIZE_MATCH(xXIQueryPointerReq); + /* Check if client is compliant with XInput 2.2 or later. Earlier clients + * do not know about touches, so we must report emulated button presses. 2.2 + * and later clients are aware of touches, so we don't include emulated + * button presses in the reply. */ + xi_client = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey); + if (version_compare(xi_client->major_version, + xi_client->minor_version, 2, 2) >= 0) + have_xi22 = TRUE; + rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess); if (rc != Success) { client->errorValue = stuff->deviceid; @@ -132,7 +143,7 @@ ProcXIQueryPointer(ClientPtr client) } if (pDev->button) { - int i, down; + int i; rep.buttons_len = bytes_to_int32(bits_to_bytes(pDev->button->numButtons)); @@ -142,14 +153,12 @@ ProcXIQueryPointer(ClientPtr client) if (!buttons) return BadAlloc; - down = pDev->button->buttonsDown; + for (i = 1; i < pDev->button->numButtons; i++) + if (BitIsOn(pDev->button->down, i)) + SetBit(buttons, pDev->button->map[i]); - for (i = 0; i < pDev->button->numButtons && down; i++) { - if (BitIsOn(pDev->button->down, i)) { - SetBit(buttons, i); - down--; - } - } + if (!have_xi22 && pDev->touch && pDev->touch->buttonsDown > 0) + SetBit(buttons, pDev->button->map[1]); } else rep.buttons_len = 0; diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 4afac8268..97ceab1b8 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -271,10 +271,11 @@ AC_CACHE_CHECK([for SYSV IPC], #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> +#include <sys/stat.h> ],[ { int id; - id = shmget(IPC_PRIVATE, 512, SHM_W | SHM_R); + id = shmget(IPC_PRIVATE, 512, S_IRUSR | S_IWUSR); if (id < 0) return -1; return shmctl(id, IPC_RMID, 0); }], @@ -592,7 +593,7 @@ AC_ARG_WITH(khronos-spec-dir, AS_HELP_STRING([--with-khronos-spec-dir=PATH], [Pa dnl Extensions. AC_ARG_ENABLE(registry, AS_HELP_STRING([--disable-registry], [Build string registry module (default: enabled)]), [XREGISTRY=$enableval], [XREGISTRY=yes]) AC_ARG_ENABLE(composite, AS_HELP_STRING([--disable-composite], [Build Composite extension (default: enabled)]), [COMPOSITE=$enableval], [COMPOSITE=yes]) -AC_ARG_ENABLE(mitshm, AS_HELP_STRING([--disable-mitshm], [Build SHM extension (default: enabled)]), [MITSHM=$enableval], [MITSHM=yes]) +AC_ARG_ENABLE(mitshm, AS_HELP_STRING([--disable-mitshm], [Build SHM extension (default: auto)]), [MITSHM=$enableval], [MITSHM=auto]) AC_ARG_ENABLE(xres, AS_HELP_STRING([--disable-xres], [Build XRes extension (default: enabled)]), [RES=$enableval], [RES=yes]) AC_ARG_ENABLE(record, AS_HELP_STRING([--disable-record], [Build Record extension (default: enabled)]), [RECORD=$enableval], [RECORD=yes]) AC_ARG_ENABLE(xv, AS_HELP_STRING([--disable-xv], [Build Xv extension (default: enabled)]), [XV=$enableval], [XV=yes]) @@ -656,6 +657,7 @@ AC_MSG_CHECKING([to see if we can install the Xorg server as root]) if test "x$SETUID" = "xauto" ; then case $host_os in cygwin*) SETUID="no" ;; + mingw*) SETUID="no" ;; darwin*) SETUID="no" ;; *) case $host_cpu in @@ -698,7 +700,7 @@ AM_CONDITIONAL(INSTALL_LIBXF86CONFIG, [test "x$INSTALL_LIBXF86CONFIG" = xyes]) dnl DDX Detection... Yes, it's ugly to have it here... but we need to dnl handle this early on so that we don't require unsupported extensions case $host_os in - cygwin*) + cygwin* | mingw*) CONFIG_DBUS_API=no CONFIG_HAL=no CONFIG_UDEV=no @@ -1000,6 +1002,9 @@ if test "x$COMPOSITE" = xyes; then COMPOSITE_INC='-I$(top_srcdir)/composite' fi +if test "x$MITSHM" = xauto; then + MITSHM="$ac_cv_sysv_ipc" +fi AM_CONDITIONAL(MITSHM, [test "x$MITSHM" = xyes]) if test "x$MITSHM" = xyes; then AC_DEFINE(MITSHM, 1, [Support MIT-SHM extension]) @@ -1350,7 +1355,7 @@ CORE_INCS='-I$(top_srcdir)/include -I$(top_builddir)/include' # SHA1 hashing AC_ARG_WITH([sha1], - [AS_HELP_STRING([--with-sha1=libc|libmd|libgcrypt|libcrypto|libsha1|CommonCrypto], + [AS_HELP_STRING([--with-sha1=libc|libmd|libgcrypt|libcrypto|libsha1|CommonCrypto|CryptoAPI], [choose SHA1 implementation])]) AC_CHECK_FUNC([SHA1Init], [HAVE_SHA1_IN_LIBC=yes]) if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_LIBC" = xyes; then @@ -1376,6 +1381,19 @@ if test "x$with_sha1" = xCommonCrypto; then [Use CommonCrypto SHA1 functions]) SHA1_LIBS="" fi +dnl stdcall functions cannot be tested with AC_CHECK_LIB +AC_CHECK_HEADER([wincrypt.h], [HAVE_SHA1_IN_CRYPTOAPI=yes], [], [#include <windows.h>]) +if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_CRYPTOAPI" = xyes; then + with_sha1=CryptoAPI +fi +if test "x$with_sha1" = xCryptoAPI && test "x$HAVE_SHA1_IN_CRYPTOAPI" != xyes; then + AC_MSG_ERROR([CryptoAPI requested but not found]) +fi +if test "x$with_sha1" = xCryptoAPI; then + AC_DEFINE([HAVE_SHA1_IN_CRYPTOAPI], [1], + [Use CryptoAPI SHA1 functions]) + SHA1_LIBS="" +fi AC_CHECK_LIB([md], [SHA1Init], [HAVE_LIBMD=yes]) if test "x$with_sha1" = x && test "x$HAVE_LIBMD" = xyes; then with_sha1=libmd @@ -1547,6 +1565,7 @@ if test "x$XORG" = xauto; then XORG="yes" case $host_os in cygwin*) XORG="no" ;; + mingw*) XORG="no" ;; darwin*) XORG="no" ;; esac fi @@ -1857,7 +1876,7 @@ if test "x$XWIN" = xyes; then XWIN_SERVER_NAME=Xming AC_DEFINE(RELOCATE_PROJECTROOT,1,[Make PROJECT_ROOT relative to the xserver location]) AC_DEFINE(HAS_WINSOCK,1,[Use Windows sockets]) - XWIN_SYS_LIBS=-lwinsock2 + XWIN_SYS_LIBS=-lws2_32 ;; esac XWIN_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $RANDR_LIB $RENDER_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $OS_LIB" @@ -1948,6 +1967,7 @@ if test "x$DMX" = xauto; then DMX="$have_dmx" case $host_os in cygwin*) DMX="no" ;; + mingw*) DMX="no" ;; darwin*) DMX="no" ;; esac fi diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am index d61c6401b..e50cb88c2 100644 --- a/xorg-server/hw/xfree86/Makefile.am +++ b/xorg-server/hw/xfree86/Makefile.am @@ -106,13 +106,13 @@ xorg.conf.example: xorgconf.cpp $(AM_V_GEN)$(SED) $(CONF_SUBSTS) < $(srcdir)/xorgconf.cpp > $@ relink: - $(AM_V_at)rm -f Xorg && $(MAKE) Xorg + $(AM_V_at)rm -f Xorg$(EXEEXT) && $(MAKE) Xorg$(EXEEXT) CLEANFILES = sdksyms.c sdksyms.dep EXTRA_DIST += sdksyms.sh sdksyms.dep sdksyms.c: sdksyms.sh - CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $(srcdir)/sdksyms.sh $(top_srcdir) $(CFLAGS) $(AM_CFLAGS) $(INCLUDES) + $(AM_V_GEN)CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $(srcdir)/sdksyms.sh $(top_srcdir) $(CFLAGS) $(AM_CFLAGS) $(INCLUDES) SDKSYMS_DEP = sdksyms.dep include $(SDKSYMS_DEP) diff --git a/xorg-server/hw/xwin/glx/Makefile.am b/xorg-server/hw/xwin/glx/Makefile.am index 6b840bacb..7222a9f21 100644 --- a/xorg-server/hw/xwin/glx/Makefile.am +++ b/xorg-server/hw/xwin/glx/Makefile.am @@ -32,10 +32,10 @@ AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \ if XWIN_GLX_WINDOWS generated_gl_wrappers.c: gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/gl.spec $(KHRONOS_SPEC_DIR)/gl.tm - $(srcdir)/gen_gl_wrappers.py --spec=$(KHRONOS_SPEC_DIR)/gl.spec --typemap=$(KHRONOS_SPEC_DIR)/gl.tm --dispatch-header=$(top_srcdir)/glx/dispatch.h --staticwrappers >generated_gl_wrappers.c + $(AM_V_GEN)$(srcdir)/gen_gl_wrappers.py --spec=$(KHRONOS_SPEC_DIR)/gl.spec --typemap=$(KHRONOS_SPEC_DIR)/gl.tm --dispatch-header=$(top_srcdir)/glx/dispatch.h --staticwrappers >generated_gl_wrappers.c generated_wgl_wrappers.c: gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/wglext.spec $(KHRONOS_SPEC_DIR)/wgl.tm - $(srcdir)/gen_gl_wrappers.py --spec=$(KHRONOS_SPEC_DIR)/wglext.spec --typemap=$(KHRONOS_SPEC_DIR)/wgl.tm --prefix=wgl --preresolve >generated_wgl_wrappers.c + $(AM_V_GEN)$(srcdir)/gen_gl_wrappers.py --spec=$(KHRONOS_SPEC_DIR)/wglext.spec --typemap=$(KHRONOS_SPEC_DIR)/wgl.tm --prefix=wgl --preresolve >generated_wgl_wrappers.c endif BUILT_SOURCES = generated_gl_wrappers.c generated_wgl_wrappers.c diff --git a/xorg-server/include/dix-config.h.in b/xorg-server/include/dix-config.h.in index 3fb641367..3c9bbafeb 100644 --- a/xorg-server/include/dix-config.h.in +++ b/xorg-server/include/dix-config.h.in @@ -148,6 +148,9 @@ /* Define to use CommonCrypto SHA1 functions */ #undef HAVE_SHA1_IN_COMMONCRYPTO +/* Define to use CryptoAPI SHA1 functions */ +#undef HAVE_SHA1_IN_CRYPTOAPI + /* Define to use libmd SHA1 functions */ #undef HAVE_SHA1_IN_LIBMD diff --git a/xorg-server/os/xsha1.c b/xorg-server/os/xsha1.c index dccce74b6..fa66c7a06 100644 --- a/xorg-server/os/xsha1.c +++ b/xorg-server/os/xsha1.c @@ -74,6 +74,48 @@ x_sha1_final(void *ctx, unsigned char result[20]) return 1; } +#elif defined(HAVE_SHA1_IN_CRYPTOAPI) /* Use CryptoAPI for SHA1 */ + +#define WIN32_LEAN_AND_MEAN +#include <X11/Xwindows.h> +#include <wincrypt.h> + +static HCRYPTPROV hProv; + +void * +x_sha1_init(void) +{ + HCRYPTHASH *ctx = malloc(sizeof(*ctx)); + + if (!ctx) + return NULL; + CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + CryptCreateHash(hProv, CALG_SHA1, 0, 0, ctx); + return ctx; +} + +int +x_sha1_update(void *ctx, void *data, int size) +{ + HCRYPTHASH *hHash = ctx; + + CryptHashData(*hHash, data, size, 0); + return 1; +} + +int +x_sha1_final(void *ctx, unsigned char result[20]) +{ + HCRYPTHASH *hHash = ctx; + DWORD len = 20; + + CryptGetHashParam(*hHash, HP_HASHVAL, result, &len, 0); + CryptDestroyHash(*hHash); + CryptReleaseContext(hProv, 0); + free(ctx); + return 1; +} + #elif defined(HAVE_SHA1_IN_LIBGCRYPT) /* Use libgcrypt for SHA1 */ #include <gcrypt.h> diff --git a/xorg-server/xkeyboard-config/rules/base.xml.in b/xorg-server/xkeyboard-config/rules/base.xml.in index d9883f1ae..e0c1b4e58 100644 --- a/xorg-server/xkeyboard-config/rules/base.xml.in +++ b/xorg-server/xkeyboard-config/rules/base.xml.in @@ -3148,6 +3148,12 @@ </variant> <variant> <configItem> + <name>qwerty</name> + <_description>German (qwerty)</_description> + </configItem> + </variant> + <variant> + <configItem> <name>ru</name> <_description>Russian (Germany, phonetic)</_description> <languageList> diff --git a/xorg-server/xkeyboard-config/symbols/de b/xorg-server/xkeyboard-config/symbols/de index 4a04cadae..5e412f6a0 100644 --- a/xorg-server/xkeyboard-config/symbols/de +++ b/xorg-server/xkeyboard-config/symbols/de @@ -484,6 +484,21 @@ xkb_symbols "dsb_qwertz" key <AD09> { [ o, O, oacute, Oacute ] }; }; +partial alphanumeric_keys +xkb_symbols "qwerty" { + + // This layout should work exactly as a de with the exception + // of 'Z' and 'Y' keys, which are in the qwerty style (ie. swapped). + // 2008 by Matej Koลกรญk <kosik@fiit.stuba.sk> + + include "de(basic)" + + name[Group1] = "German (qwerty)"; + + key <AB01> { [ z, Z, leftarrow, yen ] }; + key <AD06> { [ y, Y, guillemotleft, less ] }; +}; + // layout for Russian letters on an german keyboard // based on US-RU layout by Ivan Popov <pin@konvalo.org> 2005-07-17 // adopted for german layout by Alexey Fisher <bug-track@fisher-privat.net> 2010-08-19 diff --git a/xorg-server/xkeyboard-config/symbols/it b/xorg-server/xkeyboard-config/symbols/it index 90fb7f5c9..1d26a044b 100644 --- a/xorg-server/xkeyboard-config/symbols/it +++ b/xorg-server/xkeyboard-config/symbols/it @@ -175,9 +175,9 @@ xkb_symbols "olpc" { partial alphanumeric_keys modifier_keys xkb_symbols "us" { - name[Group1]= "Italian (US keyboard with Italian letters)"; - include "us(euro)" + + name[Group1]= "Italian (US keyboard with Italian letters)"; // Alphanumeric section |