aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2012-12-10 08:55:36 +0100
committermarha <marha@users.sourceforge.net>2012-12-10 08:55:36 +0100
commita0124a5e8e70979d2c24ef55285da989fdad766a (patch)
tree5cea5c9804a8edf67bc7260e0851a20d21324547
parent514b4afb64ccbf8e954270105ed5064272a2be68 (diff)
parent0328076efb5ff6e62152c09e38d0d11f7931d07b (diff)
downloadvcxsrv-a0124a5e8e70979d2c24ef55285da989fdad766a.tar.gz
vcxsrv-a0124a5e8e70979d2c24ef55285da989fdad766a.tar.bz2
vcxsrv-a0124a5e8e70979d2c24ef55285da989fdad766a.zip
Merge remote-tracking branch 'origin/released'
* origin/released: fontconfig libX11 mesa pixman git update 10 dec 2012 Conflicts: fontconfig/src/fcxml.c
-rw-r--r--fontconfig/conf.d/50-user.conf7
-rw-r--r--fontconfig/configure.ac2
-rw-r--r--fontconfig/src/fccfg.c2
-rw-r--r--fontconfig/src/fcdir.c14
-rw-r--r--fontconfig/src/fcinit.c16
-rw-r--r--fontconfig/src/fcint.h3
-rw-r--r--fontconfig/src/fclang.c26
-rw-r--r--fontconfig/src/fcstr.c5
-rwxr-xr-x[-rw-r--r--]fontconfig/src/fcxml.c34
-rw-r--r--libX11/configure.ac2
-rw-r--r--libX11/nls/compose.dir.pre98
-rw-r--r--libX11/nls/ja.S90/XI18N_OBJS7
-rw-r--r--libX11/nls/ja.S90/XLC_LOCALE.pre150
-rw-r--r--libX11/nls/ja.U90/XI18N_OBJS7
-rw-r--r--libX11/nls/ja.U90/XLC_LOCALE.pre151
-rw-r--r--libX11/nls/ja_JP.UTF-8/Compose.pre1
-rw-r--r--libX11/nls/km_KH.UTF-8/Compose.pre8
-rw-r--r--libX11/nls/km_KH.UTF-8/XI18N_OBJS8
-rw-r--r--libX11/nls/km_KH.UTF-8/XLC_LOCALE.pre (renamed from libX11/nls/ja.S90/Compose.pre)0
-rw-r--r--libX11/nls/ko_KR.UTF-8/Compose.pre1
-rw-r--r--libX11/nls/locale.alias.pre254
-rw-r--r--libX11/nls/locale.dir.pre43
-rw-r--r--libX11/nls/sr_CS.UTF-8/Compose.pre128
-rw-r--r--libX11/nls/sr_CS.UTF-8/XI18N_OBJS8
-rw-r--r--libX11/nls/sr_CS.UTF-8/XLC_LOCALE.pre (renamed from libX11/nls/ja.U90/Compose.pre)0
-rw-r--r--libX11/nls/th_TH.UTF-8/Compose.pre1
-rw-r--r--libX11/nls/zh_CN.UTF-8/Compose.pre1
-rw-r--r--libX11/nls/zh_HK.UTF-8/Compose.pre1
-rw-r--r--libX11/nls/zh_TW.UTF-8/Compose.pre1
-rw-r--r--mesalib/.dir-locals.el11
-rw-r--r--mesalib/include/GL/gl.h12
-rw-r--r--mesalib/scons/gallium.py2
-rw-r--r--mesalib/src/gallium/auxiliary/Makefile.sources1
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.h6
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_rect.c158
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_rect.h30
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_surface.c179
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_surface.h24
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_transfer.c28
-rw-r--r--mesalib/src/glsl/Makefile.am6
-rw-r--r--mesalib/src/glsl/SConscript6
-rw-r--r--mesalib/src/glsl/ast_function.cpp23
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp153
-rw-r--r--mesalib/src/glsl/builtin_compiler/Makefile.am3
-rw-r--r--mesalib/src/glsl/builtin_types.h5
-rw-r--r--mesalib/src/glsl/builtin_variables.cpp193
-rw-r--r--mesalib/src/glsl/glcpp/Makefile.am2
-rw-r--r--mesalib/src/glsl/glcpp/glcpp-parse.y62
-rw-r--r--mesalib/src/glsl/glsl_lexer.ll315
-rw-r--r--mesalib/src/glsl/glsl_parser.yy86
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp172
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h77
-rw-r--r--mesalib/src/glsl/glsl_symbol_table.cpp6
-rw-r--r--mesalib/src/glsl/glsl_symbol_table.h3
-rw-r--r--mesalib/src/glsl/glsl_types.cpp140
-rw-r--r--mesalib/src/glsl/glsl_types.h11
-rw-r--r--mesalib/src/glsl/hir_field_selection.cpp3
-rw-r--r--mesalib/src/glsl/ir_variable_refcount.cpp35
-rw-r--r--mesalib/src/glsl/ir_variable_refcount.h17
-rw-r--r--mesalib/src/glsl/linker.cpp37
-rw-r--r--mesalib/src/glsl/lower_output_reads.cpp1
-rw-r--r--mesalib/src/glsl/main.cpp2
-rw-r--r--mesalib/src/glsl/opt_dead_code.cpp6
-rw-r--r--mesalib/src/glsl/standalone_scaffolding.cpp1
-rw-r--r--mesalib/src/mesa/Android.libmesa_glsl_utils.mk6
-rw-r--r--mesalib/src/mesa/SConscript3
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c80
-rw-r--r--mesalib/src/mesa/drivers/dri/common/drisw_util.c16
-rw-r--r--mesalib/src/mesa/main/bufferobj.c22
-rw-r--r--mesalib/src/mesa/main/extensions.c1
-rw-r--r--mesalib/src/mesa/main/ff_fragment_shader.cpp1
-rw-r--r--mesalib/src/mesa/main/format_unpack.c101
-rw-r--r--mesalib/src/mesa/main/format_unpack.h3
-rw-r--r--mesalib/src/mesa/main/formats.c133
-rw-r--r--mesalib/src/mesa/main/formats.h10
-rw-r--r--mesalib/src/mesa/main/glformats.c21
-rw-r--r--mesalib/src/mesa/main/mtypes.h9
-rw-r--r--mesalib/src/mesa/main/set.c348
-rw-r--r--mesalib/src/mesa/main/set.h94
-rw-r--r--mesalib/src/mesa/main/shared.c12
-rw-r--r--mesalib/src/mesa/main/syncobj.c31
-rw-r--r--mesalib/src/mesa/main/texcompress.c100
-rw-r--r--mesalib/src/mesa/main/texcompress_etc.c1376
-rw-r--r--mesalib/src/mesa/main/texcompress_etc.h79
-rw-r--r--mesalib/src/mesa/main/texcompress_s3tc.c52
-rw-r--r--mesalib/src/mesa/main/texformat.c37
-rw-r--r--mesalib/src/mesa/main/teximage.c21
-rw-r--r--mesalib/src/mesa/main/texstore.c12
-rw-r--r--mesalib/src/mesa/program/Android.mk3
-rw-r--r--mesalib/src/mesa/program/prog_hash_table.c (renamed from mesalib/src/mesa/program/hash_table.c)0
-rw-r--r--mesalib/src/mesa/sources.mak3
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom.h2
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_constbuf.c68
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_texture.c18
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c6
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.c194
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c25
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp94
-rw-r--r--mesalib/src/mesa/state_tracker/st_manager.c6
-rw-r--r--mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c1
-rw-r--r--mesalib/src/mesa/swrast/s_texfetch.c60
-rw-r--r--pixman/configure.ac2
-rw-r--r--pixman/demos/Makefile.am11
-rw-r--r--pixman/demos/conical-test.c134
-rw-r--r--pixman/demos/gtk-utils.c66
-rw-r--r--pixman/demos/gtk-utils.h3
-rw-r--r--pixman/demos/scale.c431
-rw-r--r--pixman/demos/scale.ui302
-rw-r--r--pixman/demos/zone_plate.pngbin0 -> 228732 bytes
-rw-r--r--pixman/pixman/Makefile.sources1
-rw-r--r--pixman/pixman/pixman-bits-image.c285
-rw-r--r--pixman/pixman/pixman-filter.c340
-rw-r--r--pixman/pixman/pixman-image.c22
-rw-r--r--pixman/pixman/pixman-private.h1
-rw-r--r--pixman/pixman/pixman.c8
-rw-r--r--pixman/pixman/pixman.h50
-rw-r--r--pixman/pixman/rounding.txt33
-rw-r--r--pixman/test/Makefile.sources3
-rw-r--r--pixman/test/affine-test.c111
-rw-r--r--pixman/test/alpha-loop.c11
-rw-r--r--pixman/test/alphamap.c2
-rw-r--r--pixman/test/blitters-test.c60
-rw-r--r--pixman/test/combiner-test.c4
-rw-r--r--pixman/test/composite-traps-test.c58
-rw-r--r--pixman/test/composite.c12
-rw-r--r--pixman/test/glyph-test.c94
-rw-r--r--pixman/test/prng-test.c172
-rw-r--r--pixman/test/region-contains-test.c28
-rw-r--r--pixman/test/region-test.c10
-rw-r--r--pixman/test/rotate-test.c14
-rw-r--r--pixman/test/scaling-helpers-test.c9
-rw-r--r--pixman/test/scaling-test.c129
-rw-r--r--pixman/test/stress-test.c112
-rw-r--r--pixman/test/utils-prng.c238
-rw-r--r--pixman/test/utils-prng.h168
-rw-r--r--pixman/test/utils.c25
-rw-r--r--pixman/test/utils.h58
138 files changed, 7086 insertions, 1766 deletions
diff --git a/fontconfig/conf.d/50-user.conf b/fontconfig/conf.d/50-user.conf
index 2f1040898..07c9182e7 100644
--- a/fontconfig/conf.d/50-user.conf
+++ b/fontconfig/conf.d/50-user.conf
@@ -1,7 +1,12 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
- <!-- Load per-user customization file -->
+ <!--
+ Load per-user customization files where stored on XDG Base Directory
+ specification compliant places. it should be usually:
+ $HOME/.config/fontconfig/conf.d
+ $HOME/.config/fontconfig/fonts.conf
+ -->
<include ignore_missing="yes" prefix="xdg">fontconfig/conf.d</include>
<include ignore_missing="yes" prefix="xdg">fontconfig/fonts.conf</include>
<!-- the following elements will be removed in the future -->
diff --git a/fontconfig/configure.ac b/fontconfig/configure.ac
index 6d5ce7e77..5657bb5d1 100644
--- a/fontconfig/configure.ac
+++ b/fontconfig/configure.ac
@@ -137,7 +137,7 @@ AC_TYPE_PID_T
# Checks for library functions.
AC_FUNC_VPRINTF
AC_FUNC_MMAP
-AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr strtol getopt getopt_long sysconf ftruncate chsize rand random lrand48 random_r rand_r regcomp regerror regexec regfree fstatvfs fstatfs])
+AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr strtol getopt getopt_long sysconf ftruncate chsize rand random lrand48 random_r rand_r regcomp regerror regexec regfree fstatvfs fstatfs lstat])
dnl AC_CHECK_FUNCS doesn't check for header files.
dnl posix_fadvise() may be not available in older libc.
diff --git a/fontconfig/src/fccfg.c b/fontconfig/src/fccfg.c
index d3752e552..45b486945 100644
--- a/fontconfig/src/fccfg.c
+++ b/fontconfig/src/fccfg.c
@@ -1743,6 +1743,8 @@ FcConfigFileExists (const FcChar8 *dir, const FcChar8 *file)
#else
if ((!path[0] || path[strlen((char *) path)-1] != '/') && file[0] != '/')
strcat ((char *) path, "/");
+ else
+ osize--;
#endif
strcat ((char *) path, (char *) file);
diff --git a/fontconfig/src/fcdir.c b/fontconfig/src/fcdir.c
index 2b476e8b9..6869ea179 100644
--- a/fontconfig/src/fcdir.c
+++ b/fontconfig/src/fcdir.c
@@ -35,6 +35,20 @@ FcFileIsDir (const FcChar8 *file)
return S_ISDIR(statb.st_mode);
}
+FcBool
+FcFileIsLink (const FcChar8 *file)
+{
+#if HAVE_LSTAT
+ struct stat statb;
+
+ if (lstat ((const char *)file, &statb) != 0)
+ return FcFalse;
+ return S_ISLNK (statb.st_mode);
+#else
+ return FcFalse;
+#endif
+}
+
static FcBool
FcFileScanFontConfig (FcFontSet *set,
FcBlanks *blanks,
diff --git a/fontconfig/src/fcinit.c b/fontconfig/src/fcinit.c
index ab6401215..606483d8d 100644
--- a/fontconfig/src/fcinit.c
+++ b/fontconfig/src/fcinit.c
@@ -72,7 +72,7 @@ FcInitLoadConfig (void)
if (config->cacheDirs && config->cacheDirs->num == 0)
{
- FcChar8 *prefix;
+ FcChar8 *prefix, *p;
size_t plen;
fprintf (stderr,
@@ -81,12 +81,15 @@ FcInitLoadConfig (void)
"Fontconfig warning: adding <cachedir>%s</cachedir>\n",
FC_CACHEDIR);
prefix = FcConfigXdgCacheHome ();
- plen = prefix ? strlen ((const char *)prefix) : 0;
if (!prefix)
goto bail;
- prefix = realloc (prefix, plen + 12);
- if (!prefix)
+ plen = strlen ((const char *)prefix);
+ p = realloc (prefix, plen + 12);
+ if (!p)
goto bail;
+ prefix = p;
+ FcMemFree (FC_MEM_STRING, plen + 1);
+ FcMemAlloc (FC_MEM_STRING, plen + 12);
memcpy (&prefix[plen], FC_DIR_SEPARATOR_S "fontconfig", 11);
prefix[plen + 11] = 0;
fprintf (stderr,
@@ -98,11 +101,12 @@ FcInitLoadConfig (void)
bail:
fprintf (stderr,
"Fontconfig error: out of memory");
- free (prefix);
+ if (prefix)
+ FcStrFree (prefix);
FcConfigDestroy (config);
return FcInitFallbackConfig ();
}
- free (prefix);
+ FcStrFree (prefix);
}
return config;
diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h
index 7125f2e5e..87c7b9a9f 100644
--- a/fontconfig/src/fcint.h
+++ b/fontconfig/src/fcint.h
@@ -764,6 +764,9 @@ FcGetDefaultLang (void);
/* fcdir.c */
FcPrivate FcBool
+FcFileIsLink (const FcChar8 *file);
+
+FcPrivate FcBool
FcFileScanConfig (FcFontSet *set,
FcStrSet *dirs,
FcBlanks *blanks,
diff --git a/fontconfig/src/fclang.c b/fontconfig/src/fclang.c
index b7e70fcfb..65d22a932 100644
--- a/fontconfig/src/fclang.c
+++ b/fontconfig/src/fclang.c
@@ -182,7 +182,7 @@ FcLangNormalize (const FcChar8 *lang)
{
FcChar8 *result = NULL, *s, *orig;
char *territory, *encoding, *modifier;
- size_t llen, tlen = 0, mlen = 0;
+ size_t llen, tlen = 0, mlen = 0, ssize;
if (!lang || !*lang)
return NULL;
@@ -197,6 +197,10 @@ FcLangNormalize (const FcChar8 *lang)
s = FcStrCopy (lang);
if (!s)
goto bail;
+ /* store the original length of 's' here to let FcMemFree know
+ * the correct size since we breaks 's' from now on.
+ */
+ ssize = strlen ((const char *)s) + 1;
/* from the comments in glibc:
*
@@ -282,6 +286,11 @@ FcLangNormalize (const FcChar8 *lang)
else
{
result = s;
+ /* we'll miss the opportunity to reduce the correct size
+ * of the allocated memory for the string after that.
+ */
+ FcMemFree (FC_MEM_STRING, ssize);
+ FcMemAlloc (FC_MEM_STRING, strlen((const char *)s) + 1);
s = NULL;
goto bail1;
}
@@ -295,6 +304,11 @@ FcLangNormalize (const FcChar8 *lang)
else
{
result = s;
+ /* we'll miss the opportunity to reduce the correct size
+ * of the allocated memory for the string after that.
+ */
+ FcMemFree (FC_MEM_STRING, ssize);
+ FcMemAlloc (FC_MEM_STRING, strlen((const char *)s) + 1);
s = NULL;
goto bail1;
}
@@ -312,14 +326,22 @@ FcLangNormalize (const FcChar8 *lang)
else
{
result = s;
+ /* we'll miss the opportunity to reduce the correct size
+ * of the allocated memory for the string after that.
+ */
+ FcMemFree (FC_MEM_STRING, ssize);
+ FcMemAlloc (FC_MEM_STRING, strlen((const char *)s) + 1);
s = NULL;
}
bail1:
if (orig)
- free (orig);
+ FcStrFree (orig);
bail0:
if (s)
+ {
free (s);
+ FcMemFree (FC_MEM_STRING, ssize);
+ }
bail:
if (FcDebug () & FC_DBG_LANGSET)
{
diff --git a/fontconfig/src/fcstr.c b/fontconfig/src/fcstr.c
index 037960d2f..99b59da0a 100644
--- a/fontconfig/src/fcstr.c
+++ b/fontconfig/src/fcstr.c
@@ -38,7 +38,6 @@ FcStrCopy (const FcChar8 *s)
{
int len;
FcChar8 *r;
-
if (!s)
return 0;
len = strlen ((char *) s) + 1;
@@ -1204,7 +1203,7 @@ FcStrSetAddLangs (FcStrSet *strs, const char *languages)
if (normalized_lang)
{
FcStrSetAdd (strs, normalized_lang);
- free (normalized_lang);
+ FcStrFree (normalized_lang);
ret = FcTrue;
}
}
@@ -1216,7 +1215,7 @@ FcStrSetAddLangs (FcStrSet *strs, const char *languages)
if (normalized_lang)
{
FcStrSetAdd (strs, normalized_lang);
- free (normalized_lang);
+ FcStrFree (normalized_lang);
ret = FcTrue;
}
}
diff --git a/fontconfig/src/fcxml.c b/fontconfig/src/fcxml.c
index 7d1d6f1ad..0c8c80561 100644..100755
--- a/fontconfig/src/fcxml.c
+++ b/fontconfig/src/fcxml.c
@@ -1850,7 +1850,7 @@ FcParseDir (FcConfigParse *parse)
{
const FcChar8 *attr;
FcChar8 *data;
- FcChar8 *prefix = NULL;
+ FcChar8 *prefix = NULL, *p;
#ifdef _WIN32
FcChar8 buffer[1000];
#endif
@@ -1869,13 +1869,14 @@ FcParseDir (FcConfigParse *parse)
size_t plen = strlen ((const char *)prefix);
size_t dlen = strlen ((const char *)data);
- FcMemFree (FC_MEM_STRING, plen + 1);
- prefix = realloc (prefix, plen + 1 + dlen + 1);
- if (!prefix)
+ p = realloc (prefix, plen + 1 + dlen + 1);
+ if (!p)
{
FcConfigMessage (parse, FcSevereError, "out of memory");
goto bail;
}
+ prefix = p;
+ FcMemFree (FC_MEM_STRING, plen + 1);
FcMemAlloc (FC_MEM_STRING, plen + 1 + dlen + 1);
prefix[plen] = FC_DIR_SEPARATOR;
memcpy (&prefix[plen + 1], data, dlen);
@@ -1948,7 +1949,7 @@ static void
FcParseCacheDir (FcConfigParse *parse)
{
const FcChar8 *attr;
- FcChar8 *prefix = NULL, *data;
+ FcChar8 *prefix = NULL, *p, *data;
attr = FcConfigGetAttribute (parse, "prefix");
if (attr && FcStrCmp (attr, (const FcChar8 *)"xdg") == 0)
@@ -1964,13 +1965,15 @@ FcParseCacheDir (FcConfigParse *parse)
size_t plen = strlen ((const char *)prefix);
size_t dlen = strlen ((const char *)data);
- FcMemFree (FC_MEM_STRING, plen + 1);
- prefix = realloc (prefix, plen + 1 + dlen + 1);
- if (!prefix)
+ p = realloc (prefix, plen + 1 + dlen + 1);
+ if (!p)
{
FcConfigMessage (parse, FcSevereError, "out of memory");
+ data = prefix;
goto bail;
}
+ prefix = p;
+ FcMemFree (FC_MEM_STRING, plen + 1);
FcMemAlloc (FC_MEM_STRING, plen + 1 + dlen + 1);
prefix[plen] = FC_DIR_SEPARATOR;
memcpy (&prefix[plen + 1], data, dlen);
@@ -2044,7 +2047,7 @@ FcParseInclude (FcConfigParse *parse)
const FcChar8 *attr;
FcBool ignore_missing = FcFalse;
FcBool deprecated = FcFalse;
- FcChar8 *prefix = NULL;
+ FcChar8 *prefix = NULL, *p;
s = FcStrBufDoneStatic (&parse->pstack->str);
if (!s)
@@ -2066,13 +2069,14 @@ FcParseInclude (FcConfigParse *parse)
size_t plen = strlen ((const char *)prefix);
size_t dlen = strlen ((const char *)s);
- FcMemFree (FC_MEM_STRING, plen + 1);
- prefix = realloc (prefix, plen + 1 + dlen + 1);
- if (!prefix)
+ p = realloc (prefix, plen + 1 + dlen + 1);
+ if (!p)
{
FcConfigMessage (parse, FcSevereError, "out of memory");
goto bail;
}
+ prefix = p;
+ FcMemFree (FC_MEM_STRING, plen + 1);
FcMemAlloc (FC_MEM_STRING, plen + 1 + dlen + 1);
prefix[plen] = FC_DIR_SEPARATOR;
memcpy (&prefix[plen + 1], s, dlen);
@@ -2086,8 +2090,10 @@ FcParseInclude (FcConfigParse *parse)
FcChar8 *filename;
filename = FcConfigFilename(s);
- if ((deprecated == FcTrue) && filename)
- {
+ if (deprecated == FcTrue &&
+ filename != NULL &&
+ !FcFileIsLink (filename))
+ {
FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated.", s);
}
if(filename)
diff --git a/libX11/configure.ac b/libX11/configure.ac
index a45f9d956..fe3179948 100644
--- a/libX11/configure.ac
+++ b/libX11/configure.ac
@@ -439,7 +439,7 @@ locales="\
iso8859-1 iso8859-10 iso8859-11 iso8859-13 iso8859-14 iso8859-15 \
iso8859-2 iso8859-3 iso8859-4 iso8859-5 iso8859-6 iso8859-7 \
iso8859-8 iso8859-9 iso8859-9e ja ja.JIS ja_JP.UTF-8\
- ja.S90 ja.SJIS ja.U90 ko koi8-c koi8-r \
+ ja.SJIS ko koi8-c koi8-r \
koi8-u ko_KR.UTF-8 microsoft-cp1251 microsoft-cp1255 \
microsoft-cp1256 mulelao-1 nokhchi-1 pt_BR.UTF-8 ru_RU.UTF-8 \
tatar-cyr th_TH th_TH.UTF-8 tscii-0 vi_VN.tcvn vi_VN.viscii \
diff --git a/libX11/nls/compose.dir.pre b/libX11/nls/compose.dir.pre
index 14a2fa987..ef9a519bc 100644
--- a/libX11/nls/compose.dir.pre
+++ b/libX11/nls/compose.dir.pre
@@ -7,6 +7,7 @@ XCOMM
iso8859-1/Compose: C
iso8859-1/Compose: af_ZA.ISO8859-1
iso8859-6/Compose: ar_AA.ISO8859-6
+iso8859-6/Compose: ar_AE.ISO8859-6
iso8859-6/Compose: ar_BH.ISO8859-6
iso8859-6/Compose: ar_DZ.ISO8859-6
iso8859-6/Compose: ar_EG.ISO8859-6
@@ -19,13 +20,17 @@ iso8859-6/Compose: ar_MA.ISO8859-6
iso8859-6/Compose: ar_OM.ISO8859-6
iso8859-6/Compose: ar_QA.ISO8859-6
iso8859-6/Compose: ar_SA.ISO8859-6
+iso8859-6/Compose: ar_SD.ISO8859-6
+iso8859-6/Compose: ar_SY.ISO8859-6
iso8859-6/Compose: ar_TN.ISO8859-6
iso8859-6/Compose: ar_YE.ISO8859-6
iso8859-9e/Compose: az_AZ.ISO8859-9E
-koi8-c/Compose: a3_AZ.KOI8-C
+koi8-c/Compose: az_AZ.KOI8-C
microsoft-cp1251/Compose: be_BY.CP1251
+iso8859-5/Compose: be_BY.ISO8859-5
iso8859-5/Compose: bg_BG.ISO8859-5
microsoft-cp1251/Compose: bg_BG.CP1251
+koi8-r/Compose: bg_BG.KOI8-R
iso8859-1/Compose: br_FR.ISO8859-1
iso8859-14/Compose: br_FR.ISO8859-14
iso8859-15/Compose: br_FR.ISO8859-15
@@ -46,6 +51,8 @@ iso8859-1/Compose: da_DK.ISO8859-1
iso8859-15/Compose: da_DK.ISO8859-15
iso8859-1/Compose: de_AT.ISO8859-1
iso8859-15/Compose: de_AT.ISO8859-15
+iso8859-1/Compose: de_BE.ISO8859-1
+iso8859-15/Compose: de_BE.ISO8859-15
iso8859-1/Compose: de_CH.ISO8859-1
iso8859-15/Compose: de_CH.ISO8859-15
iso8859-1/Compose: de_DE.ISO8859-1
@@ -54,16 +61,26 @@ iso8859-1/Compose: de_LI.ISO8859-1
iso8859-15/Compose: de_LI.ISO8859-15
iso8859-1/Compose: de_LU.ISO8859-1
iso8859-15/Compose: de_LU.ISO8859-15
+iso8859-4/Compose: ee_EE.ISO8859-4
iso8859-7/Compose: el_GR.ISO8859-7
+iso8859-15/Compose: el_GR.ISO8859-15
iso8859-1/Compose: en_AU.ISO8859-1
+iso8859-1/Compose: en_BE.ISO8859-1
+iso8859-15/Compose: en_BE.ISO8859-15
+iso8859-1/Compose: en_BW.ISO8859-1
iso8859-1/Compose: en_BZ.ISO8859-1
iso8859-1/Compose: en_CA.ISO8859-1
+iso8859-1/Compose: en_EN.ISO8859-1
iso8859-1/Compose: en_GB.ISO8859-1
iso8859-15/Compose: en_GB.ISO8859-15
+iso8859-1/Compose: en_HK.ISO8859-1
iso8859-1/Compose: en_IE.ISO8859-1
iso8859-15/Compose: en_IE.ISO8859-15
+iso8859-15/Compose: en_IN.ISO8859-15
iso8859-1/Compose: en_JM.ISO8859-1
iso8859-1/Compose: en_NZ.ISO8859-1
+iso8859-1/Compose: en_PH.ISO8859-1
+iso8859-1/Compose: en_SG.ISO8859-1
iso8859-1/Compose: en_TT.ISO8859-1
iso8859-1/Compose: en_UK.ISO8859-1
iso8859-15/Compose: en_UK.ISO8859-15
@@ -71,6 +88,8 @@ iso8859-1/Compose: en_US.ISO8859-1
iso8859-15/Compose: en_US.ISO8859-15
iso8859-1/Compose: en_ZA.ISO8859-1
iso8859-15/Compose: en_ZA.ISO8859-15
+iso8859-1/Compose: en_ZW.ISO8859-1
+iso8859-3/Compose: eo_EO.ISO8859-3
iso8859-3/Compose: eo_XX.ISO8859-3
iso8859-1/Compose: es_AR.ISO8859-1
iso8859-1/Compose: es_BO.ISO8859-1
@@ -86,12 +105,19 @@ iso8859-1/Compose: es_HN.ISO8859-1
iso8859-1/Compose: es_MX.ISO8859-1
iso8859-1/Compose: es_NI.ISO8859-1
iso8859-1/Compose: es_PA.ISO8859-1
+iso8859-15/Compose: es_PA.ISO8859-15
iso8859-1/Compose: es_PE.ISO8859-1
+iso8859-15/Compose: es_PE.ISO8859-15
iso8859-1/Compose: es_PR.ISO8859-1
iso8859-1/Compose: es_PY.ISO8859-1
+iso8859-15/Compose: es_PY.ISO8859-15
iso8859-1/Compose: es_SV.ISO8859-1
+iso8859-15/Compose: es_SV.ISO8859-15
+iso8859-1/Compose: es_US.ISO8859-1
iso8859-1/Compose: es_UY.ISO8859-1
+iso8859-15/Compose: es_UY.ISO8859-15
iso8859-1/Compose: es_VE.ISO8859-1
+iso8859-15/Compose: es_VE.ISO8859-15
iso8859-1/Compose: et_EE.ISO8859-1
iso8859-4/Compose: et_EE.ISO8859-4
iso8859-13/Compose: et_EE.ISO8859-13
@@ -151,14 +177,12 @@ iso8859-15/Compose: kw_GB.ISO8859-15
ko/Compose: ko_KR.eucKR
ibm-cp1133/Compose: lo_LA.IBM-CP1133
mulelao-1/Compose: lo_LA.MULELAO-1
-iso8859-1/Compose: lt_LN.ISO8859-1
iso8859-4/Compose: lt_LT.ISO8859-4
iso8859-13/Compose: lt_LT.ISO8859-13
iso8859-4/Compose: lv_LV.ISO8859-4
iso8859-13/Compose: lv_LV.ISO8859-13
iso8859-13/Compose: mi_NZ.ISO8859-13
iso8859-5/Compose: mk_MK.ISO8859-5
-XCOMM mk_MK.UTF-8/Compose: mk_MK.UTF-8
microsoft-cp1251/Compose: mk_MK.CP1251
iso8859-1/Compose: ms_MY.ISO8859-1
iso8859-3/Compose: mt_MT.ISO8859-3
@@ -179,7 +203,9 @@ iso8859-15/Compose: ny_NO.ISO8859-15
iso8859-1/Compose: oc_FR.ISO8859-1
iso8859-15/Compose: oc_FR.ISO8859-15
iso8859-1/Compose: pd_DE.ISO8859-1
+iso8859-15/Compose: pd_DE.ISO8859-15
iso8859-1/Compose: pd_US.ISO8859-1
+iso8859-15/Compose: pd_US.ISO8859-15
iso8859-1/Compose: ph_PH.ISO8859-1
iso8859-2/Compose: pl_PL.ISO8859-2
iso8859-1/Compose: pp_AN.ISO8859-1
@@ -191,16 +217,17 @@ iso8859-2/Compose: ro_RO.ISO8859-2
koi8-r/Compose: ru_RU.KOI8-R
iso8859-5/Compose: ru_RU.ISO8859-5
microsoft-cp1251/Compose: ru_RU.CP1251
+microsoft-cp1251/Compose: ru_UA.CP1251
koi8-u/Compose: ru_UA.KOI8-U
iso8859-1/Compose: rw_RW.ISO8859-1
iso8859-2/Compose: sh_YU.ISO8859-2
iso8859-2/Compose: sk_SK.ISO8859-2
-iso8859-2/Compose: sl_CS.ISO8859-2
iso8859-2/Compose: sl_SI.ISO8859-2
iso8859-2/Compose: sq_AL.ISO8859-2
iso8859-2/Compose: sr_CS.ISO8859-2
iso8859-5/Compose: sr_CS.ISO8859-5
iso8859-2/Compose: sr_YU.ISO8859-2
+microsoft-cp1251/Compose: sr_YU.CP1251
iso8859-5/Compose: sr_YU.ISO8859-5
iso8859-1/Compose: ss_ZA.ISO8859-1
iso8859-1/Compose: st_ZA.ISO8859-1
@@ -211,34 +238,39 @@ iso8859-15/Compose: sv_SE.ISO8859-15
tscii-0/Compose: ta_IN.TSCII-0
koi8-c/Compose: tg_TJ.KOI8-C
iso8859-1/Compose: tl_PH.ISO8859-1
+iso8859-11/Compose: th_TH.ISO8859-11
+th_TH/Compose: th_TH.TIS620
iso8859-15/Compose: tn_ZA.ISO8859-15
iso8859-9/Compose: tr_TR.ISO8859-9
iso8859-1/Compose: ts_ZA.ISO8859-1
tatar-cyr/Compose: tt_RU.TATAR-CYR
+microsoft-cp1251/Compose: uk_UA.CP1251
koi8-c/Compose: tt_RU.KOI8-C
koi8-u/Compose: uk_UA.KOI8-U
+iso8859-5/Compose: uk_UA.ISO8859-5
microsoft-cp1256/Compose: ur_PK.CP1256
+iso8859-1/Compose: uz_UZ.ISO8859-1
vi_VN.viscii/Compose: vi_VN.VISCII
vi_VN.tcvn/Compose: vi_VN.TCVN
iso8859-1/Compose: wa_BE.ISO8859-1
+iso8859-15/Compose: wa_BE.ISO8859-15
iso8859-1/Compose: xh_ZA.ISO8859-1
-microsoft-cp1255/Compose: yi_US.CP1256
+microsoft-cp1255/Compose: yi_US.CP1255
zh_CN/Compose: zh_CN.eucCN
-zh_CN/Compose: zh_CN.GB2312
-zh_CN.gbk/Compose: zh_CN.GBK
-zh_CN.gb18030/Compose: zh_CN.GB18030
+zh_CN/Compose: zh_CN.gb2312
+zh_CN.gbk/Compose: zh_CN.gbk
+zh_CN.gb18030/Compose: zh_CN.gb18030
zh_HK.big5/Compose: zh_HK.big5
-zh_HK.big5/Compose: zh_HK.Big5
zh_HK.big5hkscs/Compose: zh_HK.big5hkscs
-zh_HK.big5hkscs/Compose: zh_HK.Big5HKSCS
zh_TW.big5/Compose: zh_TW.big5
-zh_TW.big5/Compose: zh_TW.Big5
zh_TW/Compose: zh_TW.eucTW
iso8859-1/Compose: zu_ZA.ISO8859-1
XCOMM
XCOMM
en_US.UTF-8/Compose: af_ZA.UTF-8
+am_ET.UTF-8/Compose: am_ET.UTF-8
en_US.UTF-8/Compose: ar_AA.UTF-8
+en_US.UTF-8/Compose: ar_AE.UTF-8
en_US.UTF-8/Compose: ar_BH.UTF-8
en_US.UTF-8/Compose: ar_DZ.UTF-8
en_US.UTF-8/Compose: ar_EG.UTF-8
@@ -252,23 +284,26 @@ en_US.UTF-8/Compose: ar_MA.UTF-8
en_US.UTF-8/Compose: ar_OM.UTF-8
en_US.UTF-8/Compose: ar_QA.UTF-8
en_US.UTF-8/Compose: ar_SA.UTF-8
+en_US.UTF-8/Compose: ar_SD.UTF-8
+en_US.UTF-8/Compose: ar_SY.UTF-8
en_US.UTF-8/Compose: ar_TN.UTF-8
en_US.UTF-8/Compose: ar_YE.UTF-8
+en_US.UTF-8/Compose: as_IN.UTF-8
en_US.UTF-8/Compose: bo_IN.UTF-8
en_US.UTF-8/Compose: bs_BA.UTF-8
en_US.UTF-8/Compose: az_AZ.UTF-8
-en_US.UTF-8/Compose: a3_AZ.UTF-8
en_US.UTF-8/Compose: be_BY.UTF-8
en_US.UTF-8/Compose: bg_BG.UTF-8
en_US.UTF-8/Compose: bn_IN.UTF-8
+en_US.UTF-8/Compose: bn_BD.UTF-8
en_US.UTF-8/Compose: br_FR.UTF-8
+en_US.UTF-8/Compose: bs_BA.UTF-8
en_US.UTF-8/Compose: ca_AD.UTF-8
en_US.UTF-8/Compose: ca_ES.UTF-8
en_US.UTF-8/Compose: ca_FR.UTF-8
en_US.UTF-8/Compose: ca_IT.UTF-8
en_US.UTF-8/Compose: cs_CZ.UTF-8
en_US.UTF-8/Compose: cy_GB.UTF-8
-en_US.UTF-8/Compose: cz_CZ.UTF-8
en_US.UTF-8/Compose: da_DK.UTF-8
en_US.UTF-8/Compose: de_AT.UTF-8
en_US.UTF-8/Compose: de_BE.UTF-8
@@ -279,17 +314,27 @@ en_US.UTF-8/Compose: de_LU.UTF-8
el_GR.UTF-8/Compose: el_CY.UTF-8
el_GR.UTF-8/Compose: el_GR.UTF-8
en_US.UTF-8/Compose: en_AU.UTF-8
+en_US.UTF-8/Compose: en_BE.UTF-8
+en_US.UTF-8/Compose: en_BW.UTF-8
en_US.UTF-8/Compose: en_BZ.UTF-8
+en_US.UTF-8/Compose: en_DK.UTF-8
en_US.UTF-8/Compose: en_CA.UTF-8
en_US.UTF-8/Compose: en_GB.UTF-8
+en_US.UTF-8/Compose: en_EN.UTF-8
+en_US.UTF-8/Compose: en_HK.UTF-8
en_US.UTF-8/Compose: en_IE.UTF-8
+en_US.UTF-8/Compose: en_IN.UTF-8
en_US.UTF-8/Compose: en_JM.UTF-8
en_US.UTF-8/Compose: en_MT.UTF-8
en_US.UTF-8/Compose: en_NZ.UTF-8
+en_US.UTF-8/Compose: en_PH.UTF-8
+en_US.UTF-8/Compose: en_SG.UTF-8
en_US.UTF-8/Compose: en_TT.UTF-8
en_US.UTF-8/Compose: en_UK.UTF-8
en_US.UTF-8/Compose: en_US.UTF-8
en_US.UTF-8/Compose: en_ZA.UTF-8
+en_US.UTF-8/Compose: en_ZW.UTF-8
+en_US.UTF-8/Compose: eo_EO.UTF-8
en_US.UTF-8/Compose: eo_XX.UTF-8
en_US.UTF-8/Compose: es_AR.UTF-8
en_US.UTF-8/Compose: es_BO.UTF-8
@@ -337,12 +382,13 @@ en_US.UTF-8/Compose: is_IS.UTF-8
en_US.UTF-8/Compose: it_CH.UTF-8
en_US.UTF-8/Compose: it_IT.UTF-8
en_US.UTF-8/Compose: iu_CA.UTF-8
-en_US.UTF-8/Compose: ja_JP.UTF-8
+ja_JP.UTF-8/Compose: ja_JP.UTF-8
en_US.UTF-8/Compose: ka_GE.UTF-8
-en_US.UTF-8/Compose: kl_GL.UTF-8
en_US.UTF-8/Compose: kk_KZ.UTF-8
+en_US.UTF-8/Compose: kl_GL.UTF-8
+km_KH.UTF-8/Compose: mk_KH.UTF-8
en_US.UTF-8/Compose: kn_IN.UTF-8
-en_US.UTF-8/Compose: ko_KR.UTF-8
+ko_KR.UTF-8/Compose: ko_KR.UTF-8
en_US.UTF-8/Compose: ks_IN.UTF-8
en_US.UTF-8/Compose: ks_IN@devanagari.UTF-8
en_US.UTF-8/Compose: kw_GB.UTF-8
@@ -357,6 +403,7 @@ en_US.UTF-8/Compose: ml_IN.UTF-8
en_US.UTF-8/Compose: mr_IN.UTF-8
en_US.UTF-8/Compose: ms_MY.UTF-8
en_US.UTF-8/Compose: mt_MT.UTF-8
+en_US.UTF-8/Compose: ne_NP.UTF-8
en_US.UTF-8/Compose: nl_BE.UTF-8
en_US.UTF-8/Compose: nl_NL.UTF-8
en_US.UTF-8/Compose: nn_NO.UTF-8
@@ -377,18 +424,20 @@ en_US.UTF-8/Compose: pp_AN.UTF-8
pt_BR.UTF-8/Compose: pt_BR.UTF-8
en_US.UTF-8/Compose: pt_PT.UTF-8
en_US.UTF-8/Compose: ro_RO.UTF-8
-en_US.UTF-8/Compose: ru_RU.UTF-8
+ru_RU.UTF-8/Compose: ru_RU.UTF-8
en_US.UTF-8/Compose: ru_UA.UTF-8
en_US.UTF-8/Compose: rw_RW.UTF-8
en_US.UTF-8/Compose: sa_IN.UTF-8
en_US.UTF-8/Compose: sd_IN.UTF-8
en_US.UTF-8/Compose: sd_IN@devanagari.UTF-8
+en_US.UTF-8/Compose: se_NO.UTF-8
en_US.UTF-8/Compose: sh_BA.UTF-8
+en_US.UTF-8/Compose: sh_YU.UTF-8
en_US.UTF-8/Compose: si_LK.UTF-8
en_US.UTF-8/Compose: sk_SK.UTF-8
en_US.UTF-8/Compose: sl_SI.UTF-8
en_US.UTF-8/Compose: sq_AL.UTF-8
-en_US.UTF-8/Compose: sr_CS.UTF-8
+sr_CS.UTF-8/Compose: sr_CS.UTF-8
en_US.UTF-8/Compose: sr_ME.UTF-8
en_US.UTF-8/Compose: sr_RS.UTF-8
en_US.UTF-8/Compose: sr_YU.UTF-8
@@ -399,7 +448,9 @@ en_US.UTF-8/Compose: sv_SE.UTF-8
en_US.UTF-8/Compose: ta_IN.UTF-8
en_US.UTF-8/Compose: te_IN.UTF-8
en_US.UTF-8/Compose: tg_TJ.UTF-8
-en_US.UTF-8/Compose: th_TH.UTF-8
+th_TH.UTF-8/Compose: th_TH.UTF-8
+en_US.UTF-8/Compose: ti_ER.UTF-8
+en_US.UTF-8/Compose: ti_ET.UTF-8
en_US.UTF-8/Compose: tl_PH.UTF-8
en_US.UTF-8/Compose: tn_ZA.UTF-8
en_US.UTF-8/Compose: tr_TR.UTF-8
@@ -407,14 +458,15 @@ en_US.UTF-8/Compose: ts_ZA.UTF-8
en_US.UTF-8/Compose: tt_RU.UTF-8
en_US.UTF-8/Compose: uk_UA.UTF-8
en_US.UTF-8/Compose: ur_PK.UTF-8
+en_US.UTF-8/Compose: ur_IN.UTF-8
en_US.UTF-8/Compose: uz_UZ.UTF-8
en_US.UTF-8/Compose: ve_ZA.UTF-8
en_US.UTF-8/Compose: vi_VN.UTF-8
en_US.UTF-8/Compose: wa_BE.UTF-8
en_US.UTF-8/Compose: yi_US.UTF-8
en_US.UTF-8/Compose: xh_ZA.UTF-8
-en_US.UTF-8/Compose: zh_TW.UTF-8
+zh_CN.UTF-8/Compose: zh_CN.UTF-8
+zh_HK.UTF-8/Compose: zh_HK.UTF-8
+zh_TW.UTF-8/Compose: zh_TW.UTF-8
en_US.UTF-8/Compose: zu_ZA.UTF-8
-en_US.UTF-8/Compose: bs_BA.UTF-8
-en_US.UTF-8/Compose: ne_NP.UTF-8
-
+en_US.UTF-8/Compose: zh_SG.UTF-8
diff --git a/libX11/nls/ja.S90/XI18N_OBJS b/libX11/nls/ja.S90/XI18N_OBJS
deleted file mode 100644
index d8f0fdd99..000000000
--- a/libX11/nls/ja.S90/XI18N_OBJS
+++ /dev/null
@@ -1,7 +0,0 @@
-# CATEGORY(XLC|XIM|OM) SHARED_LIBRARY_NAME FUNCTION_NAME
-#
-# XI18N objects table for ja.S90 locale
-#
-XLC common/xlibi18n _XlcGenericLoader # XLC_open
-XIM common/ximcp _XimOpenIM _XimRegisterIMInstantiateCallback _XimUnRegisterIMInstantiateCallback # XIM_open XIM_register XIM_unregister
-XOM common/xomGeneric _XomGenericOpenOM # XOM_open
diff --git a/libX11/nls/ja.S90/XLC_LOCALE.pre b/libX11/nls/ja.S90/XLC_LOCALE.pre
deleted file mode 100644
index cb4e49d13..000000000
--- a/libX11/nls/ja.S90/XLC_LOCALE.pre
+++ /dev/null
@@ -1,150 +0,0 @@
-XCOMM Copyright 1995 by FUJITSU LIMITED
-XCOMM This is source code modified by FUJITSU LIMITED under the Joint
-XCOMM Development Agreement for the CDEnext PST.
-XCOMM This is unpublished proprietary source code of FUJITSU LIMITED
-XCOMM
-XCOMM NLS-DB for ja_JP.S90
-
-XCOMM
-XCOMM XLC_CHARSET_DEFINE category
-XCOMM
-XLC_CHARSET_DEFINE
-csd0 {
- charset_name u90x03.1991-0
- side GL
- length 2
- gc_number 94
- string_encoding False
- sequence \x1b\x25\x28\x32
- encoding_name fujitsu.U90X03
-}
-
-csd1 {
- charset_name u90x03.1991-0
- side GR
- length 2
- gc_number 94
- string_encoding False
- sequence \x1b\x25\x2f\x32
- encoding_name fujitsu.U90X03
-}
-END XLC_CHARSET_DEFINE
-
-XCOMM
-XCOMM XLC_FONTSET category
-XCOMM
-XLC_FONTSET
-XCOMM fs0 class (7 bit ASCII)
-fs0 {
- charset {
- name JISX0201.1976-0:GL
- }
- font {
- primary JISX0201.1976-0:GL
- substitute ISO8859-1:GL
- vertical_rotate all
- }
-}
-XCOMM fs1 class (Kanji)
-fs1 {
- charset {
- name JISX0208.1983-0:GL
- udc_area \x7521,\x7e7e
- }
- font {
- primary fujitsu.u90x01.1991-0:GL,[\x2121,\x747e];\
- fujitsu.u90x03.1991-0:GL,[\x7521,\x7e7e]->\x6521
- substitute u90x01.1991-0:GL;\
- JISX0208.1983-0:GL; JISX0208.1983-0:GR;\
- JISX0208.1983-1:GL; JISX0208.1983-1:GR;\
- JISX0208.1990-0:GL; JISX0208.1990-0:GR
- vertical_map u90x01.1991-0.2:GL,\
- [\x2122,\x2125]->\x7d21,[\x2131,\x2132]->\x7d25,\
- [\x213c,\x213e]->\x7d27,[\x2141,\x215b]->\x7d2a,\
- [\x2421,\x2421]->\x7d45,[\x2423,\x2423]->\x7d46,\
- [\x2425,\x2425]->\x7d47,[\x2427,\x2427]->\x7d48,\
- [\x2429,\x2429]->\x7d49,[\x2443,\x2443]->\x7d4a,\
- [\x2463,\x2463]->\x7d4b,[\x2465,\x2465]->\x7d4c,\
- [\x2467,\x2467]->\x7d4d,[\x246e,\x246e]->\x7d4e,\
- [\x2521,\x2521]->\x7d4f,[\x2523,\x2523]->\x7d50,\
- [\x2525,\x2525]->\x7d51,[\x2527,\x2527]->\x7d52,\
- [\x2529,\x2529]->\x7d53,[\x2543,\x2543]->\x7d54,\
- [\x2563,\x2563]->\x7d55,[\x2565,\x2565]->\x7d56,\
- [\x2567,\x2567]->\x7d57,[\x256e,\x256e]->\x7d58,\
- [\x2575,\x2576]->\x7d59,[\x2475,\x2476]->\x7d5b
- }
-}
-XCOMM fs2 class (Half Kana)
-fs2 {
- charset {
- name JISX0201.1976-0:GR
- }
- font {
- primary JISX0201.1976-0:GR
- vertical_rotate all
- }
-}
-XCOMM fs3 class (JEF Kanji + User Defined Character)
-fs3 {
- charset {
- name u90x03.1991-0:GR; u90x03.1991-0:GL
- udc_area \x6521,\x787e
- }
- font {
- primary fujitsu.u90x03.1991-0:GL
- substitute u90x03.1991-0:GL;\
- JISX0208.1983-0:GL; JISX0208.1983-0:GR;\
- JISX0208.1983-1:GL; JISX0208.1983-1:GR;\
- JISX0208.1990-0:GL; JISX0208.1990-0:GR
- }
-}
-END XLC_FONTSET
-
-XCOMM
-XCOMM XLC_XLOCALE category
-XCOMM
-XLC_XLOCALE
-
-XCOMM encoding_name ja.euc
-encoding_name ja_JP.S90
-mb_cur_max 3
-state_depend_encoding False
-
-wc_encoding_mask \x30000000
-wc_shift_bits 7
-
-
-XCOMM cs0 class
-cs0 {
- side GL:Default
- length 1
- wc_encoding \x00000000
- ct_encoding JISX0201.1976-0:GL; ISO8859-1:GL
-}
-
-XCOMM cs1 class
-cs1 {
- side GR:Default
- length 2
- wc_encoding \x30000000
- ct_encoding JISX0208.1983-0:GL; JISX0208.1983-0:GR;\
- JISX0208.1983-1:GL; JISX0208.1983-1:GR
-}
-
-XCOMM cs2 class
-cs2 {
- side GR
- length 1
- mb_encoding <SS> \x8e
- wc_encoding \x10000000
- ct_encoding JISX0201.1976-0:GR
-}
-XCOMM cs3 class
-cs3 {
- side GR
- length 2
- mb_encoding <SS> \x8f
- wc_encoding \x20000000
- ct_encoding u90x03.1991-0:GR; u90x03.1991-0:GL
-}
-END XLC_XLOCALE
diff --git a/libX11/nls/ja.U90/XI18N_OBJS b/libX11/nls/ja.U90/XI18N_OBJS
deleted file mode 100644
index 8c766a958..000000000
--- a/libX11/nls/ja.U90/XI18N_OBJS
+++ /dev/null
@@ -1,7 +0,0 @@
-# CATEGORY(XLC|XIM|OM) SHARED_LIBRARY_NAME FUNCTION_NAME
-#
-# XI18N objects table for ja.U90 locale
-#
-XLC common/xlibi18n _XlcGenericLoader # XLC_open
-XIM common/ximcp _XimOpenIM _XimRegisterIMInstantiateCallback _XimUnRegisterIMInstantiateCallback # XIM_open XIM_register XIM_unregister
-XOM common/xomGeneric _XomGenericOpenOM # XOM_open
diff --git a/libX11/nls/ja.U90/XLC_LOCALE.pre b/libX11/nls/ja.U90/XLC_LOCALE.pre
deleted file mode 100644
index 5d8fd3c0a..000000000
--- a/libX11/nls/ja.U90/XLC_LOCALE.pre
+++ /dev/null
@@ -1,151 +0,0 @@
-XCOMM Copyright 1995 by FUJITSU LIMITED
-XCOMM This is source code modified by FUJITSU LIMITED under the Joint
-XCOMM Development Agreement for the CDEnext PST.
-XCOMM This is unpublished proprietary source code of FUJITSU LIMITED
-XCOMM
-XCOMM NLS-DB for ja_JP.U90
-
-XCOMM
-XCOMM XLC_CHARSET_DEFINE category
-XCOMM
-XLC_CHARSET_DEFINE
-csd0 {
- charset_name u90x03.1991-0
- side GL
- length 2
- gc_number 94
- string_encoding False
- sequence \x1b\x25\x28\x32
- encoding_name fujitsu.U90X03
-}
-
-csd1 {
- charset_name u90x03.1991-0
- side GR
- length 2
- gc_number 94
- string_encoding False
- sequence \x1b\x25\x2f\x32
- encoding_name fujitsu.U90X03
-}
-END XLC_CHARSET_DEFINE
-
-XCOMM
-XCOMM XLC_FONTSET category
-XCOMM
-XLC_FONTSET
-XCOMM fs0 class (7 bit ASCII)
-fs0 {
- charset {
- name JISX0201.1976-0:GL
- }
- font {
- primary JISX0201.1976-0:GL
- substitute ISO8859-1:GL
- vertical_rotate all
- }
-}
-XCOMM fs1 class (Kanji)
-fs1 {
- charset {
- name JISX0208.1983-0:GL
- }
- font {
- primary fujitsu.u90x01.1991-0:GL
-XCOMM primary JISX0208.1983-0:GL
- substitute JISX0208.1983-0:GL; JISX0208.1983-0:GR;\
- JISX0208.1983-1:GL; JISX0208.1983-1:GR;\
- JISX0208.1990-0:GL; JISX0208.1990-0:GR;\
- u90x01.1991-0:GL
- vertical_map u90x01.1991-0.2:GL,\
- [\x2122,\x2125]->\x7d21,[\x2131,\x2132]->\x7d25,\
- [\x213c,\x213e]->\x7d27,[\x2141,\x215b]->\x7d2a,\
- [\x2421,\x2421]->\x7d45,[\x2423,\x2423]->\x7d46,\
- [\x2425,\x2425]->\x7d47,[\x2427,\x2427]->\x7d48,\
- [\x2429,\x2429]->\x7d49,[\x2443,\x2443]->\x7d4a,\
- [\x2463,\x2463]->\x7d4b,[\x2465,\x2465]->\x7d4c,\
- [\x2467,\x2467]->\x7d4d,[\x246e,\x246e]->\x7d4e,\
- [\x2521,\x2521]->\x7d4f,[\x2523,\x2523]->\x7d50,\
- [\x2525,\x2525]->\x7d51,[\x2527,\x2527]->\x7d52,\
- [\x2529,\x2529]->\x7d53,[\x2543,\x2543]->\x7d54,\
- [\x2563,\x2563]->\x7d55,[\x2565,\x2565]->\x7d56,\
- [\x2567,\x2567]->\x7d57,[\x256e,\x256e]->\x7d58,\
- [\x2575,\x2576]->\x7d59,[\x2475,\x2476]->\x7d5b
- }
-}
-XCOMM fs2 class (Half Kana)
-fs2 {
- charset {
- name JISX0201.1976-0:GR
- }
- font {
- primary JISX0201.1976-0:GR
- vertical_rotate all
- }
-}
-XCOMM fs3 class (JEF Kanji + User Defined Character)
-fs3 {
- charset {
- name u90x03.1991-0:GR; u90x03.1991-0:GL
- udc_area \x6521,\x787e
- }
- font {
- primary fujitsu.u90x03.1991-0:GL
- substitute u90x03.1991-0:GL;\
- JISX0208.1983-0:GL; JISX0208.1983-0:GR;\
- JISX0208.1983-1:GL; JISX0208.1983-1:GR;\
- JISX0208.1990-0:GL; JISX0208.1990-0:GR
- }
-}
-END XLC_FONTSET
-
-XCOMM
-XCOMM XLC_XLOCALE category
-XCOMM
-XLC_XLOCALE
-
-XCOMM encoding_name ja.euc
-encoding_name ja_JP.U90
-mb_cur_max 3
-state_depend_encoding False
-
-wc_encoding_mask \x30000000
-wc_shift_bits 7
-
-
-XCOMM cs0 class
-cs0 {
- side GL:Default
- length 1
- wc_encoding \x00000000
- ct_encoding JISX0201.1976-0:GL; ISO8859-1:GL
-}
-
-XCOMM cs1 class
-cs1 {
- side GR:Default
- length 2
- wc_encoding \x30000000
- ct_encoding JISX0208.1983-0:GL; JISX0208.1983-0:GR;\
- JISX0208.1983-1:GL; JISX0208.1983-1:GR
-}
-
-XCOMM cs2 class
-cs2 {
- side GR
- length 1
- mb_encoding <SS> \x8e
- wc_encoding \x10000000
- ct_encoding JISX0201.1976-0:GR
-}
-
-XCOMM cs3 class
-cs3 {
- side GR
- length 2
- mb_encoding <SS> \x8f
- wc_encoding \x20000000
- ct_encoding u90x03.1991-0:GR; u90x03.1991-0:GL
-}
-
-END XLC_XLOCALE
diff --git a/libX11/nls/ja_JP.UTF-8/Compose.pre b/libX11/nls/ja_JP.UTF-8/Compose.pre
index e69de29bb..6c2c4114d 100644
--- a/libX11/nls/ja_JP.UTF-8/Compose.pre
+++ b/libX11/nls/ja_JP.UTF-8/Compose.pre
@@ -0,0 +1 @@
+include "X11_LOCALEDATADIR/en_US.UTF-8/Compose"
diff --git a/libX11/nls/km_KH.UTF-8/Compose.pre b/libX11/nls/km_KH.UTF-8/Compose.pre
new file mode 100644
index 000000000..77651d085
--- /dev/null
+++ b/libX11/nls/km_KH.UTF-8/Compose.pre
@@ -0,0 +1,8 @@
+include "X11_LOCALEDATADIR/en_US.UTF-8/Compose"
+
+# Khmer digraphs
+<U17ff> : "ាំ"
+<U17fe> : "ោះ"
+<U17fd> : "េះ"
+<U17fc> : "ុំ"
+<U17fb> : "ុះ"
diff --git a/libX11/nls/km_KH.UTF-8/XI18N_OBJS b/libX11/nls/km_KH.UTF-8/XI18N_OBJS
new file mode 100644
index 000000000..f201bf435
--- /dev/null
+++ b/libX11/nls/km_KH.UTF-8/XI18N_OBJS
@@ -0,0 +1,8 @@
+# CATEGORY(XLC|XIM|OM) SHARED_LIBRARY_NAME FUNCTION_NAME
+#
+# XI18N objects table for euro locales
+#
+XLC common/xlcUTF8Load _XlcUtf8Loader # XLC_open
+XOM common/xomLTRTTB _XomGenericOpenOM # XOM_open
+XIM common/xiiimp _SwitchOpenIM # XIM_open
+XIM common/xiiimp _XimpLocalOpenIM # XIM_open
diff --git a/libX11/nls/ja.S90/Compose.pre b/libX11/nls/km_KH.UTF-8/XLC_LOCALE.pre
index e69de29bb..e69de29bb 100644
--- a/libX11/nls/ja.S90/Compose.pre
+++ b/libX11/nls/km_KH.UTF-8/XLC_LOCALE.pre
diff --git a/libX11/nls/ko_KR.UTF-8/Compose.pre b/libX11/nls/ko_KR.UTF-8/Compose.pre
index e69de29bb..6c2c4114d 100644
--- a/libX11/nls/ko_KR.UTF-8/Compose.pre
+++ b/libX11/nls/ko_KR.UTF-8/Compose.pre
@@ -0,0 +1 @@
+include "X11_LOCALEDATADIR/en_US.UTF-8/Compose"
diff --git a/libX11/nls/locale.alias.pre b/libX11/nls/locale.alias.pre
index 7b3546099..11d93f26e 100644
--- a/libX11/nls/locale.alias.pre
+++ b/libX11/nls/locale.alias.pre
@@ -17,9 +17,11 @@ Cextend.en: en_US.ISO8859-1
English_United-States.437: C
C.UTF-8: en_US.UTF-8
XCOMM a3 is not an ISO 639 language code, but in Cyrillic, "Z" looks like "3".
-a3: a3_AZ.KOI8-C
-a3_AZ: a3_AZ.KOI8-C
-a3_AZ.koi8c: a3_AZ.KOI8-C
+a3: az_AZ.KOI8-C
+a3_AZ: az_AZ.KOI8-C
+a3_AZ.koi8c: az_AZ.KOI8-C
+a3_AZ.KOI-C: az_AZ.KOI8-C
+a3_AZ.UTF-8: az_AZ.UTF-8
af: af_ZA.ISO8859-1
af_ZA: af_ZA.ISO8859-1
af_ZA.iso88591: af_ZA.ISO8859-1
@@ -50,6 +52,7 @@ ar_EG: ar_EG.ISO8859-6
ar_EG.iso88596: ar_EG.ISO8859-6
ar_EG.ISO-8859-6: ar_EG.ISO8859-6
ar_EG.utf8: ar_EG.UTF-8
+ar_IN: ar_IN.UTF-8
ar_IN.utf8: ar_IN.UTF-8
ar_IQ: ar_IQ.ISO8859-6
ar_IQ.iso88596: ar_IQ.ISO8859-6
@@ -100,6 +103,7 @@ ar_TN.iso88596: ar_TN.ISO8859-6
ar_TN.ISO-8859-6: ar_TN.ISO8859-6
ar_TN.utf8: ar_TN.UTF-8
as: as_IN.UTF-8
+as_IN: as_IN.UTF-8
as_IN.utf8: as_IN.UTF-8
ar_YE: ar_YE.ISO8859-6
ar_YE.iso88596: ar_YE.ISO8859-6
@@ -128,7 +132,9 @@ bg_BG.iso88595: bg_BG.ISO8859-5
bg_BG.ISO-8859-5: bg_BG.ISO8859-5
bg_BG.koi8r: bg_BG.KOI8-R
be_BG.utf8: bg_BG.UTF-8
+bn_IN: bn_IN.UTF-8
bn_IN.utf8: bn_IN.UTF-8
+bo_IN: bo_IN.UTF-8
bo_IN.utf8: bo_IN.UTF-8
br: br_FR.ISO8859-1
br_FR: br_FR.ISO8859-1
@@ -188,7 +194,7 @@ cs_CS: cs_CZ.ISO8859-2
cs_CS.ISO8859-2: cs_CZ.ISO8859-2
cs_CZ: cs_CZ.ISO8859-2
cs_CZ.iso88592: cs_CZ.ISO8859-2
-cs_CS.iso8859-2: cs_CS.ISO8859-2
+cs_CS.iso8859-2: cs_CZ.ISO8859-2
cs_CZ.ISO-8859-2: cs_CZ.ISO8859-2
cs_CZ.ISO_8859-2: cs_CZ.ISO8859-2
cs_CZ.utf8: cs_CZ.UTF-8
@@ -297,6 +303,7 @@ en_BE: en_BE.ISO8859-1
en_BE@euro: en_BE.ISO8859-15
en_BE.utf8: en_BE.UTF-8
en_BW: en_BW.ISO8859-1
+en_BW.utf8: en_BW.UTF-8
en_BW.iso88591: en_BW.ISO8859-1
en_BW.ISO-8859-1: en_BW.ISO8859-1
en_CA: en_CA.ISO8859-1
@@ -304,6 +311,7 @@ en_CA.iso88591: en_CA.ISO8859-1
en_CA.ISO-8859-1: en_CA.ISO8859-1
en_CA.ISO_8859-1: en_CA.ISO8859-1
en_CA.utf8: en_CA.UTF-8
+en_DL.utf8: en_DL.UTF-8
en_GB: en_GB.ISO8859-1
en_GB.88591: en_GB.ISO8859-1
en_GB.88591.en: en_GB.ISO8859-1
@@ -319,6 +327,7 @@ ENG_GB.8859.in: en_GB.ISO8859-1
en_HK: en_HK.ISO8859-1
en_HK.iso88591: en_HK.ISO8859-1
en_HK.ISO-8859-1: en_HK.ISO8859-1
+en_HK.utf8: en_HK.UTF-8
en_IE: en_IE.ISO8859-1
en_IE.iso88591: en_IE.ISO8859-1
en_IE.ISO-8859-1: en_IE.ISO8859-1
@@ -328,15 +337,18 @@ en_IE.ISO-8859-15@euro: en_IE.ISO8859-15
en_IE@euro: en_IE.ISO8859-15
en_IE.UTF-8@euro: en_IE.UTF-8
en_IE.utf8: en_IE.UTF-8
+en_IN.utf8: en_IN.UTF-8
en_IN: en_IN.ISO8859-1
en_NZ: en_NZ.ISO8859-1
en_NZ.iso88591: en_NZ.ISO8859-1
en_NZ.ISO-8859-1: en_NZ.ISO8859-1
en_NZ.utf8: en_NZ.UTF-8
en_PH: en_PH.ISO8859-1
+en_PH.utf8: en_PH.UTF-8
en_PH.iso88591: en_PH.ISO8859-1
en_PH.ISO-8859-1: en_PH.ISO8859-1
en_SG: en_SG.ISO8859-1
+en_SG.utf8: en_SG.UTF-8
en_SG.iso88591: en_SG.ISO8859-1
en_SG.ISO-8859-1: en_SG.ISO8859-1
en_US: en_US.ISO8859-1
@@ -362,6 +374,7 @@ en_ZA.iso885915: en_ZA.ISO8859-15
en_ZA.ISO-8859-15: en_ZA.ISO8859-15
en_ZA.utf8: en_ZA.UTF-8
en_ZW: en_ZW.ISO8859-1
+en_ZW.utf8: en_ZS.UTF-8
en_ZW.iso88591: en_ZW.ISO8859-1
en_ZW.ISO-8859-1: en_ZW.ISO8859-1
eo: eo_XX.ISO8859-3
@@ -602,6 +615,7 @@ gl_ES.ISO-8859-15@euro: gl_ES.ISO8859-15
gl_ES@euro: gl_ES.ISO8859-15
gl_ES.UTF-8@euro: gl_ES.UTF-8
gl_ES.utf8: gl_ES.UTF-8
+gu_IN: gu_IN.UTF-8
gu_IN.utf8: gu_IN.UTF-8
gv: gv_GB.ISO8859-1
gv_GB: gv_GB.ISO8859-1
@@ -629,6 +643,7 @@ hi_IN.isciidev: hi_IN.ISCII-DEV
hi_IN.utf8: hi_IN.UTF-8
HI_IN.UTF-8: hi_IN.UTF-8
hne: hne_IN.UTF-8
+hne_IN: hne_IN.UTF-8
hne_IN.utf8: hne_IN.UTF-8
hr: hr_HR.ISO8859-2
hr_HR: hr_HR.ISO8859-2
@@ -674,6 +689,8 @@ it_IT.ISO-8859-15@euro: it_IT.ISO8859-15
it_IT@euro: it_IT.ISO8859-15
it_IT.utf8: it_IT.UTF-8
it_IT.UTF-8@euro: it_IT.UTF-8
+XCOMM NUNACOM is an encoding for the Inuktitut syllabics
+XCOMM we have little else on this encoding.
iu: iu_CA.NUNACOM-8
iu_CA: iu_CA.NUNACOM-8
iu_CA.nunacom8: iu_CA.NUNACOM-8
@@ -684,13 +701,7 @@ iw_IL: he_IL.ISO8859-8
Iw_IL: he_IL.ISO8859-8
iw_IL.iso88598: he_IL.ISO8859-8
iw_IL.ISO-8859-8: he_IL.ISO8859-8
-#ifndef __uxp__
ja_JP: ja_JP.eucJP
-#else /* __uxp__ */
-ja_JP: ja_JP.U90
-ja_JP.U90: ja_JP.U90
-ja_JP.S90: ja_JP.S90
-#endif /* __uxp__ */
ja: ja_JP.eucJP
ja.JIS: ja_JP.JIS7
ja.SJIS: ja_JP.SJIS
@@ -721,7 +732,10 @@ kl_GL.iso88591: kl_GL.ISO8859-1
kl_GL.ISO-8859-1: kl_GL.ISO8859-1
kl_GL.iso885915: kl_GL.ISO8859-15
kl_GL.utf8: kl_GL.UTF-8
+km_KH: mk_KH.UTF-8
+km_KH.utf8: mk_KH.UTF-8
kn: kn_IN.UTF-8
+kn_IN: kn_IN.UTF-8
kn_IN.utf8: kn_IN.UTF-8
ko: ko_KR.eucKR
ko.UTF-8: ko_KR.UTF-8
@@ -734,6 +748,7 @@ ko_KR.euckr: ko_KR.eucKR
ko_KR.utf8: ko_KR.UTF-8
KO_KR.UTF-8: ko_KR.UTF-8
ks: ks_IN.UTF-8
+ks_IN: ks_IN.UTF-8
ks_IN.utf8: ks_IN.UTF-8
ks_IN@devanagari: ks_IN@devanagari.UTF-8
ks_IN@devanagari.utf8: ks_IN@devanagari.UTF-8
@@ -748,6 +763,7 @@ kw_GB.ISO-8859-15: kw_GB.ISO8859-15
ky: ky_KG.UTF-8
ky_KG: ky_KG.UTF-8
ky_KG.UTF-8: ky_KG.UTF-8
+ky_KG.utf8: ky_KG.UTF-8
lo: lo_LA.MULELAO-1
lo_LA: lo_LA.MULELAO-1
lo_LA.cp1133: lo_LA.IBM-CP1133
@@ -778,6 +794,7 @@ lv_LV.ISO-8859-13: lv_LV.ISO8859-13
lv_LV.ISO_8859-13: lv_LV.ISO8859-13
lv_LV.utf8: lv_LV.UTF-8
mai: mai_IN.UTF-8
+mai_IN: mai_IN.UTF-8
mai_IN.utf8: mai_IN.UTF-8
mi: mi_NZ.ISO8859-1
mi_NZ: mi_NZ.ISO8859-1
@@ -792,6 +809,7 @@ mk_MK.microsoft-cp1251: mk_MK.CP1251
mk_MK.MICROSOFT-CP1251: mk_MK.CP1251
mk_MK.utf8: mk_MK.UTF-8
ml: ml_IN.UTF-8
+ml_IN: ml_IN.UTF-8
ml_IN.utf8: ml_IN.UTF-8
mr: mr_IN.UTF-8
mr_IN: mr_IN.UTF-8
@@ -811,6 +829,7 @@ nb_NO.ISO-8859-1: nb_NO.ISO8859-1
nb_NO.iso885915: nb_NO.ISO8859-15
nb_NO.ISO-8859-15: nb_NO.ISO8859-15
nb_NO.utf8: nb_NO.UTF-8
+ne_NP: ne_NP.UTF-8
ne_NP.utf8: ne_NP.UTF-8
nl: nl_NL.ISO8859-1
nl.ISO8859-15: nl_NL.ISO8859-15
@@ -880,8 +899,10 @@ oc_FR.iso885915: oc_FR.ISO8859-15
oc_FR.ISO-8859-15: oc_FR.ISO8859-15
oc_FR@euro: oc_FR.ISO8859-15
or: or_IN.UTF-8
+or_IN: or_IN.UTF-8
or_IN.utf8: or_IN.UTF-8
pa: pa_IN.UTF-8
+pa_IN: pa_IN.UTF-8
pa_IN.utf8: pa_IN.UTF-8
pa_PK.utf8: pa_PK.UTF-8
pd: pd_US.ISO8859-1
@@ -961,7 +982,8 @@ rw_RW.ISO-8859-1: rw_RW.ISO8859-1
rw_RW.utf8: rw_RW.UTF-8
sd: sd_IN.UTF-8
sd_IN.utf8: sd_IN.UTF-8
-sd: sd_IN@devanagari.UTF-8
+sd@devanagari: sd_IN@devanagari.UTF-8
+sd_IN@devanagari: sd_IN@devanagari.UTF-8
sd_IN@devanagari.utf8: sd_IN@devanagari.UTF-8
se_NO: se_NO.UTF-8
se_NO.utf8: se_NO.UTF-8
@@ -1000,11 +1022,11 @@ sr@cyrillic: sr_RS.UTF-8
sr_YU@cyrillic: sr_RS.UTF-8
sr_YU.utf8: sr_RS.UTF-8
sr_YU.UTF-8@cyrillic: sr_RS.UTF-8
-sr_CS: sr_RS.UTF-8
-sr@Latn: sr_RS.UTF-8@latin
-sr_CS@Latn: sr_RS.UTF-8@latin
-sr_CS.utf8: sr_RS.UTF-8
-sr_CS.UTF-8@Latn: sr_RS.UTF-8@latin
+sr_CS: sr_CS.UTF-8
+sr@Latn: sr_CS.UTF-8@latin
+sr_CS@Latn: sr_CS.UTF-8@latin
+sr_CS.utf8: sr_CS.UTF-8
+sr_CS.UTF-8@Latn: sr_CS.UTF-8@latin
sr_RS: sr_RS.UTF-8
sr@latin: sr_RS.UTF-8@latin
sr_RS@latin: sr_RS.UTF-8@latin
@@ -1048,6 +1070,7 @@ ta_IN: ta_IN.TSCII-0
ta_IN.tscii: ta_IN.TSCII-0
ta_IN.tscii0: ta_IN.TSCII-0
te: te_IN.UTF-8
+te.UTF-8: te_IN.UTF-8
te_IN.utf8: te_IN.UTF-8
tg: tg_TJ.KOI8-C
tg_TJ: tg_TJ.KOI8-C
@@ -1092,6 +1115,7 @@ uk_UA.microsoft-cp1251: uk_UA.CP1251
uk_UA.MICROSOFT-CP1251: uk_UA.CP1251
uk_UA.utf8: uk_UA.UTF-8
ur: ur_IN.UTF-8
+ur_IN: ur_IN.UTF-8
ur_IN.utf8: ur_IN.UTF-8
ur: ur_PK.CP1256
ur_PK: ur_PK.CP1256
@@ -1153,6 +1177,10 @@ zh_HK.Big5_hkscs: zh_HK.big5hkscs
zh_HK.Big5HKSCS: zh_HK.big5hkscs
zh_HK.BIG5-HKSCS: zh_HK.big5hkscs
zh_HK.BIG5_HKSCS: zh_HK.big5hkscs
+zh_HK.Big5-HKSCS: zh_HK.big5hkscs
+zh_HK.big5-hkscs: zh_HK.big5hkscs
+zh_HK.Big5-HKSCS: zh_HK.big5hkscs
+zh_HK.Big5HKSCS: zh_HK.big5hkscs
zh_HK.Big5: zh_HK.big5
zh_HK.utf8: zh_HK.UTF-8
ZH_HK.UTF-8: zh_HK.UTF-8
@@ -1210,8 +1238,8 @@ german: de_DE.ISO8859-1
german.iso88591: de_CH.ISO8859-1
greek: el_GR.ISO8859-7
greek.iso88597: el_GR.ISO8859-7
-hebrew: iw_IL.ISO8859-8
-hebrew.iso88598: iw_IL.ISO8859-8
+hebrew: he_IL.ISO8859-8
+hebrew.iso88598: he_IL.ISO8859-8
hrvatski: hr_HR.ISO8859-2
hungarian: hu_HU.ISO8859-2
icelandic.iso88591: is_IS.ISO8859-1
@@ -1254,102 +1282,102 @@ iso_8859_15: en_US.ISO8859-15
#ifdef WIN32
XCOMM Microsoft Windows/NT 4.0 SP3
XCOMM parser doesn't grok embedded spaces in locale name
-Afrikaans_South Africa.1252: af_ZA.iso8859-1
-Arabic_Bahrain.1256: ar_BH.iso8859-6
-Arabic_Algeria.1256: ar_DZ.iso8859-6
-Arabic_Egypt.1256: ar_EG.iso8859-6
-Arabic_Iraq.1256: ar_IQ.iso8859-6
-Arabic_Jordan.1256: ar_JO.iso8859-6
-Arabic_Kuwait.1256: ar_KW.iso8859-6
-Arabic_Lebanon.1256: ar_LB.iso8859-6
-Arabic_Libya.1256: ar_LY.iso8859-6
-Arabic_Morocco.1256: ar_MA.iso8859-6
-Arabic_Oman.1256: ar_OM.iso8859-6
-Arabic_Qatar.1256: ar_QA.iso8859-6
-Arabic_Saudi Arabia.1256: ar_SA.iso8859-6
-Arabic_Tunisia.1256: ar_TN.iso8859-6
-Arabic_Yemen.1256: ar_YE.iso8859-6
-Belarusian_Belarus.1251: be_BY.iso8859-5
-Bulgarian_Bulgaria.1251: bg_BG.iso8859-5
-Catalan_Andorra.1252: ca_AD.iso8859-1
-Catalan_Spain.1252: ca_ES.iso8859-1
-Catalan_France.1252: ca_FR.iso8859-1
-Catalan_Italy.1252: ca_IT.iso8859-1
-Czech_Czech Republic.1250: cs_CZ.iso8859-2
-Danish_Denmark.1252: da_DK.iso8859-1
-German_Austria.1252: de_AT.iso8859-1
-German_Switzerland.1252: de_CH.iso8859-1
-German_Germany.1252: de_DE.iso8859-1
-German_Liechtenstein.1252: de_LI.iso8859-1
-German_Luxembourg.1252: de_LU.iso8859-1
-Greek_Greece.1253: el_GR.iso8859-7
-English_Australia.1252: en_AU.iso8859-1
-English_Belize.1252: en_BZ.iso8859-1
-English_Canada.1252: en_CA.iso8859-1
-English_Ireland.1252: en_IE.iso8859-1
-English_Jamaica.1252: en_JM.iso8859-1
-English_New Zealand.1252: en_NZ.iso8859-1
-English_Trinidad y Tobago.1252: en_TT.iso8859-1
-English_United Kingdom.1252: en_UK.iso8859-1
-English_United States.1252: en_US.iso8859-1
-English_South Africa.1252: en_ZA.iso8859-1
-Spanish_Argentina.1252: es_AR.iso8859-1
-Spanish_Bolivia.1252: es_BO.iso8859-1
-Spanish_Chile.1252: es_CL.iso8859-1
-Spanish_Colombia.1252: es_CO.iso8859-1
-Spanish_Costa Rica.1252: es_CR.iso8859-1
-Spanish_Dominican Republic.1252: es_DO.iso8859-1
-Spanish_Ecuador.1252: es_EC.iso8859-1
-Spanish - Modern Sort_Spain.1252: es_ES.iso8859-1
-Spanish - Traditional Sort_Spain.1252: es_ES.iso8859-1
-Spanish_Guatemala.1252: es_GT.iso8859-1
-Spanish_Honduras.1252: es_HN.iso8859-1
-Spanish_Mexican.1252: es_MX.iso8859-1
-Spanish_Nicaragua.1252: es_NI.iso8859-1
-Spanish_Panama.1252: es_PA.iso8859-1
-Spanish_Paraguay.1252: es_PY.iso8859-1
-Spanish_Peru.1252: es_PE.iso8859-1
-Spanish_Puerto Rico.1252: es_PR.iso8859-1
-Spanish_El Salvador.1252: es_SV.iso8859-1
-Spanish_Uruguay.1252: es_UY.iso8859-1
-Spanish_Venezuela.1252: es_VE.iso8859-1
-Estonian_Estonia.1257: et_EE.iso8859-13
-Basque_Spain.1252: eu_ES.iso8859-1
-Finnish_Finland.1252: fi_FI.iso8859-1
-French_Belgium.1252: fr_BE.iso8859-1
-French_Canada.1252: fr_CA.iso8859-1
-French_Switzerland.1252: fr_CH.iso8859-1
-French_France.1252: fr_FR.iso8859-1
-French_Luxembourg.1252: fr_LU.iso8859-1
-Faeroese_Faeroe Islands.1252: fo_FO.iso8859-1
-Hebrew_Israel.1255: he_IL.iso8859-8
-Croatian_Croatia.1250: hr_HR.iso8859-2
-Hungarian_Hungary.1250: hu_HU.iso8859-2
-Indonesian_Indonesia.1252: id_ID.iso8859-1
-Icelandic_Iceland.1252: is_IS.iso8859-1
-Italian_Switzerland.1252: it_CH.iso8859-1
-Italian_Italy.1252: it_IT.iso8859-1
+Afrikaans_South Africa.1252: af_ZA.ISO8859-1
+Arabic_Bahrain.1256: ar_BH.ISO8859-6
+Arabic_Algeria.1256: ar_DZ.ISO8859-6
+Arabic_Egypt.1256: ar_EG.ISO8859-6
+Arabic_Iraq.1256: ar_IQ.ISO8859-6
+Arabic_Jordan.1256: ar_JO.ISO8859-6
+Arabic_Kuwait.1256: ar_KW.ISO8859-6
+Arabic_Lebanon.1256: ar_LB.ISO8859-6
+Arabic_Libya.1256: ar_LY.ISO8859-6
+Arabic_Morocco.1256: ar_MA.ISO8859-6
+Arabic_Oman.1256: ar_OM.ISO8859-6
+Arabic_Qatar.1256: ar_QA.ISO8859-6
+Arabic_Saudi Arabia.1256: ar_SA.ISO8859-6
+Arabic_Tunisia.1256: ar_TN.ISO8859-6
+Arabic_Yemen.1256: ar_YE.ISO8859-6
+Belarusian_Belarus.1251: be_BY.ISO8859-5
+Bulgarian_Bulgaria.1251: bg_BG.ISO8859-5
+Catalan_Andorra.1252: ca_AD.ISO8859-1
+Catalan_Spain.1252: ca_ES.ISO8859-1
+Catalan_France.1252: ca_FR.ISO8859-1
+Catalan_Italy.1252: ca_IT.ISO8859-1
+Czech_Czech Republic.1250: cs_CZ.ISO8859-2
+Danish_Denmark.1252: da_DK.ISO8859-1
+German_Austria.1252: de_AT.ISO8859-1
+German_Switzerland.1252: de_CH.ISO8859-1
+German_Germany.1252: de_DE.ISO8859-1
+German_Liechtenstein.1252: de_LI.ISO8859-1
+German_Luxembourg.1252: de_LU.ISO8859-1
+Greek_Greece.1253: el_GR.ISO8859-7
+English_Australia.1252: en_AU.ISO8859-1
+English_Belize.1252: en_BZ.ISO8859-1
+English_Canada.1252: en_CA.ISO8859-1
+English_Ireland.1252: en_IE.ISO8859-1
+English_Jamaica.1252: en_JM.ISO8859-1
+English_New Zealand.1252: en_NZ.ISO8859-1
+English_Trinidad y Tobago.1252: en_TT.ISO8859-1
+English_United Kingdom.1252: en_UK.ISO8859-1
+English_United States.1252: en_US.ISO8859-1
+English_South Africa.1252: en_ZA.ISO8859-1
+Spanish_Argentina.1252: es_AR.ISO8859-1
+Spanish_Bolivia.1252: es_BO.ISO8859-1
+Spanish_Chile.1252: es_CL.ISO8859-1
+Spanish_Colombia.1252: es_CO.ISO8859-1
+Spanish_Costa Rica.1252: es_CR.ISO8859-1
+Spanish_Dominican Republic.1252: es_DO.ISO8859-1
+Spanish_Ecuador.1252: es_EC.ISO8859-1
+Spanish - Modern Sort_Spain.1252: es_ES.ISO8859-1
+Spanish - Traditional Sort_Spain.1252: es_ES.ISO8859-1
+Spanish_Guatemala.1252: es_GT.ISO8859-1
+Spanish_Honduras.1252: es_HN.ISO8859-1
+Spanish_Mexican.1252: es_MX.ISO8859-1
+Spanish_Nicaragua.1252: es_NI.ISO8859-1
+Spanish_Panama.1252: es_PA.ISO8859-1
+Spanish_Paraguay.1252: es_PY.ISO8859-1
+Spanish_Peru.1252: es_PE.ISO8859-1
+Spanish_Puerto Rico.1252: es_PR.ISO8859-1
+Spanish_El Salvador.1252: es_SV.ISO8859-1
+Spanish_Uruguay.1252: es_UY.ISO8859-1
+Spanish_Venezuela.1252: es_VE.ISO8859-1
+Estonian_Estonia.1257: et_EE.ISO8859-13
+Basque_Spain.1252: eu_ES.ISO8859-1
+Finnish_Finland.1252: fi_FI.ISO8859-1
+French_Belgium.1252: fr_BE.ISO8859-1
+French_Canada.1252: fr_CA.ISO8859-1
+French_Switzerland.1252: fr_CH.ISO8859-1
+French_France.1252: fr_FR.ISO8859-1
+French_Luxembourg.1252: fr_LU.ISO8859-1
+Faeroese_Faeroe Islands.1252: fo_FO.ISO8859-1
+Hebrew_Israel.1255: he_IL.ISO8859-8
+Croatian_Croatia.1250: hr_HR.ISO8859-2
+Hungarian_Hungary.1250: hu_HU.ISO8859-2
+Indonesian_Indonesia.1252: id_ID.ISO8859-1
+Icelandic_Iceland.1252: is_IS.ISO8859-1
+Italian_Switzerland.1252: it_CH.ISO8859-1
+Italian_Italy.1252: it_IT.ISO8859-1
Japanese_Japan.932: ja_JP.SJIS
Korean_Korea.949: ko_KR.EUC
-Lithuanian_Lithuania.1257: lt_LT.iso8859-13
-Latvian_Latvia.1257: lv_LV.iso8859-13
-Dutch_Belgium.1252: nl_BE.iso8859-1
-Dutch_Netherlands.1252: nl_NL.iso8859-1
-Norwegian (Nynorsk)_Norway.1252: no_NO.iso8859-1
-Norwegian (Bokml)_Norway.1252: no_NO.iso8859-1
-Polish_Poland.1250: pl_PL.iso8859-2
-Portuguese_Brazil.1252: pt_BR.iso8859-1
-Portuguese_Portugal.1252: pt_PT.iso8859-1
-Romanian_Romania.1250: ro_RO.iso8859-2
-Russian_Russia.1251: ru_RU.iso8859-5
-Slovak_Slovakia.1250: sk_SK.iso8859-2
-Slovene_Slovenia.1250: sl_SI.iso8859-2
-Albanian_Albania.1250: sq_AL.iso8859-2
+Lithuanian_Lithuania.1257: lt_LT.ISO8859-13
+Latvian_Latvia.1257: lv_LV.ISO8859-13
+Dutch_Belgium.1252: nl_BE.ISO8859-1
+Dutch_Netherlands.1252: nl_NL.ISO8859-1
+Norwegian (Nynorsk)_Norway.1252: no_NO.ISO8859-1
+Norwegian (Bokml)_Norway.1252: no_NO.ISO8859-1
+Polish_Poland.1250: pl_PL.ISO8859-2
+Portuguese_Brazil.1252: pt_BR.ISO8859-1
+Portuguese_Portugal.1252: pt_PT.ISO8859-1
+Romanian_Romania.1250: ro_RO.ISO8859-2
+Russian_Russia.1251: ru_RU.ISO8859-5
+Slovak_Slovakia.1250: sk_SK.ISO8859-2
+Slovene_Slovenia.1250: sl_SI.ISO8859-2
+Albanian_Albania.1250: sq_AL.ISO8859-2
Serbian (Latin)_Serbia.1250: sr_RS.UTF-8@latin
-Swedish_Finland.1252: sv_FI.iso8859-1
-Swedish_Sweden.1252: sv_SE.iso8859-1
-Turkish_Turkey.1254: tr_TR.iso8859-9
-Ukrainian_Ukraine.1251: uk_UA.iso8859-5
+Swedish_Finland.1252: sv_FI.ISO8859-1
+Swedish_Sweden.1252: sv_SE.ISO8859-1
+Turkish_Turkey.1254: tr_TR.ISO8859-9
+Ukrainian_Ukraine.1251: uk_UA.ISO8859-5
Chinese(PRC)_People's Republic of China.936: zh_CN.EUC
Chinese(PRC)_Hong Kong.950: zh_HK.EUC
Chinese(Singapore)_Signapore.936: zh_SG.EUC
@@ -1358,9 +1386,5 @@ Chinese(Taiwan)_Taiwan.950: zh_TW.EUC
XCOMM Other miscellaneous locale names
ISO8859-1: en_US.ISO8859-1
ISO-8859-1: en_US.ISO8859-1
-#ifndef __uxp__
japan: ja_JP.eucJP
-#else
-japan: ja_JP.U90
-#endif
Japanese-EUC: ja_JP.eucJP
diff --git a/libX11/nls/locale.dir.pre b/libX11/nls/locale.dir.pre
index e0d9ef7ef..4ec929745 100644
--- a/libX11/nls/locale.dir.pre
+++ b/libX11/nls/locale.dir.pre
@@ -24,6 +24,7 @@ iso8859-6/XLC_LOCALE: ar_SD.ISO8859-6
iso8859-6/XLC_LOCALE: ar_SY.ISO8859-6
iso8859-6/XLC_LOCALE: ar_TN.ISO8859-6
iso8859-6/XLC_LOCALE: ar_YE.ISO8859-6
+iso8859-6/XLC_LOCALE: ar_AE.ISO8859-6
iso8859-9e/XLC_LOCALE: az_AZ.ISO8859-9E
koi8-c/XLC_LOCALE: az_AZ.KOI8-C
iso8859-5/XLC_LOCALE: be_BY.ISO8859-5
@@ -47,7 +48,6 @@ iso8859-2/XLC_LOCALE: cs_CZ.ISO8859-2
iso8859-1/XLC_LOCALE: cy_GB.ISO8859-1
iso8859-14/XLC_LOCALE: cy_GB.ISO8859-14
iso8859-15/XLC_LOCALE: cy_GB.ISO8859-15
-iso8859-2/XLC_LOCALE: cz_CZ.ISO8859-2
iso8859-1/XLC_LOCALE: da_DK.ISO8859-1
iso8859-15/XLC_LOCALE: da_DK.ISO8859-15
iso8859-1/XLC_LOCALE: de_AT.ISO8859-1
@@ -59,15 +59,19 @@ iso8859-15/XLC_LOCALE: de_CH.ISO8859-15
iso8859-1/XLC_LOCALE: de_DE.ISO8859-1
iso8859-15/XLC_LOCALE: de_DE.ISO8859-15
iso8859-1/XLC_LOCALE: de_LI.ISO8859-1
+iso8859-1/XLC_LOCALE: de_LI.ISO8859-15
iso8859-1/XLC_LOCALE: de_LU.ISO8859-1
iso8859-15/XLC_LOCALE: de_LU.ISO8859-15
-iso8859-7/XLC_LOCALE: el_GR.ISO8859-7
+iso8859-7/XLC_LOCALE: el_GR.ISO8859-7
+iso8859-4/XLC_LOCALE: ee_EE.ISO8859-4
iso8859-15/XLC_LOCALE: el_GR.ISO8859-15
iso8859-1/XLC_LOCALE: en_AU.ISO8859-1
iso8859-1/XLC_LOCALE: en_BE.ISO8859-1
+iso8859-15/XLC_LOCALE: en_BE.ISO8859-15
iso8859-1/XLC_LOCALE: en_BZ.ISO8859-1
iso8859-1/XLC_LOCALE: en_BW.ISO8859-1
iso8859-1/XLC_LOCALE: en_CA.ISO8859-1
+iso8859-1/XLC_LOCALE: en_EN.ISO8859-1
iso8859-1/XLC_LOCALE: en_GB.ISO8859-1
iso8859-15/XLC_LOCALE: en_GB.ISO8859-15
iso8859-1/XLC_LOCALE: en_HK.ISO8859-1
@@ -85,6 +89,7 @@ iso8859-1/XLC_LOCALE: en_US.ISO8859-1
iso8859-15/XLC_LOCALE: en_US.ISO8859-15
iso8859-1/XLC_LOCALE: en_ZA.ISO8859-1
iso8859-15/XLC_LOCALE: en_ZA.ISO8859-15
+iso8859-1/XLC_LOCALE: en_ZW.ISO8859-1
iso8859-3/XLC_LOCALE: eo_EO.ISO8859-3
iso8859-3/XLC_LOCALE: eo_XX.ISO8859-3
iso8859-1/XLC_LOCALE: es_AR.ISO8859-1
@@ -101,13 +106,19 @@ iso8859-1/XLC_LOCALE: es_HN.ISO8859-1
iso8859-1/XLC_LOCALE: es_MX.ISO8859-1
iso8859-1/XLC_LOCALE: es_NI.ISO8859-1
iso8859-1/XLC_LOCALE: es_PA.ISO8859-1
+iso8859-15/XLC_LOCALE: es_PA.ISO8859-15
iso8859-1/XLC_LOCALE: es_PE.ISO8859-1
+iso8859-15/XLC_LOCALE: es_PE.ISO8859-15
iso8859-1/XLC_LOCALE: es_PR.ISO8859-1
iso8859-1/XLC_LOCALE: es_PY.ISO8859-1
+iso8859-15/XLC_LOCALE: es_PY.ISO8859-15
iso8859-1/XLC_LOCALE: es_SV.ISO8859-1
+iso8859-15/XLC_LOCALE: es_SV.ISO8859-15
iso8859-1/XLC_LOCALE: es_US.ISO8859-1
iso8859-1/XLC_LOCALE: es_UY.ISO8859-1
+iso8859-15/XLC_LOCALE: es_UY.ISO8859-15
iso8859-1/XLC_LOCALE: es_VE.ISO8859-1
+iso8859-15/XLC_LOCALE: es_VE.ISO8859-15
iso8859-1/XLC_LOCALE: et_EE.ISO8859-1
iso8859-4/XLC_LOCALE: et_EE.ISO8859-4
iso8859-13/XLC_LOCALE: et_EE.ISO8859-13
@@ -147,9 +158,11 @@ iso8859-2/XLC_LOCALE: hr_HR.ISO8859-2
iso8859-2/XLC_LOCALE: hu_HU.ISO8859-2
armscii-8/XLC_LOCALE: hy_AM.ARMSCII-8
iso8859-1/XLC_LOCALE: id_ID.ISO8859-1
+iso8859-1/XLC_LOCALE: id_ID.ISO8859-15
iso8859-1/XLC_LOCALE: is_IS.ISO8859-1
iso8859-15/XLC_LOCALE: is_IS.ISO8859-15
iso8859-1/XLC_LOCALE: it_CH.ISO8859-1
+iso8859-15/XLC_LOCALE: it_CH.ISO8859-15
iso8859-1/XLC_LOCALE: it_IT.ISO8859-1
iso8859-15/XLC_LOCALE: it_IT.ISO8859-15
ja/XLC_LOCALE: ja_JP.eucJP
@@ -158,6 +171,7 @@ ja.JIS/XLC_LOCALE: ja_JP.JIS7
georgian-academy/XLC_LOCALE: ka_GE.GEORGIAN-ACADEMY
georgian-ps/XLC_LOCALE: ka_GE.GEORGIAN-PS
iso8859-1/XLC_LOCALE: kl_GL.ISO8859-1
+iso8859-15/XLC_LOCALE: kl_GL.ISO8859-15
ko/XLC_LOCALE: ko_KR.eucKR
iso8859-1/XLC_LOCALE: kw_GB.ISO8859-1
iso8859-14/XLC_LOCALE: kw_GB.ISO8859-14
@@ -190,16 +204,21 @@ iso8859-1/XLC_LOCALE: ny_NO.ISO8859-15
iso8859-1/XLC_LOCALE: oc_FR.ISO8859-1
iso8859-15/XLC_LOCALE: oc_FR.ISO8859-15
iso8859-1/XLC_LOCALE: pd_DE.ISO8859-1
+iso8859-15/XLC_LOCALE: pd_DE.ISO8859-15
+iso8859-1/XLC_LOCALE: pd_US.ISO8859-1
+iso8859-15/XLC_LOCALE: pd_US.ISO8859-15
iso8859-1/XLC_LOCALE: ph_PH.ISO8859-1
iso8859-2/XLC_LOCALE: pl_PL.ISO8859-2
iso8859-1/XLC_LOCALE: pp_AN.ISO8859-1
iso8859-1/XLC_LOCALE: pt_BR.ISO8859-1
+iso8859-15/XLC_LOCALE: pt_BR.ISO8859-15
iso8859-1/XLC_LOCALE: pt_PT.ISO8859-1
iso8859-15/XLC_LOCALE: pt_PT.ISO8859-15
iso8859-2/XLC_LOCALE: ro_RO.ISO8859-2
iso8859-5/XLC_LOCALE: ru_RU.ISO8859-5
microsoft-cp1251/XLC_LOCALE: ru_RU.CP1251
koi8-r/XLC_LOCALE: ru_RU.KOI8-R
+microsoft-cp1251/XLC_LOCALE: ru_UA.CP1251
koi8-u/XLC_LOCALE: ru_UA.KOI8-U
iso8859-1/XLC_LOCALE: rw_RW.ISO8859-1
iso8859-2/XLC_LOCALE: sh_YU.ISO8859-2
@@ -231,6 +250,7 @@ iso8859-5/XLC_LOCALE: uk_UA.ISO8859-5
microsoft-cp1251/XLC_LOCALE: uk_UA.CP1251
koi8-u/XLC_LOCALE: uk_UA.KOI8-U
microsoft-cp1256/XLC_LOCALE: ur_PK.CP1256
+iso8859-1/XLC_LOCALE: uz_UZ.ISO8859-1
vi_VN.tcvn/XLC_LOCALE: vi_VN.TCVN
vi_VN.viscii/XLC_LOCALE: vi_VN.VISCII
iso8859-1/XLC_LOCALE: wa_BE.ISO8859-1
@@ -242,10 +262,7 @@ zh_CN/XLC_LOCALE: zh_CN.gb2312
zh_CN.gbk/XLC_LOCALE: zh_CN.gbk
zh_CN.gb18030/XLC_LOCALE: zh_CN.gb18030
zh_HK.big5/XLC_LOCALE: zh_HK.big5
-zh_HK.big5hkscs/XLC_LOCALE: zh_HK.big5-hkscs
-zh_HK.big5hkscs/XLC_LOCALE: zh_HK.Big5-HKSCS
zh_HK.big5hkscs/XLC_LOCALE: zh_HK.big5hkscs
-zh_HK.big5hkscs/XLC_LOCALE: zh_HK.Big5HKSCS
zh_TW.big5/XLC_LOCALE: zh_TW.big5
zh_TW/XLC_LOCALE: zh_TW.eucTW
iso8859-1/XLC_LOCALE: zu_ZA.ISO8859-1
@@ -274,7 +291,6 @@ en_US.UTF-8/XLC_LOCALE: ar_TN.UTF-8
en_US.UTF-8/XLC_LOCALE: ar_YE.UTF-8
en_US.UTF-8/XLC_LOCALE: as_IN.UTF-8
en_US.UTF-8/XLC_LOCALE: az_AZ.UTF-8
-en_US.UTF-8/XLC_LOCALE: a3_AZ.UTF-8
en_US.UTF-8/XLC_LOCALE: be_BY.UTF-8
en_US.UTF-8/XLC_LOCALE: bg_BG.UTF-8
en_US.UTF-8/XLC_LOCALE: bn_BD.UTF-8
@@ -299,17 +315,25 @@ en_US.UTF-8/XLC_LOCALE: el_CY.UTF-8
en_US.UTF-8/XLC_LOCALE: el_GR.UTF-8
en_US.UTF-8/XLC_LOCALE: en_AU.UTF-8
en_US.UTF-8/XLC_LOCALE: en_BE.UTF-8
+en_US.UTF-8/XLC_LOCALE: en_BW.UTF-8
en_US.UTF-8/XLC_LOCALE: en_BZ.UTF-8
en_US.UTF-8/XLC_LOCALE: en_CA.UTF-8
+en_US.UTF-8/XLC_LOCALE: en_DK.UTF-8
en_US.UTF-8/XLC_LOCALE: en_GB.UTF-8
+en_US.UTF-8/XLC_LOCALE: en_EN.UTF-8
+en_US.UTF-8/XLC_LOCALE: en_HK.UTF-8
en_US.UTF-8/XLC_LOCALE: en_IE.UTF-8
+en_US.UTF-8/XLC_LOCALE: en_IN.UTF-8
en_US.UTF-8/XLC_LOCALE: en_JM.UTF-8
en_US.UTF-8/XLC_LOCALE: en_MT.UTF-8
en_US.UTF-8/XLC_LOCALE: en_NZ.UTF-8
+en_US.UTF-8/XLC_LOCALE: en_PH.UTF-8
+en_US.UTF-8/XLC_LOCALE: en_SG.UTF-8
en_US.UTF-8/XLC_LOCALE: en_TT.UTF-8
en_US.UTF-8/XLC_LOCALE: en_UK.UTF-8
en_US.UTF-8/XLC_LOCALE: en_US.UTF-8
en_US.UTF-8/XLC_LOCALE: en_ZA.UTF-8
+en_US.UTF-8/XLC_LOCALE: en_ZW.UTF-8
en_US.UTF-8/XLC_LOCALE: eo_EO.UTF-8
en_US.UTF-8/XLC_LOCALE: eo_XX.UTF-8
en_US.UTF-8/XLC_LOCALE: es_AR.UTF-8
@@ -360,8 +384,9 @@ en_US.UTF-8/XLC_LOCALE: it_IT.UTF-8
en_US.UTF-8/XLC_LOCALE: iu_CA.UTF-8
ja_JP.UTF-8/XLC_LOCALE: ja_JP.UTF-8
en_US.UTF-8/XLC_LOCALE: ka_GE.UTF-8
-en_US.UTF-8/XLC_LOCALE: kl_GL.UTF-8
en_US.UTF-8/XLC_LOCALE: kk_KZ.UTF-8
+en_US.UTF-8/XLC_LOCALE: kl_GL.UTF-8
+en_US.UTF-8/XLC_LOCALE: km_KH.UTF-8
en_US.UTF-8/XLC_LOCALE: kn_IN.UTF-8
en_US.UTF-8/XLC_LOCALE: ks_IN.UTF-8
en_US.UTF-8/XLC_LOCALE: ks_IN@devanagari.UTF-8
@@ -445,7 +470,3 @@ zh_HK.UTF-8/XLC_LOCALE: zh_HK.UTF-8
zh_CN.UTF-8/XLC_LOCALE: zh_SG.UTF-8
zh_TW.UTF-8/XLC_LOCALE: zh_TW.UTF-8
en_US.UTF-8/XLC_LOCALE: zu_ZA.UTF-8
-#ifdef __uxp__
-ja.U90/XLC_LOCALE: ja_JP.U90
-ja.S90/XLC_LOCALE: ja_JP.S90
-#endif
diff --git a/libX11/nls/sr_CS.UTF-8/Compose.pre b/libX11/nls/sr_CS.UTF-8/Compose.pre
new file mode 100644
index 000000000..119e23ec4
--- /dev/null
+++ b/libX11/nls/sr_CS.UTF-8/Compose.pre
@@ -0,0 +1,128 @@
+include "X11_LOCALEDATADIR/en_US.UTF-8/Compose"
+
+# Serbian accented Cyrillic
+# а А - U+0430, U+0410 Cyrillic_a, Cyrillic_A
+# е Е - U+0435, U+0415 Cyrillic_e, Cyrillic_E
+# о О - U+043E, U+041E Cyrillic_o, Cyrillic_O
+# у У - U+0443, U+0423 Cyrillic_u, Cyrillic_U
+# и И - U+0438, U+0418 Cyrillic_i, Cyrillic_I
+#
+# ̀ - U+0300 <dead_grave>, <combining_grave>, <Multi_key> <grave>
+# ́ - U+0301 <dead_acute>, <Multi_key> <acute>, <Multi_key> <apostrophe>, <combining_acute>
+# ̂ - U+0302 <dead_circumflex>, <Multi_key> <asciicircum>
+# ̏ - U+030F <dead_diaeresis>, <dead_doubleacute>
+# ̀ - kratkouzlazni, U+0300 <dead_grave>, <combining_grave>, <Multi_key> <grave>
+<dead_grave> <Cyrillic_a> : "а̀"
+<combining_grave> <Cyrillic_a> : "а̀"
+<Multi_key> <grave> <Cyrillic_a> : "а̀"
+<dead_grave> <Cyrillic_A> : "А̀"
+<combining_grave> <Cyrillic_A> : "А̀"
+<Multi_key> <grave> <Cyrillic_A> : "А̀"
+<dead_grave> <Cyrillic_e> : "ѐ"
+<combining_grave> <Cyrillic_e> : "ѐ"
+<Multi_key> <grave> <Cyrillic_e> : "ѐ"
+<dead_grave> <Cyrillic_E> : "Ѐ"
+<combining_grave> <Cyrillic_E> : "Ѐ"
+<Multi_key> <grave> <Cyrillic_E> : "Ѐ"
+<dead_grave> <Cyrillic_i> : "ѝ"
+<combining_grave> <Cyrillic_i> : "ѝ"
+<Multi_key> <grave> <Cyrillic_i> : "ѝ"
+<dead_grave> <Cyrillic_I> : "Ѝ"
+<combining_grave> <Cyrillic_I> : "Ѝ"
+<Multi_key> <grave> <Cyrillic_I> : "Ѝ"
+<dead_grave> <Cyrillic_o> : "о̀"
+<combining_grave> <Cyrillic_o> : "о̀"
+<Multi_key> <grave> <Cyrillic_o> : "о̀"
+<dead_grave> <Cyrillic_O> : "О̀"
+<combining_grave> <Cyrillic_O> : "О̀"
+<Multi_key> <grave> <Cyrillic_O> : "О̀"
+<dead_grave> <Cyrillic_u> : "у̀"
+<combining_grave> <Cyrillic_u> : "у̀"
+<Multi_key> <grave> <Cyrillic_u> : "у̀"
+<dead_grave> <Cyrillic_U> : "У̀"
+<combining_grave> <Cyrillic_U> : "У̀"
+<Multi_key> <grave> <Cyrillic_U> : "У̀"
+# ́ - dugouzlazni, U+0301 <dead_acute>, <Multi_key> <acute>, <Multi_key> <apostrophe>, <combining_acute>
+<dead_acute> <Cyrillic_a> : "а́"
+<combining_acute> <Cyrillic_a> : "а́"
+<Multi_key> <acute> <Cyrillic_a> : "а́"
+<Multi_key> <apostrophe> <Cyrillic_a> : "а́"
+<dead_acute> <Cyrillic_A> : "А́"
+<combining_acute> <Cyrillic_A> : "А́"
+<Multi_key> <acute> <Cyrillic_A> : "А́"
+<Multi_key> <apostrophe> <Cyrillic_A> : "А́"
+<dead_acute> <Cyrillic_e> : "е́"
+<combining_acute> <Cyrillic_e> : "е́"
+<Multi_key> <acute> <Cyrillic_e> : "е́"
+<Multi_key> <apostrophe> <Cyrillic_e> : "е́"
+<dead_acute> <Cyrillic_E> : "Е́"
+<combining_acute> <Cyrillic_E> : "Е́"
+<Multi_key> <acute> <Cyrillic_E> : "Е́"
+<Multi_key> <apostrophe> <Cyrillic_E> : "Е́"
+<dead_acute> <Cyrillic_i> : "и́"
+<combining_acute> <Cyrillic_i> : "и́"
+<Multi_key> <acute> <Cyrillic_i> : "и́"
+<Multi_key> <apostrophe> <Cyrillic_i> : "и́"
+<dead_acute> <Cyrillic_I> : "И́"
+<combining_acute> <Cyrillic_I> : "И́"
+<Multi_key> <acute> <Cyrillic_I> : "И́"
+<Multi_key> <apostrophe> <Cyrillic_I> : "И́"
+<dead_acute> <Cyrillic_o> : "о́"
+<combining_acute> <Cyrillic_o> : "о́"
+<Multi_key> <acute> <Cyrillic_o> : "о́"
+<Multi_key> <apostrophe> <Cyrillic_o> : "о́"
+<dead_acute> <Cyrillic_O> : "О́"
+<combining_acute> <Cyrillic_O> : "О́"
+<Multi_key> <acute> <Cyrillic_O> : "О́"
+<Multi_key> <apostrophe> <Cyrillic_O> : "О́"
+<dead_acute> <Cyrillic_u> : "у́"
+<combining_acute> <Cyrillic_u> : "у́"
+<Multi_key> <acute> <Cyrillic_u> : "у́"
+<Multi_key> <apostrophe> <Cyrillic_u> : "у́"
+<dead_acute> <Cyrillic_U> : "У́"
+<combining_acute> <Cyrillic_U> : "У́"
+<Multi_key> <acute> <Cyrillic_U> : "У́"
+<Multi_key> <apostrophe> <Cyrillic_U> : "У́"
+# ̂ - dugosilazni, U+0302 <dead_circumflex>, <Multi_key> <asciicircum>
+<dead_circumflex> <Cyrillic_a> : "а̂"
+<Multi_key> <asciicircum> <Cyrillic_a> : "а̂"
+<dead_circumflex> <Cyrillic_A> : "А̂"
+<Multi_key> <asciicircum> <Cyrillic_A> : "А̂"
+<dead_circumflex> <Cyrillic_e> : "е̂"
+<Multi_key> <asciicircum> <Cyrillic_e> : "е̂"
+<dead_circumflex> <Cyrillic_E> : "Е̂"
+<Multi_key> <asciicircum> <Cyrillic_E> : "Е̂"
+<dead_circumflex> <Cyrillic_i> : "и̂"
+<Multi_key> <asciicircum> <Cyrillic_i> : "и̂"
+<dead_circumflex> <Cyrillic_I> : "И̂"
+<Multi_key> <asciicircum> <Cyrillic_I> : "И̂"
+<dead_circumflex> <Cyrillic_o> : "о̂"
+<Multi_key> <asciicircum> <Cyrillic_o> : "о̂"
+<dead_circumflex> <Cyrillic_O> : "О̂"
+<Multi_key> <asciicircum> <Cyrillic_O> : "О̂"
+<dead_circumflex> <Cyrillic_u> : "у̂"
+<Multi_key> <asciicircum> <Cyrillic_u> : "у̂"
+<dead_circumflex> <Cyrillic_U> : "У̂"
+<Multi_key> <asciicircum> <Cyrillic_U> : "У̂"
+# ̏ - kratkosilazni, U+030F <dead_diaeresis>, <dead_doubleacute>
+# there's no appropriate dead_doublegrave, so we use these two dead keys
+<dead_diaeresis> <Cyrillic_a> : "а̏"
+<dead_doubleacute> <Cyrillic_a> : "а̏"
+<dead_diaeresis> <Cyrillic_A> : "А̏"
+<dead_doubleacute> <Cyrillic_A> : "А̏"
+<dead_diaeresis> <Cyrillic_e> : "е̏"
+<dead_doubleacute> <Cyrillic_e> : "е̏"
+<dead_diaeresis> <Cyrillic_E> : "Е̏"
+<dead_doubleacute> <Cyrillic_E> : "Е̏"
+<dead_diaeresis> <Cyrillic_i> : "и̏"
+<dead_doubleacute> <Cyrillic_i> : "и̏"
+<dead_diaeresis> <Cyrillic_I> : "И̏"
+<dead_doubleacute> <Cyrillic_I> : "И̏"
+<dead_diaeresis> <Cyrillic_o> : "о̏"
+<dead_doubleacute> <Cyrillic_o> : "о̏"
+<dead_diaeresis> <Cyrillic_O> : "О̏"
+<dead_doubleacute> <Cyrillic_O> : "О̏"
+<dead_diaeresis> <Cyrillic_u> : "у̏"
+<dead_doubleacute> <Cyrillic_u> : "у̏"
+<dead_diaeresis> <Cyrillic_U> : "У̏"
+<dead_doubleacute> <Cyrillic_U> : "У̏"
diff --git a/libX11/nls/sr_CS.UTF-8/XI18N_OBJS b/libX11/nls/sr_CS.UTF-8/XI18N_OBJS
new file mode 100644
index 000000000..f201bf435
--- /dev/null
+++ b/libX11/nls/sr_CS.UTF-8/XI18N_OBJS
@@ -0,0 +1,8 @@
+# CATEGORY(XLC|XIM|OM) SHARED_LIBRARY_NAME FUNCTION_NAME
+#
+# XI18N objects table for euro locales
+#
+XLC common/xlcUTF8Load _XlcUtf8Loader # XLC_open
+XOM common/xomLTRTTB _XomGenericOpenOM # XOM_open
+XIM common/xiiimp _SwitchOpenIM # XIM_open
+XIM common/xiiimp _XimpLocalOpenIM # XIM_open
diff --git a/libX11/nls/ja.U90/Compose.pre b/libX11/nls/sr_CS.UTF-8/XLC_LOCALE.pre
index e69de29bb..e69de29bb 100644
--- a/libX11/nls/ja.U90/Compose.pre
+++ b/libX11/nls/sr_CS.UTF-8/XLC_LOCALE.pre
diff --git a/libX11/nls/th_TH.UTF-8/Compose.pre b/libX11/nls/th_TH.UTF-8/Compose.pre
index e69de29bb..6c2c4114d 100644
--- a/libX11/nls/th_TH.UTF-8/Compose.pre
+++ b/libX11/nls/th_TH.UTF-8/Compose.pre
@@ -0,0 +1 @@
+include "X11_LOCALEDATADIR/en_US.UTF-8/Compose"
diff --git a/libX11/nls/zh_CN.UTF-8/Compose.pre b/libX11/nls/zh_CN.UTF-8/Compose.pre
index e69de29bb..6c2c4114d 100644
--- a/libX11/nls/zh_CN.UTF-8/Compose.pre
+++ b/libX11/nls/zh_CN.UTF-8/Compose.pre
@@ -0,0 +1 @@
+include "X11_LOCALEDATADIR/en_US.UTF-8/Compose"
diff --git a/libX11/nls/zh_HK.UTF-8/Compose.pre b/libX11/nls/zh_HK.UTF-8/Compose.pre
index e69de29bb..6c2c4114d 100644
--- a/libX11/nls/zh_HK.UTF-8/Compose.pre
+++ b/libX11/nls/zh_HK.UTF-8/Compose.pre
@@ -0,0 +1 @@
+include "X11_LOCALEDATADIR/en_US.UTF-8/Compose"
diff --git a/libX11/nls/zh_TW.UTF-8/Compose.pre b/libX11/nls/zh_TW.UTF-8/Compose.pre
index e69de29bb..6c2c4114d 100644
--- a/libX11/nls/zh_TW.UTF-8/Compose.pre
+++ b/libX11/nls/zh_TW.UTF-8/Compose.pre
@@ -0,0 +1 @@
+include "X11_LOCALEDATADIR/en_US.UTF-8/Compose"
diff --git a/mesalib/.dir-locals.el b/mesalib/.dir-locals.el
new file mode 100644
index 000000000..4f0ad7ac8
--- /dev/null
+++ b/mesalib/.dir-locals.el
@@ -0,0 +1,11 @@
+((nil
+ (indent-tabs-mode . nil)
+ (tab-width . 8)
+ (c-basic-offset . 3)
+ (c-file-style . "stroustrup")
+ (fill-column . 78)
+ (eval . (progn
+ (c-set-offset 'innamespace '0)
+ (c-set-offset 'inline-open '0)))
+ )
+ )
diff --git a/mesalib/include/GL/gl.h b/mesalib/include/GL/gl.h
index e65e1bc8a..97094fc59 100644
--- a/mesalib/include/GL/gl.h
+++ b/mesalib/include/GL/gl.h
@@ -169,8 +169,8 @@ typedef double GLclampd; /* double precision float in [0,1] */
*/
/* Boolean values */
-#define GL_FALSE 0x0
-#define GL_TRUE 0x1
+#define GL_FALSE 0
+#define GL_TRUE 1
/* Data types */
#define GL_BYTE 0x1400
@@ -370,8 +370,8 @@ typedef double GLclampd; /* double precision float in [0,1] */
#define GL_BLEND 0x0BE2
#define GL_BLEND_SRC 0x0BE1
#define GL_BLEND_DST 0x0BE0
-#define GL_ZERO 0x0
-#define GL_ONE 0x1
+#define GL_ZERO 0
+#define GL_ONE 1
#define GL_SRC_COLOR 0x0300
#define GL_ONE_MINUS_SRC_COLOR 0x0301
#define GL_SRC_ALPHA 0x0302
@@ -461,7 +461,7 @@ typedef double GLclampd; /* double precision float in [0,1] */
#define GL_DECR 0x1E03
/* Buffers, Pixel Drawing/Reading */
-#define GL_NONE 0x0
+#define GL_NONE 0
#define GL_LEFT 0x0406
#define GL_RIGHT 0x0407
/*GL_FRONT 0x0404 */
@@ -689,7 +689,7 @@ typedef double GLclampd; /* double precision float in [0,1] */
#define GL_EXTENSIONS 0x1F03
/* Errors */
-#define GL_NO_ERROR 0x0
+#define GL_NO_ERROR 0
#define GL_INVALID_ENUM 0x0500
#define GL_INVALID_VALUE 0x0501
#define GL_INVALID_OPERATION 0x0502
diff --git a/mesalib/scons/gallium.py b/mesalib/scons/gallium.py
index 66ccaea73..98671f75d 100644
--- a/mesalib/scons/gallium.py
+++ b/mesalib/scons/gallium.py
@@ -500,7 +500,7 @@ def generate(env):
libs = []
if env['platform'] in ('darwin', 'freebsd', 'linux', 'posix', 'sunos'):
libs += ['m', 'pthread', 'dl']
- if env['platform'] in 'linux':
+ if env['platform'] in ('linux',):
libs += ['rt']
env.Append(LIBS = libs)
diff --git a/mesalib/src/gallium/auxiliary/Makefile.sources b/mesalib/src/gallium/auxiliary/Makefile.sources
index 6258861f0..724178535 100644
--- a/mesalib/src/gallium/auxiliary/Makefile.sources
+++ b/mesalib/src/gallium/auxiliary/Makefile.sources
@@ -124,7 +124,6 @@ C_SOURCES := \
util/u_math.c \
util/u_mm.c \
util/u_pstipple.c \
- util/u_rect.c \
util/u_ringbuffer.c \
util/u_sampler.c \
util/u_simple_shaders.c \
diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.h b/mesalib/src/gallium/auxiliary/util/u_blitter.h
index b96e68e93..99175409b 100644
--- a/mesalib/src/gallium/auxiliary/util/u_blitter.h
+++ b/mesalib/src/gallium/auxiliary/util/u_blitter.h
@@ -29,10 +29,14 @@
#include "util/u_framebuffer.h"
#include "util/u_inlines.h"
-#include "util/u_memory.h"
#include "pipe/p_state.h"
+/* u_memory.h conflicts with st/mesa */
+#ifndef Elements
+#define Elements(x) (sizeof(x)/sizeof((x)[0]))
+#endif
+
#ifdef __cplusplus
extern "C" {
diff --git a/mesalib/src/gallium/auxiliary/util/u_rect.c b/mesalib/src/gallium/auxiliary/util/u_rect.c
deleted file mode 100644
index d00568f1f..000000000
--- a/mesalib/src/gallium/auxiliary/util/u_rect.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * Rectangle-related helper functions.
- */
-
-
-#include "util/u_format.h"
-#include "util/u_rect.h"
-#include "util/u_pack_color.h"
-
-
-/**
- * Copy 2D rect from one place to another.
- * Position and sizes are in pixels.
- * src_stride may be negative to do vertical flip of pixels from source.
- */
-void
-util_copy_rect(ubyte * dst,
- enum pipe_format format,
- unsigned dst_stride,
- unsigned dst_x,
- unsigned dst_y,
- unsigned width,
- unsigned height,
- const ubyte * src,
- int src_stride,
- unsigned src_x,
- unsigned src_y)
-{
- unsigned i;
- int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
- int blocksize = util_format_get_blocksize(format);
- int blockwidth = util_format_get_blockwidth(format);
- int blockheight = util_format_get_blockheight(format);
-
- assert(blocksize > 0);
- assert(blockwidth > 0);
- assert(blockheight > 0);
-
- dst_x /= blockwidth;
- dst_y /= blockheight;
- width = (width + blockwidth - 1)/blockwidth;
- height = (height + blockheight - 1)/blockheight;
- src_x /= blockwidth;
- src_y /= blockheight;
-
- dst += dst_x * blocksize;
- src += src_x * blocksize;
- dst += dst_y * dst_stride;
- src += src_y * src_stride_pos;
- width *= blocksize;
-
- if (width == dst_stride && width == src_stride)
- memcpy(dst, src, height * width);
- else {
- for (i = 0; i < height; i++) {
- memcpy(dst, src, width);
- dst += dst_stride;
- src += src_stride;
- }
- }
-}
-
-void
-util_fill_rect(ubyte * dst,
- enum pipe_format format,
- unsigned dst_stride,
- unsigned dst_x,
- unsigned dst_y,
- unsigned width,
- unsigned height,
- union util_color *uc)
-{
- const struct util_format_description *desc = util_format_description(format);
- unsigned i, j;
- unsigned width_size;
- int blocksize = desc->block.bits / 8;
- int blockwidth = desc->block.width;
- int blockheight = desc->block.height;
-
- assert(blocksize > 0);
- assert(blockwidth > 0);
- assert(blockheight > 0);
-
- dst_x /= blockwidth;
- dst_y /= blockheight;
- width = (width + blockwidth - 1)/blockwidth;
- height = (height + blockheight - 1)/blockheight;
-
- dst += dst_x * blocksize;
- dst += dst_y * dst_stride;
- width_size = width * blocksize;
-
- switch (blocksize) {
- case 1:
- if(dst_stride == width_size)
- memset(dst, uc->ub, height * width_size);
- else {
- for (i = 0; i < height; i++) {
- memset(dst, uc->ub, width_size);
- dst += dst_stride;
- }
- }
- break;
- case 2:
- for (i = 0; i < height; i++) {
- uint16_t *row = (uint16_t *)dst;
- for (j = 0; j < width; j++)
- *row++ = uc->us;
- dst += dst_stride;
- }
- break;
- case 4:
- for (i = 0; i < height; i++) {
- uint32_t *row = (uint32_t *)dst;
- for (j = 0; j < width; j++)
- *row++ = uc->ui;
- dst += dst_stride;
- }
- break;
- default:
- for (i = 0; i < height; i++) {
- ubyte *row = dst;
- for (j = 0; j < width; j++) {
- memcpy(row, uc, blocksize);
- row += blocksize;
- }
- dst += dst_stride;
- }
- break;
- }
-}
diff --git a/mesalib/src/gallium/auxiliary/util/u_rect.h b/mesalib/src/gallium/auxiliary/util/u_rect.h
index 8fccae8c4..10909b202 100644
--- a/mesalib/src/gallium/auxiliary/util/u_rect.h
+++ b/mesalib/src/gallium/auxiliary/util/u_rect.h
@@ -83,36 +83,10 @@ u_rect_possible_intersection(const struct u_rect *a,
}
#endif
-#include "pipe/p_format.h"
-#include "util/u_pack_color.h"
-
-
-/**********************************************************************
- * Pipe copy/fill rect helpers.
- */
-
-/* These really should move to a different file:
+/* Include pipe copy/fill rect helpers declarations for backwards compatibility
*/
-#include "pipe/p_format.h"
+#include "util/u_surface.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern void
-util_copy_rect(ubyte * dst, enum pipe_format format,
- unsigned dst_stride, unsigned dst_x, unsigned dst_y,
- unsigned width, unsigned height, const ubyte * src,
- int src_stride, unsigned src_x, unsigned src_y);
-
-extern void
-util_fill_rect(ubyte * dst, enum pipe_format format,
- unsigned dst_stride, unsigned dst_x, unsigned dst_y,
- unsigned width, unsigned height, union util_color *uc);
-
-#ifdef __cplusplus
-}
-#endif
#endif /* U_RECT_H */
diff --git a/mesalib/src/gallium/auxiliary/util/u_surface.c b/mesalib/src/gallium/auxiliary/util/u_surface.c
index 5b42afd0d..2c197c3df 100644
--- a/mesalib/src/gallium/auxiliary/util/u_surface.c
+++ b/mesalib/src/gallium/auxiliary/util/u_surface.c
@@ -116,6 +116,163 @@ util_create_rgba_texture(struct pipe_context *pipe,
/**
+ * Copy 2D rect from one place to another.
+ * Position and sizes are in pixels.
+ * src_stride may be negative to do vertical flip of pixels from source.
+ */
+void
+util_copy_rect(ubyte * dst,
+ enum pipe_format format,
+ unsigned dst_stride,
+ unsigned dst_x,
+ unsigned dst_y,
+ unsigned width,
+ unsigned height,
+ const ubyte * src,
+ int src_stride,
+ unsigned src_x,
+ unsigned src_y)
+{
+ unsigned i;
+ int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
+ int blocksize = util_format_get_blocksize(format);
+ int blockwidth = util_format_get_blockwidth(format);
+ int blockheight = util_format_get_blockheight(format);
+
+ assert(blocksize > 0);
+ assert(blockwidth > 0);
+ assert(blockheight > 0);
+
+ dst_x /= blockwidth;
+ dst_y /= blockheight;
+ width = (width + blockwidth - 1)/blockwidth;
+ height = (height + blockheight - 1)/blockheight;
+ src_x /= blockwidth;
+ src_y /= blockheight;
+
+ dst += dst_x * blocksize;
+ src += src_x * blocksize;
+ dst += dst_y * dst_stride;
+ src += src_y * src_stride_pos;
+ width *= blocksize;
+
+ if (width == dst_stride && width == src_stride)
+ memcpy(dst, src, height * width);
+ else {
+ for (i = 0; i < height; i++) {
+ memcpy(dst, src, width);
+ dst += dst_stride;
+ src += src_stride;
+ }
+ }
+}
+
+
+/**
+ * Copy 3D box from one place to another.
+ * Position and sizes are in pixels.
+ */
+void
+util_copy_box(ubyte * dst,
+ enum pipe_format format,
+ unsigned dst_stride, unsigned dst_slice_stride,
+ unsigned dst_x, unsigned dst_y, unsigned dst_z,
+ unsigned width, unsigned height, unsigned depth,
+ const ubyte * src,
+ int src_stride, unsigned src_slice_stride,
+ unsigned src_x, unsigned src_y, unsigned src_z)
+{
+ unsigned z;
+ dst += dst_z * dst_slice_stride;
+ src += src_z * src_slice_stride;
+ for (z = 0; z < depth; ++z) {
+ util_copy_rect(dst,
+ format,
+ dst_stride,
+ dst_x, dst_y,
+ width, height,
+ src,
+ src_stride,
+ src_x, src_y);
+
+ dst += dst_slice_stride;
+ src += src_slice_stride;
+ }
+}
+
+
+void
+util_fill_rect(ubyte * dst,
+ enum pipe_format format,
+ unsigned dst_stride,
+ unsigned dst_x,
+ unsigned dst_y,
+ unsigned width,
+ unsigned height,
+ union util_color *uc)
+{
+ const struct util_format_description *desc = util_format_description(format);
+ unsigned i, j;
+ unsigned width_size;
+ int blocksize = desc->block.bits / 8;
+ int blockwidth = desc->block.width;
+ int blockheight = desc->block.height;
+
+ assert(blocksize > 0);
+ assert(blockwidth > 0);
+ assert(blockheight > 0);
+
+ dst_x /= blockwidth;
+ dst_y /= blockheight;
+ width = (width + blockwidth - 1)/blockwidth;
+ height = (height + blockheight - 1)/blockheight;
+
+ dst += dst_x * blocksize;
+ dst += dst_y * dst_stride;
+ width_size = width * blocksize;
+
+ switch (blocksize) {
+ case 1:
+ if(dst_stride == width_size)
+ memset(dst, uc->ub, height * width_size);
+ else {
+ for (i = 0; i < height; i++) {
+ memset(dst, uc->ub, width_size);
+ dst += dst_stride;
+ }
+ }
+ break;
+ case 2:
+ for (i = 0; i < height; i++) {
+ uint16_t *row = (uint16_t *)dst;
+ for (j = 0; j < width; j++)
+ *row++ = uc->us;
+ dst += dst_stride;
+ }
+ break;
+ case 4:
+ for (i = 0; i < height; i++) {
+ uint32_t *row = (uint32_t *)dst;
+ for (j = 0; j < width; j++)
+ *row++ = uc->ui;
+ dst += dst_stride;
+ }
+ break;
+ default:
+ for (i = 0; i < height; i++) {
+ ubyte *row = dst;
+ for (j = 0; j < width; j++) {
+ memcpy(row, uc, blocksize);
+ row += blocksize;
+ }
+ dst += dst_stride;
+ }
+ break;
+ }
+}
+
+
+/**
* Fallback function for pipe->resource_copy_region().
* Note: (X,Y)=(0,0) is always the upper-left corner.
*/
@@ -133,7 +290,6 @@ util_resource_copy_region(struct pipe_context *pipe,
const uint8_t *src_map;
enum pipe_format src_format, dst_format;
struct pipe_box dst_box;
- int z;
assert(src && dst);
if (!src || !dst)
@@ -181,19 +337,14 @@ util_resource_copy_region(struct pipe_context *pipe,
assert(src_box->depth == 1);
memcpy(dst_map, src_map, src_box->width);
} else {
- for (z = 0; z < src_box->depth; ++z) {
- util_copy_rect(dst_map,
- dst_format,
- dst_trans->stride,
- 0, 0,
- src_box->width, src_box->height,
- src_map,
- src_trans->stride,
- 0, 0);
-
- dst_map += dst_trans->layer_stride;
- src_map += src_trans->layer_stride;
- }
+ util_copy_box(dst_map,
+ dst_format,
+ dst_trans->stride, dst_trans->layer_stride,
+ 0, 0, 0,
+ src_box->width, src_box->height, src_box->depth,
+ src_map,
+ src_trans->stride, src_trans->layer_stride,
+ 0, 0, 0);
}
pipe->transfer_unmap(pipe, dst_trans);
diff --git a/mesalib/src/gallium/auxiliary/util/u_surface.h b/mesalib/src/gallium/auxiliary/util/u_surface.h
index 6bcb63f3d..dd4d5785e 100644
--- a/mesalib/src/gallium/auxiliary/util/u_surface.h
+++ b/mesalib/src/gallium/auxiliary/util/u_surface.h
@@ -32,6 +32,8 @@
#include "pipe/p_compiler.h"
#include "pipe/p_state.h"
+#include "util/u_pack_color.h"
+
#ifdef __cplusplus
extern "C" {
@@ -50,6 +52,28 @@ util_create_rgba_texture(struct pipe_context *ctx,
extern void
+util_copy_rect(ubyte * dst, enum pipe_format format,
+ unsigned dst_stride, unsigned dst_x, unsigned dst_y,
+ unsigned width, unsigned height, const ubyte * src,
+ int src_stride, unsigned src_x, unsigned src_y);
+
+extern void
+util_copy_box(ubyte * dst,
+ enum pipe_format format,
+ unsigned dst_stride, unsigned dst_slice_stride,
+ unsigned dst_x, unsigned dst_y, unsigned dst_z,
+ unsigned width, unsigned height, unsigned depth,
+ const ubyte * src,
+ int src_stride, unsigned src_slice_stride,
+ unsigned src_x, unsigned src_y, unsigned src_z);
+
+extern void
+util_fill_rect(ubyte * dst, enum pipe_format format,
+ unsigned dst_stride, unsigned dst_x, unsigned dst_y,
+ unsigned width, unsigned height, union util_color *uc);
+
+
+extern void
util_resource_copy_region(struct pipe_context *pipe,
struct pipe_resource *dst,
unsigned dst_level,
diff --git a/mesalib/src/gallium/auxiliary/util/u_transfer.c b/mesalib/src/gallium/auxiliary/util/u_transfer.c
index 8b4c36592..861682553 100644
--- a/mesalib/src/gallium/auxiliary/util/u_transfer.c
+++ b/mesalib/src/gallium/auxiliary/util/u_transfer.c
@@ -1,5 +1,5 @@
#include "pipe/p_context.h"
-#include "util/u_rect.h"
+#include "util/u_surface.h"
#include "util/u_inlines.h"
#include "util/u_transfer.h"
#include "util/u_memory.h"
@@ -47,21 +47,19 @@ void u_default_transfer_inline_write( struct pipe_context *pipe,
}
else {
const uint8_t *src_data = data;
- unsigned i;
- for (i = 0; i < box->depth; i++) {
- util_copy_rect(map,
- resource->format,
- transfer->stride, /* bytes */
- 0, 0,
- box->width,
- box->height,
- src_data,
- stride, /* bytes */
- 0, 0);
- map += transfer->layer_stride;
- src_data += layer_stride;
- }
+ util_copy_box(map,
+ resource->format,
+ transfer->stride, /* bytes */
+ transfer->layer_stride, /* bytes */
+ 0, 0, 0,
+ box->width,
+ box->height,
+ box->depth,
+ src_data,
+ stride, /* bytes */
+ layer_stride, /* bytes */
+ 0, 0, 0);
}
pipe_transfer_unmap(pipe, transfer);
diff --git a/mesalib/src/glsl/Makefile.am b/mesalib/src/glsl/Makefile.am
index ea7617685..aff1559e0 100644
--- a/mesalib/src/glsl/Makefile.am
+++ b/mesalib/src/glsl/Makefile.am
@@ -49,14 +49,16 @@ libglsl_la_LIBADD = glcpp/libglcpp.la
libglsl_la_LDFLAGS =
glsl_compiler_SOURCES = \
- $(top_srcdir)/src/mesa/program/hash_table.c \
+ $(top_srcdir)/src/mesa/main/hash_table.c \
+ $(top_srcdir)/src/mesa/program/prog_hash_table.c \
$(top_srcdir)/src/mesa/program/symbol_table.c \
$(GLSL_COMPILER_CXX_FILES)
glsl_compiler_LDADD = libglsl.la
glsl_test_SOURCES = \
- $(top_srcdir)/src/mesa/program/hash_table.c \
+ $(top_srcdir)/src/mesa/main/hash_table.c \
+ $(top_srcdir)/src/mesa/program/prog_hash_table.c \
$(top_srcdir)/src/mesa/program/symbol_table.c \
$(GLSL_SRCDIR)/standalone_scaffolding.cpp \
test.cpp \
diff --git a/mesalib/src/glsl/SConscript b/mesalib/src/glsl/SConscript
index 0cf25c07b..6abba2a24 100644
--- a/mesalib/src/glsl/SConscript
+++ b/mesalib/src/glsl/SConscript
@@ -57,14 +57,18 @@ if env['crosscompile'] and not env['embedded']:
Import('builtin_glsl_function')
else:
# Copy these files to avoid generation object files into src/mesa/program
+ env.Prepend(CPPPATH = ['#src/mesa/main'])
+ env.Command('hash_table.c', '#src/mesa/main/hash_table.c', Copy('$TARGET', '$SOURCE'))
+ # Copy these files to avoid generation object files into src/mesa/program
env.Prepend(CPPPATH = ['#src/mesa/program'])
- env.Command('hash_table.c', '#src/mesa/program/hash_table.c', Copy('$TARGET', '$SOURCE'))
+ env.Command('prog_hash_table.c', '#src/mesa/program/prog_hash_table.c', Copy('$TARGET', '$SOURCE'))
env.Command('symbol_table.c', '#src/mesa/program/symbol_table.c', Copy('$TARGET', '$SOURCE'))
compiler_objs = env.StaticObject(source_lists['GLSL_COMPILER_CXX_FILES'])
mesa_objs = env.StaticObject([
'hash_table.c',
+ 'prog_hash_table.c',
'symbol_table.c',
])
diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp
index ea3282c5f..b56a3c723 100644
--- a/mesalib/src/glsl/ast_function.cpp
+++ b/mesalib/src/glsl/ast_function.cpp
@@ -275,9 +275,10 @@ generate_call(exec_list *instructions, ir_function_signature *sig,
/* If the function call is a constant expression, don't generate any
* instructions; just generate an ir_constant.
*
- * Function calls were first allowed to be constant expressions in GLSL 1.20.
+ * Function calls were first allowed to be constant expressions in GLSL
+ * 1.20 and GLSL ES 3.00.
*/
- if (state->language_version >= 120) {
+ if (state->is_version(120, 300)) {
ir_constant *value = sig->constant_expression_value(actual_parameters, NULL);
if (value != NULL) {
return value;
@@ -324,7 +325,8 @@ match_function_by_name(const char *name,
goto done; /* no match */
/* Is the function hidden by a variable (impossible in 1.10)? */
- if (state->language_version != 110 && state->symbols->get_variable(name))
+ if (!state->symbols->separate_function_namespace
+ && state->symbols->get_variable(name))
goto done; /* no match */
if (f != NULL) {
@@ -1242,9 +1244,8 @@ ast_function_expression::hir(exec_list *instructions,
}
if (constructor_type->is_array()) {
- if (state->language_version <= 110) {
- _mesa_glsl_error(& loc, state,
- "array constructors forbidden in GLSL 1.10");
+ if (!state->check_version(120, 300, &loc,
+ "array constructors forbidden")) {
return ir_rvalue::error_value(ctx);
}
@@ -1367,11 +1368,11 @@ ast_function_expression::hir(exec_list *instructions,
* "It is an error to construct matrices from other matrices. This
* is reserved for future use."
*/
- if (state->language_version == 110 && matrix_parameters > 0
- && constructor_type->is_matrix()) {
- _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
- "matrix in GLSL 1.10",
- constructor_type->name);
+ if (matrix_parameters > 0
+ && constructor_type->is_matrix()
+ && !state->check_version(120, 100, &loc,
+ "cannot construct `%s' from a matrix",
+ constructor_type->name)) {
return ir_rvalue::error_value(ctx);
}
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index d450aa1e4..94b63f682 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -66,7 +66,7 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
{
_mesa_glsl_initialize_variables(instructions, state);
- state->symbols->language_version = state->language_version;
+ state->symbols->separate_function_namespace = state->language_version == 110;
state->current_function = NULL;
@@ -121,7 +121,7 @@ apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from,
/* This conversion was added in GLSL 1.20. If the compilation mode is
* GLSL 1.10, the conversion is skipped.
*/
- if (state->language_version < 120)
+ if (!state->is_version(120, 0))
return false;
/* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec:
@@ -390,8 +390,7 @@ bit_logic_result_type(const struct glsl_type *type_a,
ast_operators op,
struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
{
- if (state->language_version < 130) {
- _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30");
+ if (!state->check_bitwise_operations_allowed(loc)) {
return glsl_type::error_type;
}
@@ -446,10 +445,7 @@ modulus_result_type(const struct glsl_type *type_a,
const struct glsl_type *type_b,
struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
{
- if (state->language_version < 130) {
- _mesa_glsl_error(loc, state,
- "operator '%%' is reserved in %s",
- state->version_string);
+ if (!state->check_version(130, 300, loc, "operator '%%' is reserved")) {
return glsl_type::error_type;
}
@@ -553,8 +549,7 @@ shift_result_type(const struct glsl_type *type_a,
ast_operators op,
struct _mesa_glsl_parse_state *state, YYLTYPE *loc)
{
- if (state->language_version < 130) {
- _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30");
+ if (!state->check_bitwise_operations_allowed(loc)) {
return glsl_type::error_type;
}
@@ -694,15 +689,17 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
lhs->variable_referenced()->name);
error_emitted = true;
- } else if (state->language_version <= 110 && lhs->type->is_array()) {
+ } else if (lhs->type->is_array() &&
+ !state->check_version(120, 300, &lhs_loc,
+ "whole array assignment forbidden")) {
/* From page 32 (page 38 of the PDF) of the GLSL 1.10 spec:
*
* "Other binary or unary expressions, non-dereferenced
* arrays, function names, swizzles with repeated fields,
* and constants cannot be l-values."
+ *
+ * The restriction on arrays is lifted in GLSL 1.20 and GLSL ES 3.00.
*/
- _mesa_glsl_error(&lhs_loc, state, "whole array assignment is not "
- "allowed in GLSL 1.10 or GLSL ES 1.00.");
error_emitted = true;
} else if (!lhs->is_lvalue()) {
_mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
@@ -1099,9 +1096,7 @@ ast_expression::hir(exec_list *instructions,
case ast_lshift:
case ast_rshift:
- if (state->language_version < 130) {
- _mesa_glsl_error(&loc, state, "operator %s requires GLSL 1.30",
- operator_string(this->oper));
+ if (!state->check_bitwise_operations_allowed(&loc)) {
error_emitted = true;
}
@@ -1155,10 +1150,9 @@ ast_expression::hir(exec_list *instructions,
_mesa_glsl_error(& loc, state, "operands of `%s' must have the same "
"type", (this->oper == ast_equal) ? "==" : "!=");
error_emitted = true;
- } else if ((state->language_version <= 110)
- && (op[0]->type->is_array() || op[1]->type->is_array())) {
- _mesa_glsl_error(& loc, state, "array comparisons forbidden in "
- "GLSL 1.10");
+ } else if ((op[0]->type->is_array() || op[1]->type->is_array()) &&
+ !state->check_version(120, 300, &loc,
+ "array comparisons forbidden")) {
error_emitted = true;
}
@@ -1185,8 +1179,7 @@ ast_expression::hir(exec_list *instructions,
case ast_bit_not:
op[0] = this->subexpressions[0]->hir(instructions, state);
- if (state->language_version < 130) {
- _mesa_glsl_error(&loc, state, "bit-wise operations require GLSL 1.30");
+ if (!state->check_bitwise_operations_allowed(&loc)) {
error_emitted = true;
}
@@ -1424,9 +1417,10 @@ ast_expression::hir(exec_list *instructions,
* "The second and third expressions must be the same type, but can
* be of any type other than an array."
*/
- if ((state->language_version <= 110) && type->is_array()) {
- _mesa_glsl_error(& loc, state, "Second and third operands of ?: "
- "operator must not be arrays.");
+ if (type->is_array() &&
+ !state->check_version(120, 300, &loc,
+ "Second and third operands of ?: operator "
+ "cannot be arrays")) {
error_emitted = true;
}
@@ -1660,15 +1654,18 @@ ast_expression::hir(exec_list *instructions,
array->type->element_type()->is_sampler() &&
const_index == NULL) {
- if (state->language_version == 100) {
- _mesa_glsl_warning(&loc, state,
- "sampler arrays indexed with non-constant "
- "expressions is optional in GLSL ES 1.00");
- } else if (state->language_version < 130) {
- _mesa_glsl_warning(&loc, state,
- "sampler arrays indexed with non-constant "
- "expressions is forbidden in GLSL 1.30 and "
- "later");
+ if (!state->is_version(130, 100)) {
+ if (state->es_shader) {
+ _mesa_glsl_warning(&loc, state,
+ "sampler arrays indexed with non-constant "
+ "expressions is optional in %s",
+ state->get_version_string());
+ } else {
+ _mesa_glsl_warning(&loc, state,
+ "sampler arrays indexed with non-constant "
+ "expressions will be forbidden in GLSL 1.30 and "
+ "later");
+ }
} else {
_mesa_glsl_error(&loc, state,
"sampler arrays indexed with non-constant "
@@ -2288,7 +2285,7 @@ get_variable_being_redeclared(ir_variable *var, ast_declaration *decl,
* * gl_Color
* * gl_SecondaryColor
*/
- } else if (state->language_version >= 130
+ } else if (state->is_version(130, 0)
&& (strcmp(var->name, "gl_FrontColor") == 0
|| strcmp(var->name, "gl_BackColor") == 0
|| strcmp(var->name, "gl_FrontSecondaryColor") == 0
@@ -2355,10 +2352,9 @@ process_initializer(ir_variable *var, ast_declaration *decl,
* directly by an application via API commands, or indirectly by
* OpenGL."
*/
- if ((state->language_version <= 110)
- && (var->mode == ir_var_uniform)) {
- _mesa_glsl_error(& initializer_loc, state,
- "cannot initialize uniforms in GLSL 1.10");
+ if (var->mode == ir_var_uniform) {
+ state->check_version(120, 0, &initializer_loc,
+ "cannot initialize uniforms");
}
if (var->type->is_sampler()) {
@@ -2608,23 +2604,23 @@ ast_declarator_list::hir(exec_list *instructions,
*
* Local variables can only use the qualifier const."
*
- * This is relaxed in GLSL 1.30. It is also relaxed by any extension
- * that adds the 'layout' keyword.
+ * This is relaxed in GLSL 1.30 and GLSL ES 3.00. It is also relaxed by
+ * any extension that adds the 'layout' keyword.
*/
- if ((state->language_version < 130)
+ if (!state->is_version(130, 300)
&& !state->ARB_explicit_attrib_location_enable
&& !state->ARB_fragment_coord_conventions_enable) {
if (this->type->qualifier.flags.q.out) {
_mesa_glsl_error(& loc, state,
"`out' qualifier in declaration of `%s' "
"only valid for function parameters in %s.",
- decl->identifier, state->version_string);
+ decl->identifier, state->get_version_string());
}
if (this->type->qualifier.flags.q.in) {
_mesa_glsl_error(& loc, state,
"`in' qualifier in declaration of `%s' "
"only valid for function parameters in %s.",
- decl->identifier, state->version_string);
+ decl->identifier, state->get_version_string());
}
/* FINISHME: Test for other invalid qualifiers. */
}
@@ -2703,6 +2699,13 @@ ast_declarator_list::hir(exec_list *instructions,
* "The attribute qualifier can be used only with float,
* floating-point vectors, and matrices. Attribute variables
* cannot be declared as arrays or structures."
+ *
+ * From page 33 (page 39 of the PDF) of the GLSL ES 3.00 spec:
+ *
+ * "Vertex shader inputs can only be float, floating-point
+ * vectors, matrices, signed and unsigned integers and integer
+ * vectors. Vertex shader inputs cannot be arrays or
+ * structures."
*/
const glsl_type *check_type = var->type->is_array()
? var->type->fields.array : var->type;
@@ -2712,7 +2715,7 @@ ast_declarator_list::hir(exec_list *instructions,
break;
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
- if (state->language_version > 120)
+ if (state->is_version(120, 300))
break;
/* FALLTHROUGH */
default:
@@ -2724,11 +2727,10 @@ ast_declarator_list::hir(exec_list *instructions,
error_emitted = true;
}
- if (!error_emitted && (state->language_version <= 130)
- && var->type->is_array()) {
- _mesa_glsl_error(& loc, state,
- "vertex shader input / attribute cannot have "
- "array type");
+ if (!error_emitted && var->type->is_array() &&
+ !state->check_version(140, 0, &loc,
+ "vertex shader input / attribute "
+ "cannot have array type")) {
error_emitted = true;
}
}
@@ -2740,8 +2742,16 @@ ast_declarator_list::hir(exec_list *instructions,
* "If a vertex output is a signed or unsigned integer or integer
* vector, then it must be qualified with the interpolation qualifier
* flat."
+ *
+ * From section 4.3.4 of the GLSL 3.00 ES spec:
+ * "Fragment shader inputs that are signed or unsigned integers or
+ * integer vectors must be qualified with the interpolation qualifier
+ * flat."
+ *
+ * Since vertex outputs and fragment inputs must have matching
+ * qualifiers, these two requirements are equivalent.
*/
- if (state->language_version >= 130
+ if (state->is_version(130, 300)
&& state->target == vertex_shader
&& state->current_function == NULL
&& var->type->is_integer()
@@ -2760,8 +2770,10 @@ ast_declarator_list::hir(exec_list *instructions,
* "interpolation qualifiers may only precede the qualifiers in,
* centroid in, out, or centroid out in a declaration. They do not apply
* to the deprecated storage qualifiers varying or centroid varying."
+ *
+ * These deprecated storage qualifiers do not exist in GLSL ES 3.00.
*/
- if (state->language_version >= 130
+ if (state->is_version(130, 0)
&& this->type->qualifier.has_interpolation()
&& this->type->qualifier.flags.q.varying) {
@@ -2786,8 +2798,14 @@ ast_declarator_list::hir(exec_list *instructions,
* "Outputs from a vertex shader (out) and inputs to a fragment
* shader (in) can be further qualified with one or more of these
* interpolation qualifiers"
+ *
+ * From page 31 (page 37 of the PDF) of the GLSL ES 3.00 spec:
+ * "These interpolation qualifiers may only precede the qualifiers
+ * in, centroid in, out, or centroid out in a declaration. They do
+ * not apply to inputs into a vertex shader or outputs from a
+ * fragment shader."
*/
- if (state->language_version >= 130
+ if (state->is_version(130, 300)
&& this->type->qualifier.has_interpolation()) {
const char *i = this->type->qualifier.interpolation_string();
@@ -2816,8 +2834,12 @@ ast_declarator_list::hir(exec_list *instructions,
/* From section 4.3.4 of the GLSL 1.30 spec:
* "It is an error to use centroid in in a vertex shader."
+ *
+ * From section 4.3.4 of the GLSL ES 3.00 spec:
+ * "It is an error to use centroid in or interpolation qualifiers in
+ * a vertex shader input."
*/
- if (state->language_version >= 130
+ if (state->is_version(130, 300)
&& this->type->qualifier.flags.q.centroid
&& this->type->qualifier.flags.q.in
&& state->target == vertex_shader) {
@@ -2829,13 +2851,8 @@ ast_declarator_list::hir(exec_list *instructions,
/* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
*/
- if (this->type->specifier->precision != ast_precision_none
- && state->language_version != 100
- && state->language_version < 130) {
-
- _mesa_glsl_error(&loc, state,
- "precision qualifiers are supported only in GLSL ES "
- "1.00, and GLSL 1.30 and later");
+ if (this->type->specifier->precision != ast_precision_none) {
+ state->check_precision_qualifiers_allowed(&loc);
}
@@ -3077,8 +3094,9 @@ ast_parameter_declarator::hir(exec_list *instructions,
* allowed. This restriction is removed in GLSL 1.20, and in GLSL ES.
*/
if ((var->mode == ir_var_inout || var->mode == ir_var_out)
- && type->is_array() && state->language_version == 110) {
- _mesa_glsl_error(&loc, state, "Arrays cannot be out or inout parameters in GLSL 1.10");
+ && type->is_array()
+ && !state->check_version(120, 100, &loc,
+ "Arrays cannot be out or inout parameters")) {
type = glsl_type::error_type;
}
@@ -3161,7 +3179,8 @@ ast_function::hir(exec_list *instructions,
*
* Note that this language does not appear in GLSL 1.10.
*/
- if ((state->current_function != NULL) && (state->language_version != 110)) {
+ if ((state->current_function != NULL) &&
+ state->is_version(120, 100)) {
YYLTYPE loc = this->get_location();
_mesa_glsl_error(&loc, state,
"declaration of function `%s' not allowed within "
@@ -3872,11 +3891,7 @@ ast_type_specifier::hir(exec_list *instructions,
YYLTYPE loc = this->get_location();
if (this->precision != ast_precision_none
- && state->language_version != 100
- && state->language_version < 130) {
- _mesa_glsl_error(&loc, state,
- "precision qualifiers exist only in "
- "GLSL ES 1.00, and GLSL 1.30 and later");
+ && !state->check_precision_qualifiers_allowed(&loc)) {
return NULL;
}
if (this->precision != ast_precision_none
diff --git a/mesalib/src/glsl/builtin_compiler/Makefile.am b/mesalib/src/glsl/builtin_compiler/Makefile.am
index d6f85a7f4..d27aca555 100644
--- a/mesalib/src/glsl/builtin_compiler/Makefile.am
+++ b/mesalib/src/glsl/builtin_compiler/Makefile.am
@@ -55,7 +55,8 @@ builtin_compiler_SOURCES = \
$(GLSL_BUILDDIR)/glsl_parser.cc \
$(LIBGLSL_FILES) \
$(LIBGLSL_CXX_FILES) \
- $(top_srcdir)/src/mesa/program/hash_table.c \
+ $(top_srcdir)/src/mesa/main/hash_table.c \
+ $(top_srcdir)/src/mesa/program/prog_hash_table.c \
$(top_srcdir)/src/mesa/program/symbol_table.c \
$(GLSL_COMPILER_CXX_FILES) \
builtin_stubs.cpp
diff --git a/mesalib/src/glsl/builtin_types.h b/mesalib/src/glsl/builtin_types.h
index 92427d8e7..a4c995fd1 100644
--- a/mesalib/src/glsl/builtin_types.h
+++ b/mesalib/src/glsl/builtin_types.h
@@ -31,6 +31,11 @@ const glsl_type glsl_type::_sampler3D_type =
glsl_type(GL_SAMPLER_3D, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_FLOAT,
"sampler3D");
+const glsl_type glsl_type::_samplerCubeShadow_type =
+ glsl_type(GL_SAMPLER_CUBE_SHADOW,
+ GLSL_SAMPLER_DIM_CUBE, 1, 0, GLSL_TYPE_FLOAT,
+ "samplerCubeShadow");
+
const glsl_type *const glsl_type::error_type = & glsl_type::_error_type;
const glsl_type *const glsl_type::void_type = & glsl_type::_void_type;
diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp
index 353805b7f..e7769419f 100644
--- a/mesalib/src/glsl/builtin_variables.cpp
+++ b/mesalib/src/glsl/builtin_variables.cpp
@@ -61,6 +61,17 @@ static const builtin_variable builtin_100ES_fs_variables[] = {
{ ir_var_in, FRAG_ATTRIB_PNTC, "vec2", "gl_PointCoord" },
};
+static const builtin_variable builtin_300ES_vs_variables[] = {
+ { ir_var_system_value, SYSTEM_VALUE_VERTEX_ID, "int", "gl_VertexID" },
+};
+
+static const builtin_variable builtin_300ES_fs_variables[] = {
+ { ir_var_in, FRAG_ATTRIB_WPOS, "vec4", "gl_FragCoord" },
+ { ir_var_in, FRAG_ATTRIB_FACE, "bool", "gl_FrontFacing" },
+ { ir_var_out, FRAG_RESULT_DEPTH, "float", "gl_FragDepth" },
+ { ir_var_in, FRAG_ATTRIB_PNTC, "vec2", "gl_PointCoord" },
+};
+
static const builtin_variable builtin_110_fs_variables[] = {
{ ir_var_out, FRAG_RESULT_DEPTH, "float", "gl_FragDepth" },
};
@@ -499,12 +510,15 @@ add_builtin_constant(exec_list *instructions, glsl_symbol_table *symtab,
return var;
}
-/* Several constants in GLSL ES have different names than normal desktop GLSL.
+/**
+ * Uniforms that are common to all GLSL ES implementations.
+ *
+ * Several constants in GLSL ES have different names than normal desktop GLSL.
* Therefore, this function should only be called on the ES path.
*/
static void
-generate_100ES_uniforms(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
+generate_common_ES_uniforms(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
{
glsl_symbol_table *const symtab = state->symbols;
@@ -512,8 +526,6 @@ generate_100ES_uniforms(exec_list *instructions,
state->Const.MaxVertexAttribs);
add_builtin_constant(instructions, symtab, "gl_MaxVertexUniformVectors",
state->Const.MaxVertexUniformComponents);
- add_builtin_constant(instructions, symtab, "gl_MaxVaryingVectors",
- state->Const.MaxVaryingFloats / 4);
add_builtin_constant(instructions, symtab, "gl_MaxVertexTextureImageUnits",
state->Const.MaxVertexTextureImageUnits);
add_builtin_constant(instructions, symtab, "gl_MaxCombinedTextureImageUnits",
@@ -528,6 +540,36 @@ generate_100ES_uniforms(exec_list *instructions,
}
static void
+generate_100ES_uniforms(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ generate_common_ES_uniforms(instructions, state);
+
+ glsl_symbol_table *const symtab = state->symbols;
+
+ add_builtin_constant(instructions, symtab, "gl_MaxVaryingVectors",
+ state->Const.MaxVaryingFloats / 4);
+}
+
+static void
+generate_300ES_uniforms(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ generate_common_ES_uniforms(instructions, state);
+
+ glsl_symbol_table *const symtab = state->symbols;
+
+ add_builtin_constant(instructions, symtab, "gl_MaxVertexOutputVectors",
+ state->Const.MaxVaryingFloats / 4);
+ add_builtin_constant(instructions, symtab, "gl_MaxFragmentInputVectors",
+ state->Const.MaxVaryingFloats / 4);
+ add_builtin_constant(instructions, symtab, "gl_MinProgramTexelOffset",
+ state->Const.MinProgramTexelOffset);
+ add_builtin_constant(instructions, symtab, "gl_MaxProgramTexelOffset",
+ state->Const.MaxProgramTexelOffset);
+}
+
+static void
generate_110_uniforms(exec_list *instructions,
struct _mesa_glsl_parse_state *state,
bool add_deprecated)
@@ -657,6 +699,26 @@ generate_100ES_vs_variables(exec_list *instructions,
vertex_shader);
}
+static void
+generate_300ES_vs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) {
+ add_builtin_variable(instructions, state->symbols,
+ & builtin_core_vs_variables[i]);
+ }
+
+ for (unsigned i = 0; i < Elements(builtin_300ES_vs_variables); i++) {
+ add_builtin_variable(instructions, state->symbols,
+ & builtin_300ES_vs_variables[i]);
+ }
+
+ generate_300ES_uniforms(instructions, state);
+
+ generate_ARB_draw_buffers_variables(instructions, state, false,
+ vertex_shader);
+}
+
static void
generate_110_vs_variables(exec_list *instructions,
@@ -760,23 +822,36 @@ static void
initialize_vs_variables(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
-
- switch (state->language_version) {
- case 100:
- generate_100ES_vs_variables(instructions, state);
- break;
- case 110:
- generate_110_vs_variables(instructions, state, true);
- break;
- case 120:
- generate_120_vs_variables(instructions, state, true);
- break;
- case 130:
- generate_130_vs_variables(instructions, state, true);
- break;
- case 140:
- generate_130_vs_variables(instructions, state, false);
- break;
+ if (state->es_shader) {
+ switch (state->language_version) {
+ case 100:
+ generate_100ES_vs_variables(instructions, state);
+ break;
+ case 300:
+ generate_300ES_vs_variables(instructions, state);
+ break;
+ default:
+ assert(!"Unexpected language version");
+ break;
+ }
+ } else {
+ switch (state->language_version) {
+ case 110:
+ generate_110_vs_variables(instructions, state, true);
+ break;
+ case 120:
+ generate_120_vs_variables(instructions, state, true);
+ break;
+ case 130:
+ generate_130_vs_variables(instructions, state, true);
+ break;
+ case 140:
+ generate_130_vs_variables(instructions, state, false);
+ break;
+ default:
+ assert(!"Unexpected language version");
+ break;
+ }
}
generate_ARB_draw_instanced_variables(instructions, state, false,
@@ -806,6 +881,25 @@ generate_100ES_fs_variables(exec_list *instructions,
}
static void
+generate_300ES_fs_variables(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ /* Note: we don't add builtin_core_fs_variables, because it contains
+ * gl_FragColor, which is not in GLSL 3.00 ES.
+ */
+
+ for (unsigned i = 0; i < Elements(builtin_300ES_fs_variables); i++) {
+ add_builtin_variable(instructions, state->symbols,
+ & builtin_300ES_fs_variables[i]);
+ }
+
+ generate_300ES_uniforms(instructions, state);
+
+ generate_ARB_draw_buffers_variables(instructions, state, false,
+ fragment_shader);
+}
+
+static void
generate_110_fs_variables(exec_list *instructions,
struct _mesa_glsl_parse_state *state,
bool add_deprecated)
@@ -865,8 +959,9 @@ generate_ARB_draw_buffers_variables(exec_list *instructions,
mdb->warn_extension = "GL_ARB_draw_buffers";
/* gl_FragData is only available in the fragment shader.
+ * It is not present in GLSL 3.00 ES.
*/
- if (target == fragment_shader) {
+ if (target == fragment_shader && !state->is_version(0, 300)) {
const glsl_type *const vec4_array_type =
glsl_type::get_array_instance(glsl_type::vec4_type,
state->Const.MaxDrawBuffers);
@@ -903,7 +998,8 @@ generate_ARB_draw_instanced_variables(exec_list *instructions,
inst->warn_extension = "GL_ARB_draw_instanced";
}
- if (state->ARB_draw_instanced_enable || state->language_version >= 140) {
+ bool available_in_core = state->is_version(140, 300);
+ if (state->ARB_draw_instanced_enable || available_in_core) {
/* Originally ARB_draw_instanced only specified that ARB decorated name.
* Since no vendor actually implemented that behavior and some apps use
* the undecorated name, the extension now specifies that both names are
@@ -914,7 +1010,7 @@ generate_ARB_draw_instanced_variables(exec_list *instructions,
"gl_InstanceID", glsl_type::int_type,
ir_var_system_value, SYSTEM_VALUE_INSTANCE_ID);
- if (state->language_version < 140 && warn)
+ if (!available_in_core && warn)
inst->warn_extension = "GL_ARB_draw_instanced";
}
}
@@ -1016,23 +1112,36 @@ static void
initialize_fs_variables(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
{
-
- switch (state->language_version) {
- case 100:
- generate_100ES_fs_variables(instructions, state);
- break;
- case 110:
- generate_110_fs_variables(instructions, state, true);
- break;
- case 120:
- generate_120_fs_variables(instructions, state, true);
- break;
- case 130:
- generate_130_fs_variables(instructions, state);
- break;
- case 140:
- generate_140_fs_variables(instructions, state);
- break;
+ if (state->es_shader) {
+ switch (state->language_version) {
+ case 100:
+ generate_100ES_fs_variables(instructions, state);
+ break;
+ case 300:
+ generate_300ES_fs_variables(instructions, state);
+ break;
+ default:
+ assert(!"Unexpected language version");
+ break;
+ }
+ } else {
+ switch (state->language_version) {
+ case 110:
+ generate_110_fs_variables(instructions, state, true);
+ break;
+ case 120:
+ generate_120_fs_variables(instructions, state, true);
+ break;
+ case 130:
+ generate_130_fs_variables(instructions, state);
+ break;
+ case 140:
+ generate_140_fs_variables(instructions, state);
+ break;
+ default:
+ assert(!"Unexpected language version");
+ break;
+ }
}
if (state->ARB_shader_stencil_export_enable)
diff --git a/mesalib/src/glsl/glcpp/Makefile.am b/mesalib/src/glsl/glcpp/Makefile.am
index 04d8cda01..d8d39d295 100644
--- a/mesalib/src/glsl/glcpp/Makefile.am
+++ b/mesalib/src/glsl/glcpp/Makefile.am
@@ -46,7 +46,7 @@ libglcpp_la_SOURCES = \
glcpp_SOURCES = \
../ralloc.c \
- $(top_srcdir)/src/mesa/program/hash_table.c \
+ $(top_srcdir)/src/mesa/program/prog_hash_table.c \
glcpp.c
glcpp_LDADD = libglcpp.la
diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y
index e7daf7fea..380a1d99c 100644
--- a/mesalib/src/glsl/glcpp/glcpp-parse.y
+++ b/mesalib/src/glsl/glcpp/glcpp-parse.y
@@ -133,6 +133,10 @@ _glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc,
static void
_glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc);
+static void
+_glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version,
+ const char *ident);
+
static int
glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser);
@@ -334,25 +338,10 @@ control_line:
_glcpp_parser_skip_stack_pop (parser, & @1);
} NEWLINE
| HASH_VERSION integer_constant NEWLINE {
- macro_t *macro = hash_table_find (parser->defines, "__VERSION__");
- if (macro) {
- hash_table_remove (parser->defines, "__VERSION__");
- ralloc_free (macro);
- }
- add_builtin_define (parser, "__VERSION__", $2);
-
- if ($2 == 100)
- add_builtin_define (parser, "GL_ES", 1);
-
- /* Currently, all ES2 implementations support highp in the
- * fragment shader, so we always define this macro in ES2.
- * If we ever get a driver that doesn't support highp, we'll
- * need to add a flag to the gl_context and check that here.
- */
- if ($2 >= 130 || $2 == 100)
- add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1);
-
- ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#version %" PRIiMAX, $2);
+ _glcpp_parser_handle_version_declaration(parser, $2, NULL);
+ }
+| HASH_VERSION integer_constant IDENTIFIER NEWLINE {
+ _glcpp_parser_handle_version_declaration(parser, $2, $3);
}
| HASH NEWLINE
;
@@ -2032,3 +2021,38 @@ _glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc)
parser->skip_stack = node->next;
ralloc_free (node);
}
+
+static void
+_glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version,
+ const char *es_identifier)
+{
+ /* Note: We assume that if any identifier is present, it means ES.
+ * The GLSL parser will double-check that the identifier is correct.
+ */
+ bool is_es = es_identifier != NULL;
+
+ macro_t *macro = hash_table_find (parser->defines, "__VERSION__");
+ if (macro) {
+ hash_table_remove (parser->defines, "__VERSION__");
+ ralloc_free (macro);
+ }
+ add_builtin_define (parser, "__VERSION__", version);
+
+ if (version == 100)
+ is_es = true;
+ if (is_es)
+ add_builtin_define (parser, "GL_ES", 1);
+
+ /* Currently, all ES2/ES3 implementations support highp in the
+ * fragment shader, so we always define this macro in ES2/ES3.
+ * If we ever get a driver that doesn't support highp, we'll
+ * need to add a flag to the gl_context and check that here.
+ */
+ if (version >= 130 || is_es)
+ add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1);
+
+ ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length,
+ "#version %" PRIiMAX "%s%s", version,
+ es_identifier ? " " : "",
+ es_identifier ? es_identifier : "");
+}
diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll
index c538d7d8e..2f66c5828 100644
--- a/mesalib/src/glsl/glsl_lexer.ll
+++ b/mesalib/src/glsl/glsl_lexer.ll
@@ -48,20 +48,34 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);
*
* Certain words start out as identifiers, become reserved words in
* later language revisions, and finally become language keywords.
+ * This may happen at different times in desktop GLSL and GLSL ES.
*
* For example, consider the following lexer rule:
- * samplerBuffer KEYWORD(130, 140, SAMPLERBUFFER)
+ * samplerBuffer KEYWORD(130, 0, 140, 0, SAMPLERBUFFER)
*
* This means that "samplerBuffer" will be treated as:
* - a keyword (SAMPLERBUFFER token) ...in GLSL >= 1.40
* - a reserved word - error ...in GLSL >= 1.30
- * - an identifier ...in GLSL < 1.30
+ * - an identifier ...in GLSL < 1.30 or GLSL ES
*/
-#define KEYWORD(reserved_version, allowed_version, token) \
+#define KEYWORD(reserved_glsl, reserved_glsl_es, \
+ allowed_glsl, allowed_glsl_es, token) \
+ KEYWORD_WITH_ALT(reserved_glsl, reserved_glsl_es, \
+ allowed_glsl, allowed_glsl_es, false, token)
+
+/**
+ * Like the KEYWORD macro, but the word is also treated as a keyword
+ * if the given boolean expression is true.
+ */
+#define KEYWORD_WITH_ALT(reserved_glsl, reserved_glsl_es, \
+ allowed_glsl, allowed_glsl_es, \
+ alt_expr, token) \
do { \
- if (yyextra->language_version >= allowed_version) { \
+ if (yyextra->is_version(allowed_glsl, allowed_glsl_es) \
+ || alt_expr) { \
return token; \
- } else if (yyextra->language_version >= reserved_version) { \
+ } else if (yyextra->is_version(reserved_glsl, \
+ reserved_glsl_es)) { \
_mesa_glsl_error(yylloc, yyextra, \
"Illegal use of reserved word `%s'", yytext); \
return ERROR_TOK; \
@@ -71,15 +85,20 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);
} \
} while (0)
-/* The ES macro can be used in KEYWORD checks:
- *
- * word KEYWORD(110 || ES, 400, TOKEN)
- * ...means the word is reserved in GLSL ES 1.00, while
- *
- * word KEYWORD(110, 130 || ES, TOKEN)
- * ...means the word is a legal keyword in GLSL ES 1.00.
+/**
+ * A macro for handling keywords that have been present in GLSL since
+ * its origin, but were changed into reserved words in GLSL 3.00 ES.
*/
-#define ES yyextra->es_shader
+#define DEPRECATED_ES_KEYWORD(token) \
+ do { \
+ if (yyextra->is_version(0, 300)) { \
+ _mesa_glsl_error(yylloc, yyextra, \
+ "Illegal use of reserved word `%s'", yytext); \
+ return ERROR_TOK; \
+ } else { \
+ return token; \
+ } \
+ } while (0)
static int
literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state,
@@ -103,7 +122,7 @@ literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state,
if (value > UINT_MAX) {
/* Note that signed 0xffffffff is valid, not out of range! */
- if (state->language_version >= 130) {
+ if (state->is_version(130, 300)) {
_mesa_glsl_error(lloc, state,
"Literal value `%s' out of range", text);
} else {
@@ -219,12 +238,12 @@ HASH ^{SPC}#{SPC}
\n { yylineno++; yycolumn = 0; }
-attribute return ATTRIBUTE;
+attribute DEPRECATED_ES_KEYWORD(ATTRIBUTE);
const return CONST_TOK;
bool return BOOL_TOK;
float return FLOAT_TOK;
int return INT_TOK;
-uint KEYWORD(130, 130, UINT_TOK);
+uint KEYWORD(130, 300, 130, 300, UINT_TOK);
break return BREAK;
continue return CONTINUE;
@@ -242,59 +261,59 @@ bvec4 return BVEC4;
ivec2 return IVEC2;
ivec3 return IVEC3;
ivec4 return IVEC4;
-uvec2 KEYWORD(130, 130, UVEC2);
-uvec3 KEYWORD(130, 130, UVEC3);
-uvec4 KEYWORD(130, 130, UVEC4);
+uvec2 KEYWORD(130, 300, 130, 300, UVEC2);
+uvec3 KEYWORD(130, 300, 130, 300, UVEC3);
+uvec4 KEYWORD(130, 300, 130, 300, UVEC4);
vec2 return VEC2;
vec3 return VEC3;
vec4 return VEC4;
mat2 return MAT2X2;
mat3 return MAT3X3;
mat4 return MAT4X4;
-mat2x2 KEYWORD(120, 120, MAT2X2);
-mat2x3 KEYWORD(120, 120, MAT2X3);
-mat2x4 KEYWORD(120, 120, MAT2X4);
-mat3x2 KEYWORD(120, 120, MAT3X2);
-mat3x3 KEYWORD(120, 120, MAT3X3);
-mat3x4 KEYWORD(120, 120, MAT3X4);
-mat4x2 KEYWORD(120, 120, MAT4X2);
-mat4x3 KEYWORD(120, 120, MAT4X3);
-mat4x4 KEYWORD(120, 120, MAT4X4);
+mat2x2 KEYWORD(120, 300, 120, 300, MAT2X2);
+mat2x3 KEYWORD(120, 300, 120, 300, MAT2X3);
+mat2x4 KEYWORD(120, 300, 120, 300, MAT2X4);
+mat3x2 KEYWORD(120, 300, 120, 300, MAT3X2);
+mat3x3 KEYWORD(120, 300, 120, 300, MAT3X3);
+mat3x4 KEYWORD(120, 300, 120, 300, MAT3X4);
+mat4x2 KEYWORD(120, 300, 120, 300, MAT4X2);
+mat4x3 KEYWORD(120, 300, 120, 300, MAT4X3);
+mat4x4 KEYWORD(120, 300, 120, 300, MAT4X4);
in return IN_TOK;
out return OUT_TOK;
inout return INOUT_TOK;
uniform return UNIFORM;
-varying return VARYING;
-centroid KEYWORD(120, 120, CENTROID);
-invariant KEYWORD(120 || ES, 120 || ES, INVARIANT);
-flat KEYWORD(130 || ES, 130, FLAT);
-smooth KEYWORD(130, 130, SMOOTH);
-noperspective KEYWORD(130, 130, NOPERSPECTIVE);
-
-sampler1D return SAMPLER1D;
+varying DEPRECATED_ES_KEYWORD(VARYING);
+centroid KEYWORD(120, 300, 120, 300, CENTROID);
+invariant KEYWORD(120, 100, 120, 100, INVARIANT);
+flat KEYWORD(130, 100, 130, 300, FLAT);
+smooth KEYWORD(130, 300, 130, 300, SMOOTH);
+noperspective KEYWORD(130, 300, 130, 0, NOPERSPECTIVE);
+
+sampler1D DEPRECATED_ES_KEYWORD(SAMPLER1D);
sampler2D return SAMPLER2D;
sampler3D return SAMPLER3D;
samplerCube return SAMPLERCUBE;
-sampler1DArray KEYWORD(130, 130, SAMPLER1DARRAY);
-sampler2DArray KEYWORD(130, 130, SAMPLER2DARRAY);
-sampler1DShadow return SAMPLER1DSHADOW;
+sampler1DArray KEYWORD(130, 300, 130, 0, SAMPLER1DARRAY);
+sampler2DArray KEYWORD(130, 300, 130, 300, SAMPLER2DARRAY);
+sampler1DShadow DEPRECATED_ES_KEYWORD(SAMPLER1DSHADOW);
sampler2DShadow return SAMPLER2DSHADOW;
-samplerCubeShadow KEYWORD(130, 130, SAMPLERCUBESHADOW);
-sampler1DArrayShadow KEYWORD(130, 130, SAMPLER1DARRAYSHADOW);
-sampler2DArrayShadow KEYWORD(130, 130, SAMPLER2DARRAYSHADOW);
-isampler1D KEYWORD(130, 130, ISAMPLER1D);
-isampler2D KEYWORD(130, 130, ISAMPLER2D);
-isampler3D KEYWORD(130, 130, ISAMPLER3D);
-isamplerCube KEYWORD(130, 130, ISAMPLERCUBE);
-isampler1DArray KEYWORD(130, 130, ISAMPLER1DARRAY);
-isampler2DArray KEYWORD(130, 130, ISAMPLER2DARRAY);
-usampler1D KEYWORD(130, 130, USAMPLER1D);
-usampler2D KEYWORD(130, 130, USAMPLER2D);
-usampler3D KEYWORD(130, 130, USAMPLER3D);
-usamplerCube KEYWORD(130, 130, USAMPLERCUBE);
-usampler1DArray KEYWORD(130, 130, USAMPLER1DARRAY);
-usampler2DArray KEYWORD(130, 130, USAMPLER2DARRAY);
+samplerCubeShadow KEYWORD(130, 300, 130, 300, SAMPLERCUBESHADOW);
+sampler1DArrayShadow KEYWORD(130, 300, 130, 0, SAMPLER1DARRAYSHADOW);
+sampler2DArrayShadow KEYWORD(130, 300, 130, 300, SAMPLER2DARRAYSHADOW);
+isampler1D KEYWORD(130, 300, 130, 0, ISAMPLER1D);
+isampler2D KEYWORD(130, 300, 130, 300, ISAMPLER2D);
+isampler3D KEYWORD(130, 300, 130, 300, ISAMPLER3D);
+isamplerCube KEYWORD(130, 300, 130, 300, ISAMPLERCUBE);
+isampler1DArray KEYWORD(130, 300, 130, 0, ISAMPLER1DARRAY);
+isampler2DArray KEYWORD(130, 300, 130, 300, ISAMPLER2DARRAY);
+usampler1D KEYWORD(130, 300, 130, 0, USAMPLER1D);
+usampler2D KEYWORD(130, 300, 130, 300, USAMPLER2D);
+usampler3D KEYWORD(130, 300, 130, 300, USAMPLER3D);
+usamplerCube KEYWORD(130, 300, 130, 300, USAMPLERCUBE);
+usampler1DArray KEYWORD(130, 300, 130, 0, USAMPLER1DARRAY);
+usampler2DArray KEYWORD(130, 300, 130, 300, USAMPLER2DARRAY);
samplerCubeArray {
if (yyextra->ARB_texture_cube_map_array_enable)
@@ -333,7 +352,7 @@ struct return STRUCT;
void return VOID_TOK;
layout {
- if ((yyextra->language_version >= 140)
+ if ((yyextra->is_version(140, 300))
|| yyextra->AMD_conservative_depth_enable
|| yyextra->ARB_conservative_depth_enable
|| yyextra->ARB_explicit_attrib_location_enable
@@ -411,96 +430,114 @@ false {
/* Reserved words in GLSL 1.10. */
-asm KEYWORD(110 || ES, 999, ASM);
-class KEYWORD(110 || ES, 999, CLASS);
-union KEYWORD(110 || ES, 999, UNION);
-enum KEYWORD(110 || ES, 999, ENUM);
-typedef KEYWORD(110 || ES, 999, TYPEDEF);
-template KEYWORD(110 || ES, 999, TEMPLATE);
-this KEYWORD(110 || ES, 999, THIS);
-packed KEYWORD(110 || ES, 140 || yyextra->ARB_uniform_buffer_object_enable, PACKED_TOK);
-goto KEYWORD(110 || ES, 999, GOTO);
-switch KEYWORD(110 || ES, 130, SWITCH);
-default KEYWORD(110 || ES, 130, DEFAULT);
-inline KEYWORD(110 || ES, 999, INLINE_TOK);
-noinline KEYWORD(110 || ES, 999, NOINLINE);
-volatile KEYWORD(110 || ES, 999, VOLATILE);
-public KEYWORD(110 || ES, 999, PUBLIC_TOK);
-static KEYWORD(110 || ES, 999, STATIC);
-extern KEYWORD(110 || ES, 999, EXTERN);
-external KEYWORD(110 || ES, 999, EXTERNAL);
-interface KEYWORD(110 || ES, 999, INTERFACE);
-long KEYWORD(110 || ES, 999, LONG_TOK);
-short KEYWORD(110 || ES, 999, SHORT_TOK);
-double KEYWORD(110 || ES, 400, DOUBLE_TOK);
-half KEYWORD(110 || ES, 999, HALF);
-fixed KEYWORD(110 || ES, 999, FIXED_TOK);
-unsigned KEYWORD(110 || ES, 999, UNSIGNED);
-input KEYWORD(110 || ES, 999, INPUT_TOK);
-output KEYWORD(110 || ES, 999, OUTPUT);
-hvec2 KEYWORD(110 || ES, 999, HVEC2);
-hvec3 KEYWORD(110 || ES, 999, HVEC3);
-hvec4 KEYWORD(110 || ES, 999, HVEC4);
-dvec2 KEYWORD(110 || ES, 400, DVEC2);
-dvec3 KEYWORD(110 || ES, 400, DVEC3);
-dvec4 KEYWORD(110 || ES, 400, DVEC4);
-fvec2 KEYWORD(110 || ES, 999, FVEC2);
-fvec3 KEYWORD(110 || ES, 999, FVEC3);
-fvec4 KEYWORD(110 || ES, 999, FVEC4);
-sampler2DRect return SAMPLER2DRECT;
-sampler3DRect KEYWORD(110 || ES, 999, SAMPLER3DRECT);
-sampler2DRectShadow return SAMPLER2DRECTSHADOW;
-sizeof KEYWORD(110 || ES, 999, SIZEOF);
-cast KEYWORD(110 || ES, 999, CAST);
-namespace KEYWORD(110 || ES, 999, NAMESPACE);
-using KEYWORD(110 || ES, 999, USING);
+asm KEYWORD(110, 100, 0, 0, ASM);
+class KEYWORD(110, 100, 0, 0, CLASS);
+union KEYWORD(110, 100, 0, 0, UNION);
+enum KEYWORD(110, 100, 0, 0, ENUM);
+typedef KEYWORD(110, 100, 0, 0, TYPEDEF);
+template KEYWORD(110, 100, 0, 0, TEMPLATE);
+this KEYWORD(110, 100, 0, 0, THIS);
+packed KEYWORD_WITH_ALT(110, 100, 140, 300, yyextra->ARB_uniform_buffer_object_enable, PACKED_TOK);
+goto KEYWORD(110, 100, 0, 0, GOTO);
+switch KEYWORD(110, 100, 130, 300, SWITCH);
+default KEYWORD(110, 100, 130, 300, DEFAULT);
+inline KEYWORD(110, 100, 0, 0, INLINE_TOK);
+noinline KEYWORD(110, 100, 0, 0, NOINLINE);
+volatile KEYWORD(110, 100, 0, 0, VOLATILE);
+public KEYWORD(110, 100, 0, 0, PUBLIC_TOK);
+static KEYWORD(110, 100, 0, 0, STATIC);
+extern KEYWORD(110, 100, 0, 0, EXTERN);
+external KEYWORD(110, 100, 0, 0, EXTERNAL);
+interface KEYWORD(110, 100, 0, 0, INTERFACE);
+long KEYWORD(110, 100, 0, 0, LONG_TOK);
+short KEYWORD(110, 100, 0, 0, SHORT_TOK);
+double KEYWORD(110, 100, 400, 0, DOUBLE_TOK);
+half KEYWORD(110, 100, 0, 0, HALF);
+fixed KEYWORD(110, 100, 0, 0, FIXED_TOK);
+unsigned KEYWORD(110, 100, 0, 0, UNSIGNED);
+input KEYWORD(110, 100, 0, 0, INPUT_TOK);
+output KEYWORD(110, 100, 0, 0, OUTPUT);
+hvec2 KEYWORD(110, 100, 0, 0, HVEC2);
+hvec3 KEYWORD(110, 100, 0, 0, HVEC3);
+hvec4 KEYWORD(110, 100, 0, 0, HVEC4);
+dvec2 KEYWORD(110, 100, 400, 0, DVEC2);
+dvec3 KEYWORD(110, 100, 400, 0, DVEC3);
+dvec4 KEYWORD(110, 100, 400, 0, DVEC4);
+fvec2 KEYWORD(110, 100, 0, 0, FVEC2);
+fvec3 KEYWORD(110, 100, 0, 0, FVEC3);
+fvec4 KEYWORD(110, 100, 0, 0, FVEC4);
+sampler2DRect DEPRECATED_ES_KEYWORD(SAMPLER2DRECT);
+sampler3DRect KEYWORD(110, 100, 0, 0, SAMPLER3DRECT);
+sampler2DRectShadow DEPRECATED_ES_KEYWORD(SAMPLER2DRECTSHADOW);
+sizeof KEYWORD(110, 100, 0, 0, SIZEOF);
+cast KEYWORD(110, 100, 0, 0, CAST);
+namespace KEYWORD(110, 100, 0, 0, NAMESPACE);
+using KEYWORD(110, 100, 0, 0, USING);
/* Additional reserved words in GLSL 1.20. */
-lowp KEYWORD(120, 130 || ES, LOWP);
-mediump KEYWORD(120, 130 || ES, MEDIUMP);
-highp KEYWORD(120, 130 || ES, HIGHP);
-precision KEYWORD(120, 130 || ES, PRECISION);
+lowp KEYWORD(120, 100, 130, 100, LOWP);
+mediump KEYWORD(120, 100, 130, 100, MEDIUMP);
+highp KEYWORD(120, 100, 130, 100, HIGHP);
+precision KEYWORD(120, 100, 130, 100, PRECISION);
/* Additional reserved words in GLSL 1.30. */
-case KEYWORD(130, 130, CASE);
-common KEYWORD(130, 999, COMMON);
-partition KEYWORD(130, 999, PARTITION);
-active KEYWORD(130, 999, ACTIVE);
-superp KEYWORD(130 || ES, 999, SUPERP);
-samplerBuffer KEYWORD(130, 140, SAMPLERBUFFER);
-filter KEYWORD(130, 999, FILTER);
-image1D KEYWORD(130, 999, IMAGE1D);
-image2D KEYWORD(130, 999, IMAGE2D);
-image3D KEYWORD(130, 999, IMAGE3D);
-imageCube KEYWORD(130, 999, IMAGECUBE);
-iimage1D KEYWORD(130, 999, IIMAGE1D);
-iimage2D KEYWORD(130, 999, IIMAGE2D);
-iimage3D KEYWORD(130, 999, IIMAGE3D);
-iimageCube KEYWORD(130, 999, IIMAGECUBE);
-uimage1D KEYWORD(130, 999, UIMAGE1D);
-uimage2D KEYWORD(130, 999, UIMAGE2D);
-uimage3D KEYWORD(130, 999, UIMAGE3D);
-uimageCube KEYWORD(130, 999, UIMAGECUBE);
-image1DArray KEYWORD(130, 999, IMAGE1DARRAY);
-image2DArray KEYWORD(130, 999, IMAGE2DARRAY);
-iimage1DArray KEYWORD(130, 999, IIMAGE1DARRAY);
-iimage2DArray KEYWORD(130, 999, IIMAGE2DARRAY);
-uimage1DArray KEYWORD(130, 999, UIMAGE1DARRAY);
-uimage2DArray KEYWORD(130, 999, UIMAGE2DARRAY);
-image1DShadow KEYWORD(130, 999, IMAGE1DSHADOW);
-image2DShadow KEYWORD(130, 999, IMAGE2DSHADOW);
-image1DArrayShadow KEYWORD(130, 999, IMAGE1DARRAYSHADOW);
-image2DArrayShadow KEYWORD(130, 999, IMAGE2DARRAYSHADOW);
-imageBuffer KEYWORD(130, 999, IMAGEBUFFER);
-iimageBuffer KEYWORD(130, 999, IIMAGEBUFFER);
-uimageBuffer KEYWORD(130, 999, UIMAGEBUFFER);
-row_major KEYWORD(130, 140 || yyextra->ARB_uniform_buffer_object_enable, ROW_MAJOR);
+case KEYWORD(130, 300, 130, 300, CASE);
+common KEYWORD(130, 300, 0, 0, COMMON);
+partition KEYWORD(130, 300, 0, 0, PARTITION);
+active KEYWORD(130, 300, 0, 0, ACTIVE);
+superp KEYWORD(130, 100, 0, 0, SUPERP);
+samplerBuffer KEYWORD(130, 300, 140, 0, SAMPLERBUFFER);
+filter KEYWORD(130, 300, 0, 0, FILTER);
+image1D KEYWORD(130, 300, 0, 0, IMAGE1D);
+image2D KEYWORD(130, 300, 0, 0, IMAGE2D);
+image3D KEYWORD(130, 300, 0, 0, IMAGE3D);
+imageCube KEYWORD(130, 300, 0, 0, IMAGECUBE);
+iimage1D KEYWORD(130, 300, 0, 0, IIMAGE1D);
+iimage2D KEYWORD(130, 300, 0, 0, IIMAGE2D);
+iimage3D KEYWORD(130, 300, 0, 0, IIMAGE3D);
+iimageCube KEYWORD(130, 300, 0, 0, IIMAGECUBE);
+uimage1D KEYWORD(130, 300, 0, 0, UIMAGE1D);
+uimage2D KEYWORD(130, 300, 0, 0, UIMAGE2D);
+uimage3D KEYWORD(130, 300, 0, 0, UIMAGE3D);
+uimageCube KEYWORD(130, 300, 0, 0, UIMAGECUBE);
+image1DArray KEYWORD(130, 300, 0, 0, IMAGE1DARRAY);
+image2DArray KEYWORD(130, 300, 0, 0, IMAGE2DARRAY);
+iimage1DArray KEYWORD(130, 300, 0, 0, IIMAGE1DARRAY);
+iimage2DArray KEYWORD(130, 300, 0, 0, IIMAGE2DARRAY);
+uimage1DArray KEYWORD(130, 300, 0, 0, UIMAGE1DARRAY);
+uimage2DArray KEYWORD(130, 300, 0, 0, UIMAGE2DARRAY);
+image1DShadow KEYWORD(130, 300, 0, 0, IMAGE1DSHADOW);
+image2DShadow KEYWORD(130, 300, 0, 0, IMAGE2DSHADOW);
+image1DArrayShadow KEYWORD(130, 300, 0, 0, IMAGE1DARRAYSHADOW);
+image2DArrayShadow KEYWORD(130, 300, 0, 0, IMAGE2DARRAYSHADOW);
+imageBuffer KEYWORD(130, 300, 0, 0, IMAGEBUFFER);
+iimageBuffer KEYWORD(130, 300, 0, 0, IIMAGEBUFFER);
+uimageBuffer KEYWORD(130, 300, 0, 0, UIMAGEBUFFER);
+row_major KEYWORD_WITH_ALT(130, 0, 140, 0, yyextra->ARB_uniform_buffer_object_enable, ROW_MAJOR);
/* Additional reserved words in GLSL 1.40 */
-isampler2DRect KEYWORD(140, 140, ISAMPLER2DRECT);
-usampler2DRect KEYWORD(140, 140, USAMPLER2DRECT);
-isamplerBuffer KEYWORD(140, 140, ISAMPLERBUFFER);
-usamplerBuffer KEYWORD(140, 140, USAMPLERBUFFER);
+isampler2DRect KEYWORD(140, 300, 140, 0, ISAMPLER2DRECT);
+usampler2DRect KEYWORD(140, 300, 140, 0, USAMPLER2DRECT);
+isamplerBuffer KEYWORD(140, 300, 140, 0, ISAMPLERBUFFER);
+usamplerBuffer KEYWORD(140, 300, 140, 0, USAMPLERBUFFER);
+
+ /* Additional reserved words in GLSL ES 3.00 */
+coherent KEYWORD(0, 300, 0, 0, COHERENT);
+restrict KEYWORD(0, 300, 0, 0, RESTRICT);
+readonly KEYWORD(0, 300, 0, 0, READONLY);
+writeonly KEYWORD(0, 300, 0, 0, WRITEONLY);
+resource KEYWORD(0, 300, 0, 0, RESOURCE);
+atomic_uint KEYWORD(0, 300, 0, 0, ATOMIC_UINT);
+patch KEYWORD(0, 300, 0, 0, PATCH);
+sample KEYWORD(0, 300, 0, 0, SAMPLE);
+subroutine KEYWORD(0, 300, 0, 0, SUBROUTINE);
+sampler2DMS KEYWORD(0, 300, 0, 0, SAMPLER2DMS);
+isampler2DMS KEYWORD(0, 300, 0, 0, ISAMPLER2DMS);
+usampler2DMS KEYWORD(0, 300, 0, 0, USAMPLER2DMS);
+sampler2DMSArray KEYWORD(0, 300, 0, 0, SAMPLER2DMSARRAY);
+isampler2DMSArray KEYWORD(0, 300, 0, 0, ISAMPLER2DMSARRAY);
+usampler2DMSArray KEYWORD(0, 300, 0, 0, USAMPLER2DMSARRAY);
+
[_a-zA-Z][_a-zA-Z0-9]* {
struct _mesa_glsl_parse_state *state = yyextra;
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index 407dbbeeb..d8494667b 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -137,6 +137,9 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg)
%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4
%token SAMPLER3DRECT
%token SIZEOF CAST NAMESPACE USING
+%token COHERENT RESTRICT READONLY WRITEONLY RESOURCE ATOMIC_UINT PATCH SAMPLE
+%token SUBROUTINE SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS SAMPLER2DMSARRAY
+%token ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
%token ERROR_TOK
@@ -258,54 +261,12 @@ version_statement:
/* blank - no #version specified: defaults are already set */
| VERSION_TOK INTCONSTANT EOL
{
- bool supported = false;
-
- switch ($2) {
- case 100:
- state->es_shader = true;
- supported = state->ctx->API == API_OPENGLES2 ||
- state->ctx->Extensions.ARB_ES2_compatibility;
- break;
- case 110:
- case 120:
- /* FINISHME: Once the OpenGL 3.0 'forward compatible' context or
- * the OpenGL 3.2 Core context is supported, this logic will need
- * change. Older versions of GLSL are no longer supported
- * outside the compatibility contexts of 3.x.
- */
- case 130:
- case 140:
- case 150:
- case 330:
- case 400:
- case 410:
- case 420:
- supported = _mesa_is_desktop_gl(state->ctx) &&
- ((unsigned) $2) <= state->ctx->Const.GLSLVersion;
- break;
- default:
- supported = false;
- break;
- }
-
- state->language_version = $2;
- state->version_string =
- ralloc_asprintf(state, "GLSL%s %d.%02d",
- state->es_shader ? " ES" : "",
- state->language_version / 100,
- state->language_version % 100);
-
- if (!supported) {
- _mesa_glsl_error(& @2, state, "%s is not supported. "
- "Supported versions are: %s\n",
- state->version_string,
- state->supported_version_string);
- }
-
- if (state->language_version >= 140) {
- state->ARB_uniform_buffer_object_enable = true;
- }
+ state->process_version_directive(&@2, $2, NULL);
}
+ | VERSION_TOK INTCONSTANT any_identifier EOL
+ {
+ state->process_version_directive(&@2, $2, $3);
+ }
;
pragma_statement:
@@ -315,10 +276,11 @@ pragma_statement:
| PRAGMA_OPTIMIZE_OFF EOL
| PRAGMA_INVARIANT_ALL EOL
{
- if (state->language_version == 110) {
+ if (!state->is_version(120, 100)) {
_mesa_glsl_warning(& @1, state,
- "pragma `invariant(all)' not supported in %s",
- state->version_string);
+ "pragma `invariant(all)' not supported in %s "
+ "(GLSL ES 1.00 or GLSL 1.20 required).",
+ state->get_version_string());
} else {
state->all_invariant = true;
}
@@ -1126,6 +1088,7 @@ layout_qualifier_id_list:
integer_constant:
INTCONSTANT { $$ = $1; }
| UINTCONSTANT { $$ = $1; }
+ ;
layout_qualifier_id:
any_identifier
@@ -1181,6 +1144,8 @@ layout_qualifier_id:
$$.flags.q.shared = 1;
} else if (strcmp($1, "column_major") == 0) {
$$.flags.q.column_major = 1;
+ } else if (strcmp($1, "row_major") == 0) {
+ $$.flags.q.row_major = 1;
}
if ($$.flags.i && state->ARB_uniform_buffer_object_warn) {
@@ -1498,32 +1463,17 @@ basic_type_specifier_nonarray:
precision_qualifier:
HIGHP {
- if (!state->es_shader && state->language_version < 130)
- _mesa_glsl_error(& @1, state,
- "precision qualifier forbidden "
- "in %s (1.30 or later "
- "required)\n",
- state->version_string);
+ state->check_precision_qualifiers_allowed(&@1);
$$ = ast_precision_high;
}
| MEDIUMP {
- if (!state->es_shader && state->language_version < 130)
- _mesa_glsl_error(& @1, state,
- "precision qualifier forbidden "
- "in %s (1.30 or later "
- "required)\n",
- state->version_string);
+ state->check_precision_qualifiers_allowed(&@1);
$$ = ast_precision_medium;
}
| LOWP {
- if (!state->es_shader && state->language_version < 130)
- _mesa_glsl_error(& @1, state,
- "precision qualifier forbidden "
- "in %s (1.30 or later "
- "required)\n",
- state->version_string);
+ state->check_precision_qualifiers_allowed(&@1);
$$ = ast_precision_low;
}
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index f1fdd3a47..d36089226 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -37,6 +37,16 @@ extern "C" {
#include "ir_optimization.h"
#include "loop_analysis.h"
+/**
+ * Format a short human-readable description of the given GLSL version.
+ */
+const char *
+glsl_compute_version_string(void *mem_ctx, bool is_es, unsigned version)
+{
+ return ralloc_asprintf(mem_ctx, "GLSL%s %d.%02d", is_es ? " ES" : "",
+ version / 100, version % 100);
+}
+
_mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
GLenum target, void *mem_ctx)
: ctx(_ctx)
@@ -82,6 +92,8 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits;
this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents;
+ this->Const.MinProgramTexelOffset = ctx->Const.MinProgramTexelOffset;
+ this->Const.MaxProgramTexelOffset = ctx->Const.MaxProgramTexelOffset;
this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
@@ -113,6 +125,166 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
this->default_uniform_qualifier->flags.q.column_major = 1;
}
+/**
+ * Determine whether the current GLSL version is sufficiently high to support
+ * a certain feature, and generate an error message if it isn't.
+ *
+ * \param required_glsl_version and \c required_glsl_es_version are
+ * interpreted as they are in _mesa_glsl_parse_state::is_version().
+ *
+ * \param locp is the parser location where the error should be reported.
+ *
+ * \param fmt (and additional arguments) constitute a printf-style error
+ * message to report if the version check fails. Information about the
+ * current and required GLSL versions will be appended. So, for example, if
+ * the GLSL version being compiled is 1.20, and check_version(130, 300, locp,
+ * "foo unsupported") is called, the error message will be "foo unsupported in
+ * GLSL 1.20 (GLSL 1.30 or GLSL 3.00 ES required)".
+ */
+bool
+_mesa_glsl_parse_state::check_version(unsigned required_glsl_version,
+ unsigned required_glsl_es_version,
+ YYLTYPE *locp, const char *fmt, ...)
+{
+ if (this->is_version(required_glsl_version, required_glsl_es_version))
+ return true;
+
+ va_list args;
+ va_start(args, fmt);
+ char *problem = ralloc_vasprintf(ctx, fmt, args);
+ va_end(args);
+ const char *glsl_version_string
+ = glsl_compute_version_string(ctx, false, required_glsl_version);
+ const char *glsl_es_version_string
+ = glsl_compute_version_string(ctx, true, required_glsl_es_version);
+ const char *requirement_string = "";
+ if (required_glsl_version && required_glsl_es_version) {
+ requirement_string = ralloc_asprintf(ctx, " (%s or %s required)",
+ glsl_version_string,
+ glsl_es_version_string);
+ } else if (required_glsl_version) {
+ requirement_string = ralloc_asprintf(ctx, " (%s required)",
+ glsl_version_string);
+ } else if (required_glsl_es_version) {
+ requirement_string = ralloc_asprintf(ctx, " (%s required)",
+ glsl_es_version_string);
+ }
+ _mesa_glsl_error(locp, this, "%s in %s%s.",
+ problem, this->get_version_string(),
+ requirement_string);
+
+ return false;
+}
+
+/**
+ * Process a GLSL #version directive.
+ *
+ * \param version is the integer that follows the #version token.
+ *
+ * \param ident is a string identifier that follows the integer, if any is
+ * present. Otherwise NULL.
+ */
+void
+_mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version,
+ const char *ident)
+{
+ bool es_token_present = false;
+ if (ident) {
+ if (strcmp(ident, "es") == 0) {
+ es_token_present = true;
+ } else {
+ _mesa_glsl_error(locp, this,
+ "Illegal text following version number\n");
+ }
+ }
+
+ bool supported = false;
+
+ if (es_token_present) {
+ this->es_shader = true;
+ switch (version) {
+ case 100:
+ _mesa_glsl_error(locp, this,
+ "GLSL 1.00 ES should be selected using "
+ "`#version 100'\n");
+ supported = this->ctx->API == API_OPENGLES2 ||
+ this->ctx->Extensions.ARB_ES2_compatibility;
+ break;
+ case 300:
+ supported = _mesa_is_gles3(this->ctx) ||
+ this->ctx->Extensions.ARB_ES3_compatibility;
+ break;
+ default:
+ supported = false;
+ break;
+ }
+ } else {
+ switch (version) {
+ case 100:
+ this->es_shader = true;
+ supported = this->ctx->API == API_OPENGLES2 ||
+ this->ctx->Extensions.ARB_ES2_compatibility;
+ break;
+ case 110:
+ case 120:
+ /* FINISHME: Once the OpenGL 3.0 'forward compatible' context or
+ * the OpenGL 3.2 Core context is supported, this logic will need
+ * change. Older versions of GLSL are no longer supported
+ * outside the compatibility contexts of 3.x.
+ */
+ case 130:
+ case 140:
+ case 150:
+ case 330:
+ case 400:
+ case 410:
+ case 420:
+ supported = _mesa_is_desktop_gl(this->ctx) &&
+ ((unsigned) version) <= this->ctx->Const.GLSLVersion;
+ break;
+ default:
+ supported = false;
+ break;
+ }
+ }
+
+ this->language_version = version;
+
+ if (!supported) {
+ _mesa_glsl_error(locp, this, "%s is not supported. "
+ "Supported versions are: %s\n",
+ this->get_version_string(),
+ this->supported_version_string);
+
+ /* On exit, the language_version must be set to a valid value.
+ * Later calls to _mesa_glsl_initialize_types will misbehave if
+ * the version is invalid.
+ */
+ switch (this->ctx->API) {
+ case API_OPENGL_COMPAT:
+ case API_OPENGL_CORE:
+ this->language_version = this->ctx->Const.GLSLVersion;
+ break;
+
+ case API_OPENGLES:
+ assert(!"Should not get here.");
+ /* FALLTHROUGH */
+
+ case API_OPENGLES2:
+ this->language_version = 100;
+ break;
+ }
+ }
+
+ if (this->language_version >= 140) {
+ this->ARB_uniform_buffer_object_enable = true;
+ }
+
+ if (this->language_version == 300 && this->es_shader) {
+ this->ARB_explicit_attrib_location_enable = true;
+ }
+}
+
const char *
_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)
{
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index 17ebc76a7..01cf6a8d9 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -56,6 +56,19 @@ struct glsl_switch_state {
bool is_switch_innermost; // if switch stmt is closest to break, ...
};
+const char *
+glsl_compute_version_string(void *mem_ctx, bool is_es, unsigned version);
+
+typedef struct YYLTYPE {
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+ unsigned source;
+} YYLTYPE;
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+
struct _mesa_glsl_parse_state {
_mesa_glsl_parse_state(struct gl_context *_ctx, GLenum target,
void *mem_ctx);
@@ -81,6 +94,55 @@ struct _mesa_glsl_parse_state {
ralloc_free(mem);
}
+ /**
+ * Generate a string representing the GLSL version currently being compiled
+ * (useful for error messages).
+ */
+ const char *get_version_string()
+ {
+ return glsl_compute_version_string(this, this->es_shader,
+ this->language_version);
+ }
+
+ /**
+ * Determine whether the current GLSL version is sufficiently high to
+ * support a certain feature.
+ *
+ * \param required_glsl_version is the desktop GLSL version that is
+ * required to support the feature, or 0 if no version of desktop GLSL
+ * supports the feature.
+ *
+ * \param required_glsl_es_version is the GLSL ES version that is required
+ * to support the feature, or 0 if no version of GLSL ES suports the
+ * feature.
+ */
+ bool is_version(unsigned required_glsl_version,
+ unsigned required_glsl_es_version)
+ {
+ unsigned required_version = this->es_shader ?
+ required_glsl_es_version : required_glsl_version;
+ return required_version != 0
+ && this->language_version >= required_version;
+ }
+
+ bool check_version(unsigned required_glsl_version,
+ unsigned required_glsl_es_version,
+ YYLTYPE *locp, const char *fmt, ...) PRINTFLIKE(5, 6);
+
+ bool check_precision_qualifiers_allowed(YYLTYPE *locp)
+ {
+ return check_version(130, 100, locp,
+ "precision qualifiers are forbidden");
+ }
+
+ bool check_bitwise_operations_allowed(YYLTYPE *locp)
+ {
+ return check_version(130, 300, locp, "bit-wise operations are forbidden");
+ }
+
+ void process_version_directive(YYLTYPE *locp, int version,
+ const char *ident);
+
struct gl_context *const ctx;
void *scanner;
exec_list translation_unit;
@@ -92,7 +154,6 @@ struct _mesa_glsl_parse_state {
bool es_shader;
unsigned language_version;
- const char *version_string;
enum _mesa_glsl_parser_targets target;
/**
@@ -133,6 +194,10 @@ struct _mesa_glsl_parse_state {
/* ARB_draw_buffers */
unsigned MaxDrawBuffers;
+
+ /* 3.00 ES */
+ int MinProgramTexelOffset;
+ int MaxProgramTexelOffset;
} Const;
/**
@@ -221,16 +286,6 @@ struct _mesa_glsl_parse_state {
unsigned num_builtins_to_link;
};
-typedef struct YYLTYPE {
- int first_line;
- int first_column;
- int last_line;
- int last_column;
- unsigned source;
-} YYLTYPE;
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-
# define YYLLOC_DEFAULT(Current, Rhs, N) \
do { \
if (N) \
diff --git a/mesalib/src/glsl/glsl_symbol_table.cpp b/mesalib/src/glsl/glsl_symbol_table.cpp
index 27a669b65..247aff55c 100644
--- a/mesalib/src/glsl/glsl_symbol_table.cpp
+++ b/mesalib/src/glsl/glsl_symbol_table.cpp
@@ -56,7 +56,7 @@ public:
glsl_symbol_table::glsl_symbol_table()
{
- this->language_version = 120;
+ this->separate_function_namespace = false;
this->table = _mesa_symbol_table_ctor();
this->mem_ctx = ralloc_context(NULL);
}
@@ -84,7 +84,7 @@ bool glsl_symbol_table::name_declared_this_scope(const char *name)
bool glsl_symbol_table::add_variable(ir_variable *v)
{
- if (this->language_version == 110) {
+ if (this->separate_function_namespace) {
/* In 1.10, functions and variables have separate namespaces. */
symbol_table_entry *existing = get_entry(v->name);
if (name_declared_this_scope(v->name)) {
@@ -124,7 +124,7 @@ bool glsl_symbol_table::add_type(const char *name, const glsl_type *t)
bool glsl_symbol_table::add_function(ir_function *f)
{
- if (this->language_version == 110 && name_declared_this_scope(f->name)) {
+ if (this->separate_function_namespace && name_declared_this_scope(f->name)) {
/* In 1.10, functions and variables have separate namespaces. */
symbol_table_entry *existing = get_entry(f->name);
if ((existing->f == NULL) && (existing->t == NULL)) {
diff --git a/mesalib/src/glsl/glsl_symbol_table.h b/mesalib/src/glsl/glsl_symbol_table.h
index 1afeddb33..55baebf10 100644
--- a/mesalib/src/glsl/glsl_symbol_table.h
+++ b/mesalib/src/glsl/glsl_symbol_table.h
@@ -82,7 +82,8 @@ public:
glsl_symbol_table();
~glsl_symbol_table();
- unsigned int language_version;
+ /* In 1.10, functions and variables have separate namespaces. */
+ bool separate_function_namespace;
void push_scope();
void pop_scope();
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index 3940a12a5..71b185027 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -102,11 +102,16 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
static void
add_types_to_symbol_table(glsl_symbol_table *symtab,
const struct glsl_type *types,
- unsigned num_types, bool warn)
+ unsigned num_types, bool warn,
+ bool skip_1d)
{
(void) warn;
for (unsigned i = 0; i < num_types; i++) {
+ if (skip_1d && types[i].base_type == GLSL_TYPE_SAMPLER
+ && types[i].sampler_dimensionality == GLSL_SAMPLER_DIM_1D)
+ continue;
+
symtab->add_type(types[i].name, & types[i]);
}
}
@@ -158,49 +163,68 @@ glsl_type::sampler_index() const
void
glsl_type::generate_100ES_types(glsl_symbol_table *symtab)
{
+ bool skip_1d = false;
add_types_to_symbol_table(symtab, builtin_core_types,
Elements(builtin_core_types),
- false);
+ false, skip_1d);
add_types_to_symbol_table(symtab, builtin_structure_types,
Elements(builtin_structure_types),
- false);
- add_types_to_symbol_table(symtab, void_type, 1, false);
+ false, skip_1d);
+ add_types_to_symbol_table(symtab, void_type, 1, false, skip_1d);
+}
+
+void
+glsl_type::generate_300ES_types(glsl_symbol_table *symtab)
+{
+ /* GLSL 3.00 ES types are the same as GLSL 1.30 types, except that 1D
+ * samplers are skipped, and samplerCubeShadow is added.
+ */
+ bool add_deprecated = false;
+ bool skip_1d = true;
+
+ generate_130_types(symtab, add_deprecated, skip_1d);
+
+ add_types_to_symbol_table(symtab, &_samplerCubeShadow_type, 1, false,
+ skip_1d);
}
void
-glsl_type::generate_110_types(glsl_symbol_table *symtab, bool add_deprecated)
+glsl_type::generate_110_types(glsl_symbol_table *symtab, bool add_deprecated,
+ bool skip_1d)
{
generate_100ES_types(symtab);
add_types_to_symbol_table(symtab, builtin_110_types,
Elements(builtin_110_types),
- false);
- add_types_to_symbol_table(symtab, &_sampler3D_type, 1, false);
+ false, skip_1d);
+ add_types_to_symbol_table(symtab, &_sampler3D_type, 1, false, skip_1d);
if (add_deprecated) {
add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
Elements(builtin_110_deprecated_structure_types),
- false);
+ false, skip_1d);
}
}
void
-glsl_type::generate_120_types(glsl_symbol_table *symtab, bool add_deprecated)
+glsl_type::generate_120_types(glsl_symbol_table *symtab, bool add_deprecated,
+ bool skip_1d)
{
- generate_110_types(symtab, add_deprecated);
+ generate_110_types(symtab, add_deprecated, skip_1d);
add_types_to_symbol_table(symtab, builtin_120_types,
- Elements(builtin_120_types), false);
+ Elements(builtin_120_types), false, skip_1d);
}
void
-glsl_type::generate_130_types(glsl_symbol_table *symtab, bool add_deprecated)
+glsl_type::generate_130_types(glsl_symbol_table *symtab, bool add_deprecated,
+ bool skip_1d)
{
- generate_120_types(symtab, add_deprecated);
+ generate_120_types(symtab, add_deprecated, skip_1d);
add_types_to_symbol_table(symtab, builtin_130_types,
- Elements(builtin_130_types), false);
+ Elements(builtin_130_types), false, skip_1d);
generate_EXT_texture_array_types(symtab, false);
}
@@ -208,14 +232,16 @@ glsl_type::generate_130_types(glsl_symbol_table *symtab, bool add_deprecated)
void
glsl_type::generate_140_types(glsl_symbol_table *symtab)
{
- generate_130_types(symtab, false);
+ bool skip_1d = false;
+
+ generate_130_types(symtab, false, skip_1d);
add_types_to_symbol_table(symtab, builtin_140_types,
- Elements(builtin_140_types), false);
+ Elements(builtin_140_types), false, skip_1d);
add_types_to_symbol_table(symtab, builtin_EXT_texture_buffer_object_types,
Elements(builtin_EXT_texture_buffer_object_types),
- false);
+ false, skip_1d);
}
@@ -223,9 +249,11 @@ void
glsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab,
bool warn)
{
+ bool skip_1d = false;
+
add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types,
Elements(builtin_ARB_texture_rectangle_types),
- warn);
+ warn, skip_1d);
}
@@ -233,16 +261,20 @@ void
glsl_type::generate_EXT_texture_array_types(glsl_symbol_table *symtab,
bool warn)
{
+ bool skip_1d = false;
+
add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types,
Elements(builtin_EXT_texture_array_types),
- warn);
+ warn, skip_1d);
}
void
glsl_type::generate_OES_texture_3D_types(glsl_symbol_table *symtab, bool warn)
{
- add_types_to_symbol_table(symtab, &_sampler3D_type, 1, warn);
+ bool skip_1d = false;
+
+ add_types_to_symbol_table(symtab, &_sampler3D_type, 1, warn, skip_1d);
}
@@ -250,56 +282,74 @@ void
glsl_type::generate_OES_EGL_image_external_types(glsl_symbol_table *symtab,
bool warn)
{
+ bool skip_1d = false;
+
add_types_to_symbol_table(symtab, builtin_OES_EGL_image_external_types,
Elements(builtin_OES_EGL_image_external_types),
- warn);
+ warn, skip_1d);
}
void
glsl_type::generate_ARB_texture_cube_map_array_types(glsl_symbol_table *symtab,
bool warn)
{
+ bool skip_1d = false;
+
add_types_to_symbol_table(symtab, builtin_ARB_texture_cube_map_array_types,
Elements(builtin_ARB_texture_cube_map_array_types),
- warn);
+ warn, skip_1d);
}
void
_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
{
- switch (state->language_version) {
- case 100:
- assert(state->es_shader);
- glsl_type::generate_100ES_types(state->symbols);
- break;
- case 110:
- glsl_type::generate_110_types(state->symbols, true);
- break;
- case 120:
- glsl_type::generate_120_types(state->symbols, true);
- break;
- case 130:
- glsl_type::generate_130_types(state->symbols, true);
- break;
- case 140:
- glsl_type::generate_140_types(state->symbols);
- break;
- default:
- /* error */
- break;
+ if (state->es_shader) {
+ switch (state->language_version) {
+ case 100:
+ assert(state->es_shader);
+ glsl_type::generate_100ES_types(state->symbols);
+ break;
+ case 300:
+ glsl_type::generate_300ES_types(state->symbols);
+ break;
+ default:
+ assert(!"Unexpected language version");
+ break;
+ }
+ } else {
+ bool skip_1d = false;
+ switch (state->language_version) {
+ case 110:
+ glsl_type::generate_110_types(state->symbols, true, skip_1d);
+ break;
+ case 120:
+ glsl_type::generate_120_types(state->symbols, true, skip_1d);
+ break;
+ case 130:
+ glsl_type::generate_130_types(state->symbols, true, skip_1d);
+ break;
+ case 140:
+ glsl_type::generate_140_types(state->symbols);
+ break;
+ default:
+ assert(!"Unexpected language version");
+ break;
+ }
}
if (state->ARB_texture_rectangle_enable ||
- state->language_version >= 140) {
+ state->is_version(140, 0)) {
glsl_type::generate_ARB_texture_rectangle_types(state->symbols,
state->ARB_texture_rectangle_warn);
}
- if (state->OES_texture_3D_enable && state->language_version == 100) {
+ if (state->OES_texture_3D_enable
+ && state->is_version(0, 100)) {
glsl_type::generate_OES_texture_3D_types(state->symbols,
state->OES_texture_3D_warn);
}
- if (state->EXT_texture_array_enable && state->language_version < 130) {
+ if (state->EXT_texture_array_enable
+ && !state->is_version(130, 0)) {
// These are already included in 130; don't create twice.
glsl_type::generate_EXT_texture_array_types(state->symbols,
state->EXT_texture_array_warn);
diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h
index cf954a256..d6f5c105e 100644
--- a/mesalib/src/glsl/glsl_types.h
+++ b/mesalib/src/glsl/glsl_types.h
@@ -510,6 +510,7 @@ private:
static const glsl_type _error_type;
static const glsl_type _void_type;
static const glsl_type _sampler3D_type;
+ static const glsl_type _samplerCubeShadow_type;
static const glsl_type builtin_core_types[];
static const glsl_type builtin_structure_types[];
static const glsl_type builtin_110_deprecated_structure_types[];
@@ -534,9 +535,13 @@ private:
*/
/*@{*/
static void generate_100ES_types(glsl_symbol_table *);
- static void generate_110_types(glsl_symbol_table *, bool add_deprecated);
- static void generate_120_types(glsl_symbol_table *, bool add_deprecated);
- static void generate_130_types(glsl_symbol_table *, bool add_deprecated);
+ static void generate_300ES_types(glsl_symbol_table *);
+ static void generate_110_types(glsl_symbol_table *, bool add_deprecated,
+ bool skip_1d);
+ static void generate_120_types(glsl_symbol_table *, bool add_deprecated,
+ bool skip_1d);
+ static void generate_130_types(glsl_symbol_table *, bool add_deprecated,
+ bool skip_1d);
static void generate_140_types(glsl_symbol_table *);
static void generate_ARB_texture_rectangle_types(glsl_symbol_table *, bool);
static void generate_EXT_texture_array_types(glsl_symbol_table *, bool);
diff --git a/mesalib/src/glsl/hir_field_selection.cpp b/mesalib/src/glsl/hir_field_selection.cpp
index 260b415a8..ac416d5da 100644
--- a/mesalib/src/glsl/hir_field_selection.cpp
+++ b/mesalib/src/glsl/hir_field_selection.cpp
@@ -72,8 +72,7 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
}
} else if (expr->subexpressions[1] != NULL) {
/* Handle "method calls" in GLSL 1.20 - namely, array.length() */
- if (state->language_version < 120)
- _mesa_glsl_error(&loc, state, "Methods not supported in GLSL 1.10.");
+ state->check_version(120, 300, &loc, "Methods not supported");
ast_expression *call = expr->subexpressions[1];
assert(call->oper == ast_function_call);
diff --git a/mesalib/src/glsl/ir_variable_refcount.cpp b/mesalib/src/glsl/ir_variable_refcount.cpp
index 1633a7357..923eb1a82 100644
--- a/mesalib/src/glsl/ir_variable_refcount.cpp
+++ b/mesalib/src/glsl/ir_variable_refcount.cpp
@@ -33,7 +33,26 @@
#include "ir_visitor.h"
#include "ir_variable_refcount.h"
#include "glsl_types.h"
+#include "main/hash_table.h"
+ir_variable_refcount_visitor::ir_variable_refcount_visitor()
+{
+ this->mem_ctx = ralloc_context(NULL);
+ this->ht = _mesa_hash_table_create(NULL, _mesa_key_pointer_equal);
+}
+
+static void
+free_entry(struct hash_entry *entry)
+{
+ ir_variable_refcount_entry *ivre = (ir_variable_refcount_entry *) entry->data;
+ delete ivre;
+}
+
+ir_variable_refcount_visitor::~ir_variable_refcount_visitor()
+{
+ ralloc_free(this->mem_ctx);
+ _mesa_hash_table_destroy(this->ht, free_entry);
+}
// constructor
ir_variable_refcount_entry::ir_variable_refcount_entry(ir_variable *var)
@@ -50,15 +69,17 @@ ir_variable_refcount_entry *
ir_variable_refcount_visitor::get_variable_entry(ir_variable *var)
{
assert(var);
- foreach_iter(exec_list_iterator, iter, this->variable_list) {
- ir_variable_refcount_entry *entry = (ir_variable_refcount_entry *)iter.get();
- if (entry->var == var)
- return entry;
- }
- ir_variable_refcount_entry *entry = new(mem_ctx) ir_variable_refcount_entry(var);
+ struct hash_entry *e = _mesa_hash_table_search(this->ht,
+ _mesa_hash_pointer(var),
+ var);
+ if (e)
+ return (ir_variable_refcount_entry *)e->data;
+
+ ir_variable_refcount_entry *entry = new ir_variable_refcount_entry(var);
assert(entry->referenced_count == 0);
- this->variable_list.push_tail(entry);
+ _mesa_hash_table_insert(this->ht, _mesa_hash_pointer(var), var, entry);
+
return entry;
}
diff --git a/mesalib/src/glsl/ir_variable_refcount.h b/mesalib/src/glsl/ir_variable_refcount.h
index 51a4945a1..c15e8110d 100644
--- a/mesalib/src/glsl/ir_variable_refcount.h
+++ b/mesalib/src/glsl/ir_variable_refcount.h
@@ -33,7 +33,7 @@
#include "ir_visitor.h"
#include "glsl_types.h"
-class ir_variable_refcount_entry : public exec_node
+class ir_variable_refcount_entry
{
public:
ir_variable_refcount_entry(ir_variable *var);
@@ -52,16 +52,8 @@ public:
class ir_variable_refcount_visitor : public ir_hierarchical_visitor {
public:
- ir_variable_refcount_visitor(void)
- {
- this->mem_ctx = ralloc_context(NULL);
- this->variable_list.make_empty();
- }
-
- ~ir_variable_refcount_visitor(void)
- {
- ralloc_free(this->mem_ctx);
- }
+ ir_variable_refcount_visitor(void);
+ ~ir_variable_refcount_visitor(void);
virtual ir_visitor_status visit(ir_variable *);
virtual ir_visitor_status visit(ir_dereference_variable *);
@@ -71,8 +63,7 @@ public:
ir_variable_refcount_entry *get_variable_entry(ir_variable *var);
- /* List of ir_variable_refcount_entry */
- exec_list variable_list;
+ struct hash_table *ht;
void *mem_ctx;
};
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 3b2ab962b..29fc5d841 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -289,8 +289,11 @@ validate_vertex_shader_executable(struct gl_shader_program *prog,
* operations, if present, that operate on primitives after
* vertex processing has occurred. Its value is undefined if
* the vertex shader executable does not write gl_Position."
+ *
+ * GLSL ES 3.00 is similar to GLSL 1.40--failing to write to gl_Position is
+ * not an error.
*/
- if (prog->Version < 140) {
+ if (prog->Version < (prog->IsES ? 300 : 140)) {
find_assignment_visitor find("gl_Position");
find.run(shader->ir);
if (!find.variable_found()) {
@@ -301,12 +304,15 @@ validate_vertex_shader_executable(struct gl_shader_program *prog,
prog->Vert.ClipDistanceArraySize = 0;
- if (prog->Version >= 130) {
+ if (!prog->IsES && prog->Version >= 130) {
/* From section 7.1 (Vertex Shader Special Variables) of the
* GLSL 1.30 spec:
*
* "It is an error for a shader to statically write both
* gl_ClipVertex and gl_ClipDistance."
+ *
+ * This does not apply to GLSL ES shaders, since GLSL ES defines neither
+ * gl_ClipVertex nor gl_ClipDistance.
*/
find_assignment_visitor clip_vertex("gl_ClipVertex");
find_assignment_visitor clip_distance("gl_ClipDistance");
@@ -2144,7 +2150,7 @@ assign_varying_locations(struct gl_context *ctx,
}
}
- if (ctx->API == API_OPENGLES2 || prog->Version == 100) {
+ if (ctx->API == API_OPENGLES2 || prog->IsES) {
if (varying_vectors > ctx->Const.MaxVarying) {
if (ctx->Const.GLSLSkipStrictMaxVaryingLimitCheck) {
linker_warning(prog, "shader uses too many varying vectors "
@@ -2421,10 +2427,18 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
unsigned min_version = UINT_MAX;
unsigned max_version = 0;
+ const bool is_es_prog =
+ (prog->NumShaders > 0 && prog->Shaders[0]->IsES) ? true : false;
for (unsigned i = 0; i < prog->NumShaders; i++) {
min_version = MIN2(min_version, prog->Shaders[i]->Version);
max_version = MAX2(max_version, prog->Shaders[i]->Version);
+ if (prog->Shaders[i]->IsES != is_es_prog) {
+ linker_error(prog, "all shaders must use same shading "
+ "language version\n");
+ goto done;
+ }
+
switch (prog->Shaders[i]->Type) {
case GL_VERTEX_SHADER:
vert_shader_list[num_vert_shaders] = prog->Shaders[i];
@@ -2444,10 +2458,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
/* Previous to GLSL version 1.30, different compilation units could mix and
* match shading language versions. With GLSL 1.30 and later, the versions
* of all shaders must match.
+ *
+ * GLSL ES has never allowed mixing of shading language versions.
*/
- assert(min_version >= 100);
- assert(max_version <= 140);
- if ((max_version >= 130 || min_version == 100)
+ if ((is_es_prog || max_version >= 130)
&& min_version != max_version) {
linker_error(prog, "all shaders must use same shading "
"language version\n");
@@ -2455,6 +2469,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
}
prog->Version = max_version;
+ prog->IsES = is_es_prog;
for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) {
if (prog->_LinkedShaders[i] != NULL)
@@ -2528,8 +2543,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
/* Implement the GLSL 1.30+ rule for discard vs infinite loops Do
* it before optimization because we want most of the checks to get
* dropped thanks to constant propagation.
+ *
+ * This rule also applies to GLSL ES 3.00.
*/
- if (max_version >= 130) {
+ if (max_version >= (is_es_prog ? 300 : 130)) {
struct gl_shader *sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
if (sh) {
lower_discard_flow(sh->ir);
@@ -2673,11 +2690,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
goto done;
/* OpenGL ES requires that a vertex shader and a fragment shader both be
- * present in a linked program. By checking for use of shading language
- * version 1.00, we also catch the GL_ARB_ES2_compatibility case.
+ * present in a linked program. By checking prog->IsES, we also
+ * catch the GL_ARB_ES2_compatibility case.
*/
if (!prog->InternalSeparateShader &&
- (ctx->API == API_OPENGLES2 || prog->Version == 100)) {
+ (ctx->API == API_OPENGLES2 || prog->IsES)) {
if (prog->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
linker_error(prog, "program lacks a vertex shader\n");
} else if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) {
diff --git a/mesalib/src/glsl/lower_output_reads.cpp b/mesalib/src/glsl/lower_output_reads.cpp
index 90d71b04a..a6192a517 100644
--- a/mesalib/src/glsl/lower_output_reads.cpp
+++ b/mesalib/src/glsl/lower_output_reads.cpp
@@ -97,6 +97,7 @@ output_read_remover::visit(ir_dereference_variable *ir)
temp = new(var_ctx) ir_variable(ir->var->type, ir->var->name,
ir_var_temporary);
hash_table_insert(replacements, temp, ir->var);
+ ir->var->insert_after(temp);
}
/* Update the dereference to use the temporary */
diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp
index af97c545b..d21b8cd2d 100644
--- a/mesalib/src/glsl/main.cpp
+++ b/mesalib/src/glsl/main.cpp
@@ -59,6 +59,7 @@ initialize_context(struct gl_context *ctx, gl_api api)
* everything in order to compile the built-in functions.
*/
ctx->Const.GLSLVersion = 140;
+ ctx->Extensions.ARB_ES3_compatibility = true;
ctx->Const.MaxClipPlanes = 8;
ctx->Const.MaxDrawBuffers = 2;
@@ -201,6 +202,7 @@ compile_shader(struct gl_context *ctx, struct gl_shader *shader)
shader->symbols = state->symbols;
shader->CompileStatus = !state->error;
shader->Version = state->language_version;
+ shader->IsES = state->es_shader;
memcpy(shader->builtins_to_link, state->builtins_to_link,
sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
shader->num_builtins_to_link = state->num_builtins_to_link;
diff --git a/mesalib/src/glsl/opt_dead_code.cpp b/mesalib/src/glsl/opt_dead_code.cpp
index de8475f95..47247e20d 100644
--- a/mesalib/src/glsl/opt_dead_code.cpp
+++ b/mesalib/src/glsl/opt_dead_code.cpp
@@ -31,6 +31,7 @@
#include "ir_visitor.h"
#include "ir_variable_refcount.h"
#include "glsl_types.h"
+#include "main/hash_table.h"
static bool debug = false;
@@ -49,8 +50,9 @@ do_dead_code(exec_list *instructions, bool uniform_locations_assigned)
v.run(instructions);
- foreach_iter(exec_list_iterator, iter, v.variable_list) {
- ir_variable_refcount_entry *entry = (ir_variable_refcount_entry *)iter.get();
+ struct hash_entry *e;
+ hash_table_foreach(v.ht, e) {
+ ir_variable_refcount_entry *entry = (ir_variable_refcount_entry *)e->data;
/* Since each assignment is a reference, the refereneced count must be
* greater than or equal to the assignment count. If they are equal,
diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp
index 120ee9534..33d3804c6 100644
--- a/mesalib/src/glsl/standalone_scaffolding.cpp
+++ b/mesalib/src/glsl/standalone_scaffolding.cpp
@@ -73,6 +73,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api)
ctx->Extensions.dummy_false = false;
ctx->Extensions.dummy_true = true;
ctx->Extensions.ARB_ES2_compatibility = true;
+ ctx->Extensions.ARB_ES3_compatibility = false;
ctx->Extensions.ARB_draw_instanced = true;
ctx->Extensions.ARB_fragment_coord_conventions = true;
ctx->Extensions.EXT_texture_array = true;
diff --git a/mesalib/src/mesa/Android.libmesa_glsl_utils.mk b/mesalib/src/mesa/Android.libmesa_glsl_utils.mk
index 480275795..9beeda57f 100644
--- a/mesalib/src/mesa/Android.libmesa_glsl_utils.mk
+++ b/mesalib/src/mesa/Android.libmesa_glsl_utils.mk
@@ -36,7 +36,8 @@ include $(CLEAR_VARS)
LOCAL_MODULE := libmesa_glsl_utils
LOCAL_SRC_FILES := \
- program/hash_table.c \
+ main/hash_table.c \
+ program/prog_hash_table.c \
program/symbol_table.c
include $(MESA_COMMON_MK)
@@ -52,7 +53,8 @@ LOCAL_MODULE := libmesa_glsl_utils
LOCAL_IS_HOST_MODULE := true
LOCAL_SRC_FILES := \
- program/hash_table.c \
+ main/hash_table.c \
+ program/prog_hash_table.c \
program/symbol_table.c
include $(MESA_COMMON_MK)
diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript
index be1ed5f60..a2492f771 100644
--- a/mesalib/src/mesa/SConscript
+++ b/mesalib/src/mesa/SConscript
@@ -107,6 +107,7 @@ main_sources = [
'main/renderbuffer.c',
'main/samplerobj.c',
'main/scissor.c',
+ 'main/set.c',
'main/shaderapi.c',
'main/shaderobj.c',
'main/shader_query.cpp',
@@ -293,7 +294,7 @@ env.Append(CPPPATH = [Dir('.').abspath])
program_sources = [
'program/arbprogparse.c',
- 'program/hash_table.c',
+ 'program/prog_hash_table.c',
'program/ir_to_mesa.cpp',
'program/program.c',
'program/program_parse_extra.c',
diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c
index d5e8af3c0..ac036eaac 100644
--- a/mesalib/src/mesa/drivers/common/meta.c
+++ b/mesalib/src/mesa/drivers/common/meta.c
@@ -133,6 +133,7 @@ struct save_state
struct gl_vertex_program *VertexProgram;
GLboolean FragmentProgramEnabled;
struct gl_fragment_program *FragmentProgram;
+ GLboolean ATIFragmentShaderEnabled;
struct gl_shader_program *VertexShader;
struct gl_shader_program *GeometryShader;
struct gl_shader_program *FragmentShader;
@@ -594,6 +595,11 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
_mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE);
}
+ if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ATI_fragment_shader) {
+ save->ATIFragmentShaderEnabled = ctx->ATIFragmentShader.Enabled;
+ _mesa_set_enable(ctx, GL_FRAGMENT_SHADER_ATI, GL_FALSE);
+ }
+
if (ctx->Extensions.ARB_shader_objects) {
_mesa_reference_shader_program(ctx, &save->VertexShader,
ctx->Shader.CurrentVertexProgram);
@@ -914,6 +920,11 @@ _mesa_meta_end(struct gl_context *ctx)
_mesa_reference_fragprog(ctx, &save->FragmentProgram, NULL);
}
+ if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ATI_fragment_shader) {
+ _mesa_set_enable(ctx, GL_FRAGMENT_SHADER_ATI,
+ save->ATIFragmentShaderEnabled);
+ }
+
if (ctx->Extensions.ARB_vertex_shader)
_mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader);
@@ -1844,23 +1855,8 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
"{\n"
" gl_FragColor = color;\n"
"}\n";
- const char *vs_int_source =
- "#version 130\n"
- "in vec4 position;\n"
- "void main()\n"
- "{\n"
- " gl_Position = position;\n"
- "}\n";
- const char *fs_int_source =
- "#version 130\n"
- "uniform ivec4 color;\n"
- "out ivec4 out_color;\n"
- "\n"
- "void main()\n"
- "{\n"
- " out_color = color;\n"
- "}\n";
GLuint vs, fs;
+ bool has_integer_textures;
if (clear->ArrayObj != 0)
return;
@@ -1896,9 +1892,35 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg,
"color");
- if (_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130) {
+ has_integer_textures = _mesa_is_gles3(ctx) ||
+ (_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130);
+
+ if (has_integer_textures) {
+ void *shader_source_mem_ctx = ralloc_context(NULL);
+ const char *vs_int_source =
+ ralloc_asprintf(shader_source_mem_ctx,
+ "#version %s\n"
+ "in vec4 position;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = position;\n"
+ "}\n",
+ _mesa_is_desktop_gl(ctx) ? "130" : "300 es");
+ const char *fs_int_source =
+ ralloc_asprintf(shader_source_mem_ctx,
+ "#version %s\n"
+ "uniform ivec4 color;\n"
+ "out ivec4 out_color;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " out_color = color;\n"
+ "}\n",
+ _mesa_is_desktop_gl(ctx) ? "130" : "300 es");
+
vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_int_source);
fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_int_source);
+ ralloc_free(shader_source_mem_ctx);
clear->IntegerShaderProg = _mesa_CreateProgramObjectARB();
_mesa_AttachShader(clear->IntegerShaderProg, fs);
@@ -3101,18 +3123,19 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
sampler->func, sampler->texcoords);
}
else {
- vs_source =
- "#version 130\n"
- "in vec2 position;\n"
- "in vec3 textureCoords;\n"
- "out vec3 texCoords;\n"
- "void main()\n"
- "{\n"
- " texCoords = textureCoords;\n"
- " gl_Position = vec4(position, 0.0, 1.0);\n"
- "}\n";
+ vs_source = ralloc_asprintf(mem_ctx,
+ "#version %s\n"
+ "in vec2 position;\n"
+ "in vec3 textureCoords;\n"
+ "out vec3 texCoords;\n"
+ "void main()\n"
+ "{\n"
+ " texCoords = textureCoords;\n"
+ " gl_Position = vec4(position, 0.0, 1.0);\n"
+ "}\n",
+ _mesa_is_desktop_gl(ctx) ? "130" : "300 es");
fs_source = ralloc_asprintf(mem_ctx,
- "#version 130\n"
+ "#version %s\n"
"uniform %s texSampler;\n"
"in vec3 texCoords;\n"
"out vec4 out_color;\n"
@@ -3121,6 +3144,7 @@ setup_glsl_generate_mipmap(struct gl_context *ctx,
"{\n"
" out_color = texture(texSampler, %s);\n"
"}\n",
+ _mesa_is_desktop_gl(ctx) ? "130" : "300 es",
sampler->type,
sampler->texcoords);
}
diff --git a/mesalib/src/mesa/drivers/dri/common/drisw_util.c b/mesalib/src/mesa/drivers/dri/common/drisw_util.c
index e22ae1b84..33339880b 100644
--- a/mesalib/src/mesa/drivers/dri/common/drisw_util.c
+++ b/mesalib/src/mesa/drivers/dri/common/drisw_util.c
@@ -127,7 +127,10 @@ driCreateContextAttribs(__DRIscreen *screen, int api,
mesa_api = API_OPENGLES2;
break;
case __DRI_API_OPENGL_CORE:
+ mesa_api = API_OPENGL_CORE;
+ break;
default:
+ *error = __DRI_CTX_ERROR_BAD_API;
return NULL;
}
@@ -150,6 +153,19 @@ driCreateContextAttribs(__DRIscreen *screen, int api,
}
}
+ /* Mesa does not support the GL_ARB_compatibilty extension or the
+ * compatibility profile. This means that we treat a API_OPENGL_COMPAT 3.1 as
+ * API_OPENGL_CORE and reject API_OPENGL_COMPAT 3.2+.
+ */
+ if (mesa_api == API_OPENGL_COMPAT && major_version == 3 && minor_version == 1)
+ mesa_api = API_OPENGL_CORE;
+
+ if (mesa_api == API_OPENGL_COMPAT
+ && ((major_version > 3)
+ || (major_version == 3 && minor_version >= 2))) {
+ *error = __DRI_CTX_ERROR_BAD_API;
+ return NULL;
+ }
/* There are no forward-compatible contexts before OpenGL 3.0. The
* GLX_ARB_create_context spec says:
*
diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c
index dbcd0e6e6..ce873ecd7 100644
--- a/mesalib/src/mesa/main/bufferobj.c
+++ b/mesalib/src/mesa/main/bufferobj.c
@@ -2160,17 +2160,19 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
return;
}
- if (size <= 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)",
- (int) size);
- return;
- }
+ if (buffer != 0) {
+ if (size <= 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)",
+ (int) size);
+ return;
+ }
- if (offset + size > bufObj->Size) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glBindBufferRange(offset + size %d > buffer size %d)",
- (int) (offset + size), (int) (bufObj->Size));
- return;
+ if (offset + size > bufObj->Size) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glBindBufferRange(offset + size %d > buffer size %d)",
+ (int) (offset + size), (int) (bufObj->Size));
+ return;
+ }
}
switch (target) {
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index 150d41e04..11cbea2b4 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -80,6 +80,7 @@ struct extension {
static const struct extension extension_table[] = {
/* ARB Extensions */
{ "GL_ARB_ES2_compatibility", o(ARB_ES2_compatibility), GL, 2009 },
+ { "GL_ARB_ES3_compatibility", o(ARB_ES3_compatibility), GL, 2012 },
{ "GL_ARB_base_instance", o(ARB_base_instance), GL, 2011 },
{ "GL_ARB_blend_func_extended", o(ARB_blend_func_extended), GL, 2009 },
{ "GL_ARB_color_buffer_float", o(ARB_color_buffer_float), GL, 2004 },
diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp
index 3a80ab7f3..02b4707f0 100644
--- a/mesalib/src/mesa/main/ff_fragment_shader.cpp
+++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp
@@ -1309,6 +1309,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key)
p.shader_program->InternalSeparateShader = GL_TRUE;
state->language_version = 130;
+ state->es_shader = false;
if (ctx->Extensions.OES_EGL_image_external)
state->OES_EGL_image_external_enable = true;
_mesa_glsl_initialize_types(state);
diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c
index 04fd1d698..d34a27b82 100644
--- a/mesalib/src/mesa/main/format_unpack.c
+++ b/mesalib/src/mesa/main/format_unpack.c
@@ -57,8 +57,8 @@ struct z32f_x24s8
* linear RGB value in [0, 1].
* Implemented with a 256-entry lookup table.
*/
-static inline GLfloat
-nonlinear_to_linear(GLubyte cs8)
+GLfloat
+_mesa_nonlinear_to_linear(GLubyte cs8)
{
static GLfloat table[256];
static GLboolean tableReady = GL_FALSE;
@@ -742,9 +742,9 @@ unpack_SRGB8(const void *src, GLfloat dst[][4], GLuint n)
const GLubyte *s = (const GLubyte *) src;
GLuint i;
for (i = 0; i < n; i++) {
- dst[i][RCOMP] = nonlinear_to_linear(s[i*3+2]);
- dst[i][GCOMP] = nonlinear_to_linear(s[i*3+1]);
- dst[i][BCOMP] = nonlinear_to_linear(s[i*3+0]);
+ dst[i][RCOMP] = _mesa_nonlinear_to_linear(s[i*3+2]);
+ dst[i][GCOMP] = _mesa_nonlinear_to_linear(s[i*3+1]);
+ dst[i][BCOMP] = _mesa_nonlinear_to_linear(s[i*3+0]);
dst[i][ACOMP] = 1.0F;
}
}
@@ -755,9 +755,9 @@ unpack_SRGBA8(const void *src, GLfloat dst[][4], GLuint n)
const GLuint *s = ((const GLuint *) src);
GLuint i;
for (i = 0; i < n; i++) {
- dst[i][RCOMP] = nonlinear_to_linear( (s[i] >> 24) );
- dst[i][GCOMP] = nonlinear_to_linear( (s[i] >> 16) & 0xff );
- dst[i][BCOMP] = nonlinear_to_linear( (s[i] >> 8) & 0xff );
+ dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 24) );
+ dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff );
+ dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 8) & 0xff );
dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); /* linear! */
}
}
@@ -768,9 +768,9 @@ unpack_SARGB8(const void *src, GLfloat dst[][4], GLuint n)
const GLuint *s = ((const GLuint *) src);
GLuint i;
for (i = 0; i < n; i++) {
- dst[i][RCOMP] = nonlinear_to_linear( (s[i] >> 16) & 0xff );
- dst[i][GCOMP] = nonlinear_to_linear( (s[i] >> 8) & 0xff );
- dst[i][BCOMP] = nonlinear_to_linear( (s[i] ) & 0xff );
+ dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff );
+ dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 8) & 0xff );
+ dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i] ) & 0xff );
dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] >> 24 ); /* linear! */
}
}
@@ -783,7 +783,7 @@ unpack_SL8(const void *src, GLfloat dst[][4], GLuint n)
for (i = 0; i < n; i++) {
dst[i][RCOMP] =
dst[i][GCOMP] =
- dst[i][BCOMP] = nonlinear_to_linear(s[i]);
+ dst[i][BCOMP] = _mesa_nonlinear_to_linear(s[i]);
dst[i][ACOMP] = 1.0F;
}
}
@@ -796,7 +796,7 @@ unpack_SLA8(const void *src, GLfloat dst[][4], GLuint n)
for (i = 0; i < n; i++) {
dst[i][RCOMP] =
dst[i][GCOMP] =
- dst[i][BCOMP] = nonlinear_to_linear(s[i] & 0xff);
+ dst[i][BCOMP] = _mesa_nonlinear_to_linear(s[i] & 0xff);
dst[i][ACOMP] = UBYTE_TO_FLOAT(s[i] >> 8); /* linear! */
}
}
@@ -1337,6 +1337,68 @@ unpack_ETC1_RGB8(const void *src, GLfloat dst[][4], GLuint n)
}
static void
+unpack_ETC2_RGB8(const void *src, GLfloat dst[][4], GLuint n)
+{
+ /* XXX to do */
+}
+
+static void
+unpack_ETC2_SRGB8(const void *src, GLfloat dst[][4], GLuint n)
+{
+ /* XXX to do */
+}
+
+static void
+unpack_ETC2_RGBA8_EAC(const void *src, GLfloat dst[][4], GLuint n)
+{
+ /* XXX to do */
+}
+
+static void
+unpack_ETC2_SRGB8_ALPHA8_EAC(const void *src, GLfloat dst[][4], GLuint n)
+{
+ /* XXX to do */
+}
+
+static void
+unpack_ETC2_R11_EAC(const void *src, GLfloat dst[][4], GLuint n)
+{
+ /* XXX to do */
+}
+
+static void
+unpack_ETC2_RG11_EAC(const void *src, GLfloat dst[][4], GLuint n)
+{
+ /* XXX to do */
+}
+
+static void
+unpack_ETC2_SIGNED_R11_EAC(const void *src, GLfloat dst[][4], GLuint n)
+{
+ /* XXX to do */
+}
+
+static void
+unpack_ETC2_SIGNED_RG11_EAC(const void *src, GLfloat dst[][4], GLuint n)
+{
+ /* XXX to do */
+}
+
+static void
+unpack_ETC2_RGB8_PUNCHTHROUGH_ALPHA1(const void *src, GLfloat dst[][4],
+ GLuint n)
+{
+ /* XXX to do */
+}
+
+static void
+unpack_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1(const void *src, GLfloat dst[][4],
+ GLuint n)
+{
+ /* XXX to do */
+}
+
+static void
unpack_SIGNED_A8(const void *src, GLfloat dst[][4], GLuint n)
{
const GLbyte *s = ((const GLbyte *) src);
@@ -1585,7 +1647,18 @@ get_unpack_rgba_function(gl_format format)
table[MESA_FORMAT_SIGNED_LA_LATC2] = unpack_SIGNED_LA_LATC2;
table[MESA_FORMAT_ETC1_RGB8] = unpack_ETC1_RGB8;
-
+ table[MESA_FORMAT_ETC2_RGB8] = unpack_ETC2_RGB8;
+ table[MESA_FORMAT_ETC2_SRGB8] = unpack_ETC2_SRGB8;
+ table[MESA_FORMAT_ETC2_RGBA8_EAC] = unpack_ETC2_RGBA8_EAC;
+ table[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = unpack_ETC2_SRGB8_ALPHA8_EAC;
+ table[MESA_FORMAT_ETC2_R11_EAC] = unpack_ETC2_R11_EAC;
+ table[MESA_FORMAT_ETC2_RG11_EAC] = unpack_ETC2_RG11_EAC;
+ table[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = unpack_ETC2_SIGNED_R11_EAC;
+ table[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = unpack_ETC2_SIGNED_RG11_EAC;
+ table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] =
+ unpack_ETC2_RGB8_PUNCHTHROUGH_ALPHA1;
+ table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] =
+ unpack_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1;
table[MESA_FORMAT_SIGNED_A8] = unpack_SIGNED_A8;
table[MESA_FORMAT_SIGNED_L8] = unpack_SIGNED_L8;
table[MESA_FORMAT_SIGNED_AL88] = unpack_SIGNED_AL88;
diff --git a/mesalib/src/mesa/main/format_unpack.h b/mesalib/src/mesa/main/format_unpack.h
index aad800dd1..29c526319 100644
--- a/mesalib/src/mesa/main/format_unpack.h
+++ b/mesalib/src/mesa/main/format_unpack.h
@@ -24,6 +24,9 @@
#ifndef FORMAT_UNPACK_H
#define FORMAT_UNPACK_H
+extern GLfloat
+_mesa_nonlinear_to_linear(GLubyte cs8);
+
extern void
_mesa_unpack_rgba_row(gl_format format, GLuint n,
const void *src, GLfloat dst[][4]);
diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c
index df23af1dd..47a1d6802 100644
--- a/mesalib/src/mesa/main/formats.c
+++ b/mesalib/src/mesa/main/formats.c
@@ -1398,6 +1398,106 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] =
4, 4, 8 /* 8 bytes per 4x4 block */
},
+ {
+ MESA_FORMAT_ETC2_RGB8,
+ "MESA_FORMAT_ETC2_RGB8",
+ GL_RGB,
+ GL_UNSIGNED_NORMALIZED,
+ 8, 8, 8, 0,
+ 0, 0, 0, 0, 0,
+ 4, 4, 8 /* 8 bytes per 4x4 block */
+ },
+
+ {
+ MESA_FORMAT_ETC2_SRGB8,
+ "MESA_FORMAT_ETC2_SRGB8",
+ GL_RGB,
+ GL_UNSIGNED_NORMALIZED,
+ 8, 8, 8, 0,
+ 0, 0, 0, 0, 0,
+ 4, 4, 8 /* 8 bytes per 4x4 block */
+ },
+
+ {
+ MESA_FORMAT_ETC2_RGBA8_EAC,
+ "MESA_FORMAT_ETC2_RGBA8_EAC",
+ GL_RGBA,
+ GL_UNSIGNED_NORMALIZED,
+ 8, 8, 8, 8,
+ 0, 0, 0, 0, 0,
+ 4, 4, 16 /* 16 bytes per 4x4 block */
+ },
+
+ {
+ MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC,
+ "MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC",
+ GL_RGBA,
+ GL_UNSIGNED_NORMALIZED,
+ 8, 8, 8, 8,
+ 0, 0, 0, 0, 0,
+ 4, 4, 16 /* 16 bytes per 4x4 block */
+ },
+
+ {
+ MESA_FORMAT_ETC2_R11_EAC,
+ "MESA_FORMAT_ETC2_R11_EAC",
+ GL_RED,
+ GL_UNSIGNED_NORMALIZED,
+ 11, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 4, 4, 8 /* 8 bytes per 4x4 block */
+ },
+
+ {
+ MESA_FORMAT_ETC2_RG11_EAC,
+ "MESA_FORMAT_ETC2_RG11_EAC",
+ GL_RG,
+ GL_UNSIGNED_NORMALIZED,
+ 11, 11, 0, 0,
+ 0, 0, 0, 0, 0,
+ 4, 4, 16 /* 16 bytes per 4x4 block */
+ },
+
+ {
+ MESA_FORMAT_ETC2_SIGNED_R11_EAC,
+ "MESA_FORMAT_ETC2_SIGNED_R11_EAC",
+ GL_RED,
+ GL_SIGNED_NORMALIZED,
+ 11, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 4, 4, 8 /* 8 bytes per 4x4 block */
+ },
+
+ {
+ MESA_FORMAT_ETC2_SIGNED_RG11_EAC,
+ "MESA_FORMAT_ETC2_SIGNED_RG11_EAC",
+ GL_RG,
+ GL_SIGNED_NORMALIZED,
+ 11, 11, 0, 0,
+ 0, 0, 0, 0, 0,
+ 4, 4, 16 /* 16 bytes per 4x4 block */
+ },
+
+ {
+ MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1,
+ "MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1",
+ GL_RGBA,
+ GL_UNSIGNED_NORMALIZED,
+ 8, 8, 8, 1,
+ 0, 0, 0, 0, 0,
+ 4, 4, 8 /* 8 bytes per 4x4 block */
+ },
+
+ {
+ MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1,
+ "MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1",
+ GL_RGBA,
+ GL_UNSIGNED_NORMALIZED,
+ 8, 8, 8, 1,
+ 0, 0, 0, 0, 0,
+ 4, 4, 8 /* 8 bytes per 4x4 block */
+ },
+
/* Signed formats from EXT_texture_snorm that are not in GL3.1 */
{
MESA_FORMAT_SIGNED_A8,
@@ -1840,7 +1940,20 @@ _mesa_get_uncompressed_format(gl_format format)
case MESA_FORMAT_SIGNED_LA_LATC2:
return MESA_FORMAT_SIGNED_AL88;
case MESA_FORMAT_ETC1_RGB8:
+ case MESA_FORMAT_ETC2_RGB8:
+ case MESA_FORMAT_ETC2_SRGB8:
return MESA_FORMAT_RGB888;
+ case MESA_FORMAT_ETC2_RGBA8_EAC:
+ case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
+ case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
+ case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
+ return MESA_FORMAT_RGBA8888;
+ case MESA_FORMAT_ETC2_R11_EAC:
+ case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
+ return MESA_FORMAT_R16;
+ case MESA_FORMAT_ETC2_RG11_EAC:
+ case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
+ return MESA_FORMAT_RG1616;
default:
#ifdef DEBUG
assert(!_mesa_is_format_compressed(format));
@@ -2282,6 +2395,16 @@ _mesa_format_to_type_and_comps(gl_format format,
case MESA_FORMAT_LA_LATC2:
case MESA_FORMAT_SIGNED_LA_LATC2:
case MESA_FORMAT_ETC1_RGB8:
+ case MESA_FORMAT_ETC2_RGB8:
+ case MESA_FORMAT_ETC2_SRGB8:
+ case MESA_FORMAT_ETC2_RGBA8_EAC:
+ case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
+ case MESA_FORMAT_ETC2_R11_EAC:
+ case MESA_FORMAT_ETC2_RG11_EAC:
+ case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
+ case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
+ case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
+ case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
/* XXX generate error instead? */
*datatype = GL_UNSIGNED_BYTE;
*comps = 0;
@@ -2912,6 +3035,16 @@ _mesa_format_matches_format_and_type(gl_format gl_format,
return GL_FALSE;
case MESA_FORMAT_ETC1_RGB8:
+ case MESA_FORMAT_ETC2_RGB8:
+ case MESA_FORMAT_ETC2_SRGB8:
+ case MESA_FORMAT_ETC2_RGBA8_EAC:
+ case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
+ case MESA_FORMAT_ETC2_R11_EAC:
+ case MESA_FORMAT_ETC2_RG11_EAC:
+ case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
+ case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
+ case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
+ case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
return GL_FALSE;
case MESA_FORMAT_SIGNED_A8:
diff --git a/mesalib/src/mesa/main/formats.h b/mesalib/src/mesa/main/formats.h
index 1843eb6fc..050fce96c 100644
--- a/mesalib/src/mesa/main/formats.h
+++ b/mesalib/src/mesa/main/formats.h
@@ -259,6 +259,16 @@ typedef enum
/*@}*/
MESA_FORMAT_ETC1_RGB8,
+ MESA_FORMAT_ETC2_RGB8,
+ MESA_FORMAT_ETC2_SRGB8,
+ MESA_FORMAT_ETC2_RGBA8_EAC,
+ MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC,
+ MESA_FORMAT_ETC2_R11_EAC,
+ MESA_FORMAT_ETC2_RG11_EAC,
+ MESA_FORMAT_ETC2_SIGNED_R11_EAC,
+ MESA_FORMAT_ETC2_SIGNED_RG11_EAC,
+ MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1,
+ MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1,
MESA_FORMAT_SIGNED_A8, /* AAAA AAAA */
MESA_FORMAT_SIGNED_L8, /* LLLL LLLL */
diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c
index 69caef70b..fefa9c441 100644
--- a/mesalib/src/mesa/main/glformats.c
+++ b/mesalib/src/mesa/main/glformats.c
@@ -570,6 +570,16 @@ _mesa_is_color_format(GLenum format)
case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
case GL_ETC1_RGB8_OES:
+ case GL_COMPRESSED_RGB8_ETC2:
+ case GL_COMPRESSED_SRGB8_ETC2:
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ case GL_COMPRESSED_R11_EAC:
+ case GL_COMPRESSED_RG11_EAC:
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
/* generic integer formats */
case GL_RED_INTEGER_EXT:
case GL_GREEN_INTEGER_EXT:
@@ -829,6 +839,17 @@ _mesa_is_compressed_format(struct gl_context *ctx, GLenum format)
case GL_ETC1_RGB8_OES:
return _mesa_is_gles(ctx)
&& ctx->Extensions.OES_compressed_ETC1_RGB8_texture;
+ case GL_COMPRESSED_RGB8_ETC2:
+ case GL_COMPRESSED_SRGB8_ETC2:
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ case GL_COMPRESSED_R11_EAC:
+ case GL_COMPRESSED_RG11_EAC:
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ return _mesa_is_gles3(ctx);
case GL_PALETTE4_RGB8_OES:
case GL_PALETTE4_RGBA8_OES:
case GL_PALETTE4_R5_G6_B5_OES:
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 5bfae69c8..b353e7026 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -79,6 +79,8 @@ struct st_context;
struct gl_uniform_storage;
struct prog_instruction;
struct gl_program_parameter_list;
+struct set;
+struct set_entry;
/*@}*/
@@ -2184,6 +2186,7 @@ struct gl_shader
struct gl_sl_pragmas Pragmas;
unsigned Version; /**< GLSL version used for linking */
+ GLboolean IsES; /**< True if this shader uses GLSL ES */
/**
* \name Sampler tracking
@@ -2386,6 +2389,7 @@ struct gl_shader_program
GLchar *InfoLog;
unsigned Version; /**< GLSL version used for linking */
+ GLboolean IsES; /**< True if this program uses GLSL ES */
/**
* Per-stage shaders resulting from the first stage of linking.
@@ -2509,7 +2513,7 @@ struct gl_query_state
/** Sync object state */
struct gl_sync_object
{
- struct simple_node link;
+ struct set_entry *SetEntry;
GLenum Type; /**< GL_SYNC_FENCE */
GLuint Name; /**< Fence name */
GLint RefCount; /**< Reference count */
@@ -2576,7 +2580,7 @@ struct gl_shared_state
struct _mesa_HashTable *FrameBuffers;
/* GL_ARB_sync */
- struct simple_node SyncObjects;
+ struct set *SyncObjects;
/** GL_ARB_sampler_objects */
struct _mesa_HashTable *SamplerObjects;
@@ -2939,6 +2943,7 @@ struct gl_extensions
GLboolean dummy_false; /* Set false by _mesa_init_extensions(). */
GLboolean ANGLE_texture_compression_dxt;
GLboolean ARB_ES2_compatibility;
+ GLboolean ARB_ES3_compatibility;
GLboolean ARB_base_instance;
GLboolean ARB_blend_func_extended;
GLboolean ARB_color_buffer_float;
diff --git a/mesalib/src/mesa/main/set.c b/mesalib/src/mesa/main/set.c
new file mode 100644
index 000000000..736841fc9
--- /dev/null
+++ b/mesalib/src/mesa/main/set.c
@@ -0,0 +1,348 @@
+/*
+ * Copyright © 2009-2012 Intel Corporation
+ * Copyright © 1988-2004 Keith Packard and Bart Massey.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the authors
+ * or their institutions shall not be used in advertising or
+ * otherwise to promote the sale, use or other dealings in this
+ * Software without prior written authorization from the
+ * authors.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ * Keith Packard <keithp@keithp.com>
+ */
+
+#include <stdlib.h>
+
+#include "set.h"
+#include "ralloc.h"
+
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
+
+/*
+ * From Knuth -- a good choice for hash/rehash values is p, p-2 where
+ * p and p-2 are both prime. These tables are sized to have an extra 10%
+ * free to avoid exponential performance degradation as the hash table fills
+ */
+
+uint32_t deleted_key_value;
+const void *deleted_key = &deleted_key_value;
+
+static const struct {
+ uint32_t max_entries, size, rehash;
+} hash_sizes[] = {
+ { 2, 5, 3 },
+ { 4, 7, 5 },
+ { 8, 13, 11 },
+ { 16, 19, 17 },
+ { 32, 43, 41 },
+ { 64, 73, 71 },
+ { 128, 151, 149 },
+ { 256, 283, 281 },
+ { 512, 571, 569 },
+ { 1024, 1153, 1151 },
+ { 2048, 2269, 2267 },
+ { 4096, 4519, 4517 },
+ { 8192, 9013, 9011 },
+ { 16384, 18043, 18041 },
+ { 32768, 36109, 36107 },
+ { 65536, 72091, 72089 },
+ { 131072, 144409, 144407 },
+ { 262144, 288361, 288359 },
+ { 524288, 576883, 576881 },
+ { 1048576, 1153459, 1153457 },
+ { 2097152, 2307163, 2307161 },
+ { 4194304, 4613893, 4613891 },
+ { 8388608, 9227641, 9227639 },
+ { 16777216, 18455029, 18455027 },
+ { 33554432, 36911011, 36911009 },
+ { 67108864, 73819861, 73819859 },
+ { 134217728, 147639589, 147639587 },
+ { 268435456, 295279081, 295279079 },
+ { 536870912, 590559793, 590559791 },
+ { 1073741824, 1181116273, 1181116271 },
+ { 2147483648ul, 2362232233ul, 2362232231ul }
+};
+
+static int
+entry_is_free(struct set_entry *entry)
+{
+ return entry->key == NULL;
+}
+
+static int
+entry_is_deleted(struct set_entry *entry)
+{
+ return entry->key == deleted_key;
+}
+
+static int
+entry_is_present(struct set_entry *entry)
+{
+ return entry->key != NULL && entry->key != deleted_key;
+}
+
+struct set *
+_mesa_set_create(void *mem_ctx,
+ bool key_equals_function(const void *a,
+ const void *b))
+{
+ struct set *ht;
+
+ ht = ralloc(mem_ctx, struct set);
+ if (ht == NULL)
+ return NULL;
+
+ ht->mem_ctx = mem_ctx;
+ ht->size_index = 0;
+ ht->size = hash_sizes[ht->size_index].size;
+ ht->rehash = hash_sizes[ht->size_index].rehash;
+ ht->max_entries = hash_sizes[ht->size_index].max_entries;
+ ht->key_equals_function = key_equals_function;
+ ht->table = rzalloc_array(ht, struct set_entry, ht->size);
+ ht->entries = 0;
+ ht->deleted_entries = 0;
+
+ if (ht->table == NULL) {
+ ralloc_free(ht);
+ return NULL;
+ }
+
+ return ht;
+}
+
+/**
+ * Frees the given set.
+ *
+ * If delete_function is passed, it gets called on each entry present before
+ * freeing.
+ */
+void
+_mesa_set_destroy(struct set *ht, void (*delete_function)(struct set_entry *entry))
+{
+ if (!ht)
+ return;
+
+ if (delete_function) {
+ struct set_entry *entry;
+
+ set_foreach (ht, entry) {
+ delete_function(entry);
+ }
+ }
+ ralloc_free(ht->table);
+ ralloc_free(ht);
+}
+
+/**
+ * Finds a set entry with the given key and hash of that key.
+ *
+ * Returns NULL if no entry is found.
+ */
+struct set_entry *
+_mesa_set_search(const struct set *ht, uint32_t hash, const void *key)
+{
+ uint32_t hash_address;
+
+ hash_address = hash % ht->size;
+ do {
+ uint32_t double_hash;
+
+ struct set_entry *entry = ht->table + hash_address;
+
+ if (entry_is_free(entry)) {
+ return NULL;
+ } else if (entry_is_present(entry) && entry->hash == hash) {
+ if (ht->key_equals_function(key, entry->key)) {
+ return entry;
+ }
+ }
+
+ double_hash = 1 + hash % ht->rehash;
+
+ hash_address = (hash_address + double_hash) % ht->size;
+ } while (hash_address != hash % ht->size);
+
+ return NULL;
+}
+
+static void
+set_rehash(struct set *ht, int new_size_index)
+{
+ struct set old_ht;
+ struct set_entry *table, *entry;
+
+ if (new_size_index >= ARRAY_SIZE(hash_sizes))
+ return;
+
+ table = rzalloc_array(ht, struct set_entry,
+ hash_sizes[new_size_index].size);
+ if (table == NULL)
+ return;
+
+ old_ht = *ht;
+
+ ht->table = table;
+ ht->size_index = new_size_index;
+ ht->size = hash_sizes[ht->size_index].size;
+ ht->rehash = hash_sizes[ht->size_index].rehash;
+ ht->max_entries = hash_sizes[ht->size_index].max_entries;
+ ht->entries = 0;
+ ht->deleted_entries = 0;
+
+ for (entry = old_ht.table;
+ entry != old_ht.table + old_ht.size;
+ entry++) {
+ if (entry_is_present(entry)) {
+ _mesa_set_add(ht, entry->hash, entry->key);
+ }
+ }
+
+ ralloc_free(old_ht.table);
+}
+
+/**
+ * Inserts the key with the given hash into the table.
+ *
+ * Note that insertion may rearrange the table on a resize or rehash,
+ * so previously found hash_entries are no longer valid after this function.
+ */
+struct set_entry *
+_mesa_set_add(struct set *ht, uint32_t hash, const void *key)
+{
+ uint32_t hash_address;
+
+ if (ht->entries >= ht->max_entries) {
+ set_rehash(ht, ht->size_index + 1);
+ } else if (ht->deleted_entries + ht->entries >= ht->max_entries) {
+ set_rehash(ht, ht->size_index);
+ }
+
+ hash_address = hash % ht->size;
+ do {
+ struct set_entry *entry = ht->table + hash_address;
+ uint32_t double_hash;
+
+ if (!entry_is_present(entry)) {
+ if (entry_is_deleted(entry))
+ ht->deleted_entries--;
+ entry->hash = hash;
+ entry->key = key;
+ ht->entries++;
+ return entry;
+ }
+
+ /* Implement replacement when another insert happens
+ * with a matching key. This is a relatively common
+ * feature of hash tables, with the alternative
+ * generally being "insert the new value as well, and
+ * return it first when the key is searched for".
+ *
+ * Note that the hash table doesn't have a delete callback.
+ * If freeing of old keys is required to avoid memory leaks,
+ * perform a search before inserting.
+ */
+ if (entry->hash == hash &&
+ ht->key_equals_function(key, entry->key)) {
+ entry->key = key;
+ return entry;
+ }
+
+ double_hash = 1 + hash % ht->rehash;
+
+ hash_address = (hash_address + double_hash) % ht->size;
+ } while (hash_address != hash % ht->size);
+
+ /* We could hit here if a required resize failed. An unchecked-malloc
+ * application could ignore this result.
+ */
+ return NULL;
+}
+
+/**
+ * This function deletes the given hash table entry.
+ *
+ * Note that deletion doesn't otherwise modify the table, so an iteration over
+ * the table deleting entries is safe.
+ */
+void
+_mesa_set_remove(struct set *ht, struct set_entry *entry)
+{
+ if (!entry)
+ return;
+
+ entry->key = deleted_key;
+ ht->entries--;
+ ht->deleted_entries++;
+}
+
+/**
+ * This function is an iterator over the hash table.
+ *
+ * Pass in NULL for the first entry, as in the start of a for loop. Note that
+ * an iteration over the table is O(table_size) not O(entries).
+ */
+struct set_entry *
+_mesa_set_next_entry(const struct set *ht, struct set_entry *entry)
+{
+ if (entry == NULL)
+ entry = ht->table;
+ else
+ entry = entry + 1;
+
+ for (; entry != ht->table + ht->size; entry++) {
+ if (entry_is_present(entry)) {
+ return entry;
+ }
+ }
+
+ return NULL;
+}
+
+struct set_entry *
+_mesa_set_random_entry(struct set *ht,
+ int (*predicate)(struct set_entry *entry))
+{
+ struct set_entry *entry;
+ uint32_t i = rand() % ht->size;
+
+ if (ht->entries == 0)
+ return NULL;
+
+ for (entry = ht->table + i; entry != ht->table + ht->size; entry++) {
+ if (entry_is_present(entry) &&
+ (!predicate || predicate(entry))) {
+ return entry;
+ }
+ }
+
+ for (entry = ht->table; entry != ht->table + i; entry++) {
+ if (entry_is_present(entry) &&
+ (!predicate || predicate(entry))) {
+ return entry;
+ }
+ }
+
+ return NULL;
+}
+
diff --git a/mesalib/src/mesa/main/set.h b/mesalib/src/mesa/main/set.h
new file mode 100644
index 000000000..206d0c4d2
--- /dev/null
+++ b/mesalib/src/mesa/main/set.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright © 2009-2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#ifndef _SET_H
+#define _SET_H
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct set_entry {
+ uint32_t hash;
+ const void *key;
+};
+
+struct set {
+ void *mem_ctx;
+ struct set_entry *table;
+ bool (*key_equals_function)(const void *a, const void *b);
+ uint32_t size;
+ uint32_t rehash;
+ uint32_t max_entries;
+ uint32_t size_index;
+ uint32_t entries;
+ uint32_t deleted_entries;
+};
+
+struct set *
+_mesa_set_create(void *mem_ctx,
+ bool (*key_equals_function)(const void *a,
+ const void *b));
+void
+_mesa_set_destroy(struct set *set,
+ void (*delete_function)(struct set_entry *entry));
+
+struct set_entry *
+_mesa_set_add(struct set *set, uint32_t hash, const void *key);
+
+struct set_entry *
+_mesa_set_search(const struct set *set, uint32_t hash,
+ const void *key);
+
+void
+_mesa_set_remove(struct set *set, struct set_entry *entry);
+
+struct set_entry *
+_mesa_set_next_entry(const struct set *set, struct set_entry *entry);
+
+struct set_entry *
+_mesa_set_random_entry(struct set *set,
+ int (*predicate)(struct set_entry *entry));
+
+/**
+ * This foreach function is safe against deletion, but not against
+ * insertion (which may rehash the set, making entry a dangling
+ * pointer).
+ */
+#define set_foreach(set, entry) \
+ for (entry = _mesa_set_next_entry(set, NULL); \
+ entry != NULL; \
+ entry = _mesa_set_next_entry(set, entry))
+
+#ifdef __cplusplus
+} /* extern C */
+#endif
+
+#endif /* _SET_H */
diff --git a/mesalib/src/mesa/main/shared.c b/mesalib/src/mesa/main/shared.c
index eaf9f8de1..a98a45c75 100644
--- a/mesalib/src/mesa/main/shared.c
+++ b/mesalib/src/mesa/main/shared.c
@@ -31,12 +31,14 @@
#include "mfeatures.h"
#include "mtypes.h"
#include "hash.h"
+#include "hash_table.h"
#include "atifragshader.h"
#include "bufferobj.h"
#include "shared.h"
#include "program/program.h"
#include "dlist.h"
#include "samplerobj.h"
+#include "set.h"
#include "shaderobj.h"
#include "syncobj.h"
@@ -115,7 +117,7 @@ _mesa_alloc_shared_state(struct gl_context *ctx)
shared->FrameBuffers = _mesa_NewHashTable();
shared->RenderBuffers = _mesa_NewHashTable();
- make_empty_list(& shared->SyncObjects);
+ shared->SyncObjects = _mesa_set_create(NULL, _mesa_key_pointer_equal);
return shared;
}
@@ -327,13 +329,13 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
_mesa_reference_buffer_object(ctx, &shared->NullBufferObj, NULL);
{
- struct simple_node *node;
- struct simple_node *temp;
+ struct set_entry *entry;
- foreach_s(node, temp, & shared->SyncObjects) {
- _mesa_unref_sync_object(ctx, (struct gl_sync_object *) node);
+ set_foreach(shared->SyncObjects, entry) {
+ _mesa_unref_sync_object(ctx, (struct gl_sync_object *) entry->key);
}
}
+ _mesa_set_destroy(shared->SyncObjects, NULL);
_mesa_HashDeleteAll(shared->SamplerObjects, delete_sampler_object_cb, ctx);
_mesa_DeleteHashTable(shared->SamplerObjects);
diff --git a/mesalib/src/mesa/main/syncobj.c b/mesalib/src/mesa/main/syncobj.c
index 598414596..12e325ccd 100644
--- a/mesalib/src/mesa/main/syncobj.c
+++ b/mesalib/src/mesa/main/syncobj.c
@@ -64,6 +64,8 @@
#include "get.h"
#include "dispatch.h"
#include "mtypes.h"
+#include "set.h"
+#include "hash_table.h"
#include "syncobj.h"
@@ -174,9 +176,12 @@ _mesa_free_sync_data(struct gl_context *ctx)
static int
-_mesa_validate_sync(struct gl_sync_object *syncObj)
+_mesa_validate_sync(struct gl_context *ctx, struct gl_sync_object *syncObj)
{
return (syncObj != NULL)
+ && _mesa_set_search(ctx->Shared->SyncObjects,
+ _mesa_hash_pointer(syncObj),
+ syncObj) != NULL
&& (syncObj->Type == GL_SYNC_FENCE)
&& !syncObj->DeletePending;
}
@@ -197,7 +202,7 @@ _mesa_unref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj)
_glthread_LOCK_MUTEX(ctx->Shared->Mutex);
syncObj->RefCount--;
if (syncObj->RefCount == 0) {
- remove_from_list(& syncObj->link);
+ _mesa_set_remove(ctx->Shared->SyncObjects, syncObj->SetEntry);
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
ctx->Driver.DeleteSyncObject(ctx, syncObj);
@@ -214,7 +219,7 @@ _mesa_IsSync(GLsync sync)
struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- return _mesa_validate_sync(syncObj) ? GL_TRUE : GL_FALSE;
+ return _mesa_validate_sync(ctx, syncObj) ? GL_TRUE : GL_FALSE;
}
@@ -235,8 +240,8 @@ _mesa_DeleteSync(GLsync sync)
return;
}
- if (!_mesa_validate_sync(syncObj)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteSync");
+ if (!_mesa_validate_sync(ctx, syncObj)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteSync (not a valid sync object)");
return;
}
@@ -285,7 +290,9 @@ _mesa_FenceSync(GLenum condition, GLbitfield flags)
ctx->Driver.FenceSync(ctx, syncObj, condition, flags);
_glthread_LOCK_MUTEX(ctx->Shared->Mutex);
- insert_at_tail(& ctx->Shared->SyncObjects, & syncObj->link);
+ syncObj->SetEntry = _mesa_set_add(ctx->Shared->SyncObjects,
+ _mesa_hash_pointer(syncObj),
+ syncObj);
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
return (GLsync) syncObj;
@@ -303,8 +310,8 @@ _mesa_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
GLenum ret;
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_WAIT_FAILED);
- if (!_mesa_validate_sync(syncObj)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glClientWaitSync");
+ if (!_mesa_validate_sync(ctx, syncObj)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glClientWaitSync (not a valid sync object)");
return GL_WAIT_FAILED;
}
@@ -347,8 +354,8 @@ _mesa_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (!_mesa_validate_sync(syncObj)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glWaitSync");
+ if (!_mesa_validate_sync(ctx, syncObj)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glWaitSync (not a valid sync object)");
return;
}
@@ -377,8 +384,8 @@ _mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length,
GLint v[1];
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (!_mesa_validate_sync(syncObj)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetSynciv");
+ if (!_mesa_validate_sync(ctx, syncObj)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetSynciv (not a valid sync object)");
return;
}
diff --git a/mesalib/src/mesa/main/texcompress.c b/mesalib/src/mesa/main/texcompress.c
index 957cc6df6..372a483fa 100644
--- a/mesalib/src/mesa/main/texcompress.c
+++ b/mesalib/src/mesa/main/texcompress.c
@@ -33,6 +33,7 @@
#include "glheader.h"
#include "imports.h"
#include "colormac.h"
+#include "context.h"
#include "formats.h"
#include "mfeatures.h"
#include "mtypes.h"
@@ -77,12 +78,16 @@ _mesa_gl_compressed_format_base_format(GLenum format)
{
switch (format) {
case GL_COMPRESSED_RED:
+ case GL_COMPRESSED_R11_EAC:
case GL_COMPRESSED_RED_RGTC1:
+ case GL_COMPRESSED_SIGNED_R11_EAC:
case GL_COMPRESSED_SIGNED_RED_RGTC1:
return GL_RED;
case GL_COMPRESSED_RG:
+ case GL_COMPRESSED_RG11_EAC:
case GL_COMPRESSED_RG_RGTC2:
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
case GL_COMPRESSED_SIGNED_RG_RGTC2:
return GL_RG;
@@ -92,6 +97,8 @@ _mesa_gl_compressed_format_base_format(GLenum format)
case GL_COMPRESSED_RGB_FXT1_3DFX:
case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
case GL_ETC1_RGB8_OES:
+ case GL_COMPRESSED_RGB8_ETC2:
+ case GL_COMPRESSED_SRGB8_ETC2:
return GL_RGB;
case GL_COMPRESSED_RGBA:
@@ -107,6 +114,10 @@ _mesa_gl_compressed_format_base_format(GLenum format)
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
return GL_RGBA;
case GL_COMPRESSED_ALPHA:
@@ -293,6 +304,23 @@ _mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats)
}
}
+ if (_mesa_is_gles3(ctx)) {
+ if (formats) {
+ formats[n++] = GL_COMPRESSED_RGB8_ETC2;
+ formats[n++] = GL_COMPRESSED_SRGB8_ETC2;
+ formats[n++] = GL_COMPRESSED_RGBA8_ETC2_EAC;
+ formats[n++] = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
+ formats[n++] = GL_COMPRESSED_R11_EAC;
+ formats[n++] = GL_COMPRESSED_RG11_EAC;
+ formats[n++] = GL_COMPRESSED_SIGNED_R11_EAC;
+ formats[n++] = GL_COMPRESSED_SIGNED_RG11_EAC;
+ formats[n++] = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+ formats[n++] = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+ }
+ else {
+ n += 10;
+ }
+ }
return n;
}
@@ -352,6 +380,26 @@ _mesa_glenum_to_compressed_format(GLenum format)
case GL_ETC1_RGB8_OES:
return MESA_FORMAT_ETC1_RGB8;
+ case GL_COMPRESSED_RGB8_ETC2:
+ return MESA_FORMAT_ETC2_RGB8;
+ case GL_COMPRESSED_SRGB8_ETC2:
+ return MESA_FORMAT_ETC2_SRGB8;
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ return MESA_FORMAT_ETC2_RGBA8_EAC;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ return MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC;
+ case GL_COMPRESSED_R11_EAC:
+ return MESA_FORMAT_ETC2_R11_EAC;
+ case GL_COMPRESSED_RG11_EAC:
+ return MESA_FORMAT_ETC2_RG11_EAC;
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ return MESA_FORMAT_ETC2_SIGNED_R11_EAC;
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ return MESA_FORMAT_ETC2_SIGNED_RG11_EAC;
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ return MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1;
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ return MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1;
default:
return MESA_FORMAT_NONE;
@@ -413,6 +461,26 @@ _mesa_compressed_format_to_glenum(struct gl_context *ctx, gl_format mesaFormat)
case MESA_FORMAT_ETC1_RGB8:
return GL_ETC1_RGB8_OES;
+ case MESA_FORMAT_ETC2_RGB8:
+ return GL_COMPRESSED_RGB8_ETC2;
+ case MESA_FORMAT_ETC2_SRGB8:
+ return GL_COMPRESSED_SRGB8_ETC2;
+ case MESA_FORMAT_ETC2_RGBA8_EAC:
+ return GL_COMPRESSED_RGBA8_ETC2_EAC;
+ case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
+ case MESA_FORMAT_ETC2_R11_EAC:
+ return GL_COMPRESSED_R11_EAC;
+ case MESA_FORMAT_ETC2_RG11_EAC:
+ return GL_COMPRESSED_RG11_EAC;
+ case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
+ return GL_COMPRESSED_SIGNED_R11_EAC;
+ case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
+ return GL_COMPRESSED_SIGNED_RG11_EAC;
+ case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
+ return GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+ case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
+ return GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
default:
_mesa_problem(ctx, "Unexpected mesa texture format in"
@@ -538,6 +606,38 @@ _mesa_decompress_image(gl_format format, GLuint width, GLuint height,
fetch = _mesa_fetch_texel_2d_f_etc1_rgb8;
break;
+ /* ETC2 formats */
+ case MESA_FORMAT_ETC2_RGB8:
+ fetch = _mesa_fetch_texel_2d_f_etc2_rgb8;
+ break;
+ case MESA_FORMAT_ETC2_SRGB8:
+ fetch = _mesa_fetch_texel_2d_f_etc2_srgb8;
+ break;
+ case MESA_FORMAT_ETC2_RGBA8_EAC:
+ fetch = _mesa_fetch_texel_2d_f_etc2_rgba8_eac;
+ break;
+ case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
+ fetch = _mesa_fetch_texel_2d_f_etc2_srgb8_alpha8_eac;
+ break;
+ case MESA_FORMAT_ETC2_R11_EAC:
+ fetch = _mesa_fetch_texel_2d_f_etc2_r11_eac;
+ break;
+ case MESA_FORMAT_ETC2_RG11_EAC:
+ fetch = _mesa_fetch_texel_2d_f_etc2_rg11_eac;
+ break;
+ case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
+ fetch = _mesa_fetch_texel_2d_f_etc2_signed_r11_eac;
+ break;
+ case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
+ fetch = _mesa_fetch_texel_2d_f_etc2_signed_rg11_eac;
+ break;
+ case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
+ fetch = _mesa_fetch_texel_2d_f_etc2_rgb8_punchthrough_alpha1;
+ break;
+ case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
+ fetch = _mesa_fetch_texel_2d_f_etc2_srgb8_punchthrough_alpha1;
+ break;
+
default:
_mesa_problem(NULL, "Unexpected format in _mesa_decompress_image()");
return;
diff --git a/mesalib/src/mesa/main/texcompress_etc.c b/mesalib/src/mesa/main/texcompress_etc.c
index c645f52b9..73d2fa4fe 100644
--- a/mesalib/src/mesa/main/texcompress_etc.c
+++ b/mesalib/src/mesa/main/texcompress_etc.c
@@ -24,24 +24,78 @@
/**
* \file texcompress_etc.c
* GL_OES_compressed_ETC1_RGB8_texture support.
+ * Supported ETC2 texture formats are:
+ * GL_COMPRESSED_RGB8_ETC2
+ * GL_COMPRESSED_SRGB8_ETC2
+ * GL_COMPRESSED_RGBA8_ETC2_EAC
+ * GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
+ * GL_COMPRESSED_R11_EAC
+ * GL_COMPRESSED_RG11_EAC
+ * GL_COMPRESSED_SIGNED_R11_EAC
+ * GL_COMPRESSED_SIGNED_RG11_EAC
+ * MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1
+ * MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1
*/
-
+#include <stdbool.h>
#include "mfeatures.h"
#include "texcompress.h"
#include "texcompress_etc.h"
#include "texstore.h"
#include "macros.h"
#include "swrast/s_context.h"
+#include "format_unpack.h"
-GLboolean
-_mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS)
-{
- /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */
- ASSERT(0);
+struct etc2_block {
+ int distance;
+ uint64_t pixel_indices[2];
+ const int *modifier_tables[2];
+ bool flipped;
+ bool opaque;
+ bool is_ind_mode;
+ bool is_diff_mode;
+ bool is_t_mode;
+ bool is_h_mode;
+ bool is_planar_mode;
+ uint8_t base_colors[3][3];
+ uint8_t paint_colors[4][3];
+ uint8_t base_codeword;
+ uint8_t multiplier;
+ uint8_t table_index;
+};
- return GL_FALSE;
-}
+static const int etc2_distance_table[8] = {
+ 3, 6, 11, 16, 23, 32, 41, 64 };
+
+static const int etc2_modifier_tables[16][8] = {
+ { -3, -6, -9, -15, 2, 5, 8, 14},
+ { -3, -7, -10, -13, 2, 6, 9, 12},
+ { -2, -5, -8, -13, 1, 4, 7, 12},
+ { -2, -4, -6, -13, 1, 3, 5, 12},
+ { -3, -6, -8, -12, 2, 5, 7, 11},
+ { -3, -7, -9, -11, 2, 6, 8, 10},
+ { -4, -7, -8, -11, 3, 6, 7, 10},
+ { -3, -5, -8, -11, 2, 4, 7, 10},
+ { -2, -6, -8, -10, 1, 5, 7, 9},
+ { -2, -5, -8, -10, 1, 4, 7, 9},
+ { -2, -4, -8, -10, 1, 3, 7, 9},
+ { -2, -5, -7, -10, 1, 4, 6, 9},
+ { -3, -4, -7, -10, 2, 3, 6, 9},
+ { -1, -2, -3, -10, 0, 1, 2, 9},
+ { -4, -6, -8, -9, 3, 5, 7, 8},
+ { -3, -5, -7, -9, 2, 4, 6, 8},
+};
+
+static const int etc2_modifier_tables_non_opaque[8][4] = {
+ { 0, 8, 0, -8},
+ { 0, 17, 0, -17},
+ { 0, 29, 0, -29},
+ { 0, 42, 0, -42},
+ { 0, 60, 0, -60},
+ { 0, 80, 0, -80},
+ { 0, 106, 0, -106},
+ { 0, 183, 0, -183}
+};
/* define etc1_parse_block and etc. */
#define UINT8_TYPE GLubyte
@@ -50,6 +104,15 @@ _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS)
#undef TAG
#undef UINT8_TYPE
+GLboolean
+_mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS)
+{
+ /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */
+ ASSERT(0);
+
+ return GL_FALSE;
+}
+
void
_mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image *texImage,
GLint i, GLint j, GLint k, GLfloat *texel)
@@ -101,3 +164,1300 @@ _mesa_etc1_unpack_rgba8888(uint8_t *dst_row,
src_row, src_stride,
src_width, src_height);
}
+
+static uint8_t
+etc2_base_color1_t_mode(const uint8_t *in, GLuint index)
+{
+ uint8_t R1a = 0, x = 0;
+ /* base col 1 = extend_4to8bits( (R1a << 2) | R1b, G1, B1) */
+ switch(index) {
+ case 0:
+ R1a = (in[0] >> 3) & 0x3;
+ x = ((R1a << 2) | (in[0] & 0x3));
+ break;
+ case 1:
+ x = ((in[1] >> 4) & 0xf);
+ break;
+ case 2:
+ x = (in[1] & 0xf);
+ break;
+ default:
+ /* invalid index */
+ break;
+ }
+ return ((x << 4) | (x & 0xf));
+}
+
+static uint8_t
+etc2_base_color2_t_mode(const uint8_t *in, GLuint index)
+{
+ uint8_t x = 0;
+ /*extend 4to8bits(R2, G2, B2)*/
+ switch(index) {
+ case 0:
+ x = ((in[2] >> 4) & 0xf );
+ break;
+ case 1:
+ x = (in[2] & 0xf);
+ break;
+ case 2:
+ x = ((in[3] >> 4) & 0xf);
+ break;
+ default:
+ /* invalid index */
+ break;
+ }
+ return ((x << 4) | (x & 0xf));
+}
+
+static uint8_t
+etc2_base_color1_h_mode(const uint8_t *in, GLuint index)
+{
+ uint8_t x = 0;
+ /* base col 1 = extend 4to8bits(R1, (G1a << 1) | G1b, (B1a << 3) | B1b) */
+ switch(index) {
+ case 0:
+ x = ((in[0] >> 3) & 0xf);
+ break;
+ case 1:
+ x = (((in[0] & 0x7) << 1) | ((in[1] >> 4) & 0x1));
+ break;
+ case 2:
+ x = ((in[1] & 0x8) |
+ (((in[1] & 0x3) << 1) | ((in[2] >> 7) & 0x1)));
+ break;
+ default:
+ /* invalid index */
+ break;
+ }
+ return ((x << 4) | (x & 0xf));
+ }
+
+static uint8_t
+etc2_base_color2_h_mode(const uint8_t *in, GLuint index)
+{
+ uint8_t x = 0;
+ /* base col 2 = extend 4to8bits(R2, G2, B2) */
+ switch(index) {
+ case 0:
+ x = ((in[2] >> 3) & 0xf );
+ break;
+ case 1:
+ x = (((in[2] & 0x7) << 1) | ((in[3] >> 7) & 0x1));
+ break;
+ case 2:
+ x = ((in[3] >> 3) & 0xf);
+ break;
+ default:
+ /* invalid index */
+ break;
+ }
+ return ((x << 4) | (x & 0xf));
+ }
+
+static uint8_t
+etc2_base_color_o_planar(const uint8_t *in, GLuint index)
+{
+ GLuint tmp;
+ switch(index) {
+ case 0:
+ tmp = ((in[0] >> 1) & 0x3f); /* RO */
+ return ((tmp << 2) | (tmp >> 4));
+ case 1:
+ tmp = (((in[0] & 0x1) << 6) | /* GO1 */
+ ((in[1] >> 1) & 0x3f)); /* GO2 */
+ return ((tmp << 1) | (tmp >> 6));
+ case 2:
+ tmp = (((in[1] & 0x1) << 5) | /* BO1 */
+ (in[2] & 0x18) | /* BO2 */
+ (((in[2] & 0x3) << 1) | ((in[3] >> 7) & 0x1))); /* BO3 */
+ return ((tmp << 2) | (tmp >> 4));
+ default:
+ /* invalid index */
+ return 0;
+ }
+}
+
+static uint8_t
+etc2_base_color_h_planar(const uint8_t *in, GLuint index)
+{
+ GLuint tmp;
+ switch(index) {
+ case 0:
+ tmp = (((in[3] & 0x7c) >> 1) | /* RH1 */
+ (in[3] & 0x1)); /* RH2 */
+ return ((tmp << 2) | (tmp >> 4));
+ case 1:
+ tmp = (in[4] >> 1) & 0x7f; /* GH */
+ return ((tmp << 1) | (tmp >> 6));
+ case 2:
+ tmp = (((in[4] & 0x1) << 5) |
+ ((in[5] >> 3) & 0x1f)); /* BH */
+ return ((tmp << 2) | (tmp >> 4));
+ default:
+ /* invalid index */
+ return 0;
+ }
+}
+
+static uint8_t
+etc2_base_color_v_planar(const uint8_t *in, GLuint index)
+{
+ GLuint tmp;
+ switch(index) {
+ case 0:
+ tmp = (((in[5] & 0x7) << 0x3) |
+ ((in[6] >> 5) & 0x7)); /* RV */
+ return ((tmp << 2) | (tmp >> 4));
+ case 1:
+ tmp = (((in[6] & 0x1f) << 2) |
+ ((in[7] >> 6) & 0x3)); /* GV */
+ return ((tmp << 1) | (tmp >> 6));
+ case 2:
+ tmp = in[7] & 0x3f; /* BV */
+ return ((tmp << 2) | (tmp >> 4));
+ default:
+ /* invalid index */
+ return 0;
+ }
+}
+
+static GLint
+etc2_get_pixel_index(const struct etc2_block *block, int x, int y)
+{
+ int bit = ((3 - y) + (3 - x) * 4) * 3;
+ int idx = (block->pixel_indices[1] >> bit) & 0x7;
+ return idx;
+}
+
+static uint8_t
+etc2_clamp(int color)
+{
+ /* CLAMP(color, 0, 255) */
+ return (uint8_t) CLAMP(color, 0, 255);
+}
+
+static GLushort
+etc2_clamp2(int color)
+{
+ /* CLAMP(color, 0, 2047) */
+ return (GLushort) CLAMP(color, 0, 2047);
+}
+
+static GLshort
+etc2_clamp3(int color)
+{
+ /* CLAMP(color, -1023, 1023) */
+ return (GLshort) CLAMP(color, -1023, 1023);
+}
+
+static void
+etc2_rgb8_parse_block(struct etc2_block *block,
+ const uint8_t *src,
+ GLboolean punchthrough_alpha)
+{
+ unsigned i;
+ GLboolean diffbit = false;
+ static const int lookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 };
+
+ const int R_plus_dR = (src[0] >> 3) + lookup[src[0] & 0x7];
+ const int G_plus_dG = (src[1] >> 3) + lookup[src[1] & 0x7];
+ const int B_plus_dB = (src[2] >> 3) + lookup[src[2] & 0x7];
+
+ /* Reset the mode flags */
+ block->is_ind_mode = false;
+ block->is_diff_mode = false;
+ block->is_t_mode = false;
+ block->is_h_mode = false;
+ block->is_planar_mode = false;
+
+ if (punchthrough_alpha)
+ block->opaque = src[3] & 0x2;
+ else
+ diffbit = src[3] & 0x2;
+
+ if (!diffbit && !punchthrough_alpha) {
+ /* individual mode */
+ block->is_ind_mode = true;
+
+ for (i = 0; i < 3; i++) {
+ /* Texture decode algorithm is same for individual mode in etc1
+ * & etc2.
+ */
+ block->base_colors[0][i] = etc1_base_color_ind_hi(src[i]);
+ block->base_colors[1][i] = etc1_base_color_ind_lo(src[i]);
+ }
+ }
+ else if (R_plus_dR < 0 || R_plus_dR > 31){
+ /* T mode */
+ block->is_t_mode = true;
+
+ for(i = 0; i < 3; i++) {
+ block->base_colors[0][i] = etc2_base_color1_t_mode(src, i);
+ block->base_colors[1][i] = etc2_base_color2_t_mode(src, i);
+ }
+ /* pick distance */
+ block->distance =
+ etc2_distance_table[(((src[3] >> 2) & 0x3) << 1) |
+ (src[3] & 0x1)];
+
+ for (i = 0; i < 3; i++) {
+ block->paint_colors[0][i] = etc2_clamp(block->base_colors[0][i]);
+ block->paint_colors[1][i] = etc2_clamp(block->base_colors[1][i] +
+ block->distance);
+ block->paint_colors[2][i] = etc2_clamp(block->base_colors[1][i]);
+ block->paint_colors[3][i] = etc2_clamp(block->base_colors[1][i] -
+ block->distance);
+ }
+ }
+ else if (G_plus_dG < 0 || G_plus_dG > 31){
+ int base_color_1_value, base_color_2_value;
+
+ /* H mode */
+ block->is_h_mode = true;
+
+ for(i = 0; i < 3; i++) {
+ block->base_colors[0][i] = etc2_base_color1_h_mode(src, i);
+ block->base_colors[1][i] = etc2_base_color2_h_mode(src, i);
+ }
+
+ base_color_1_value = (block->base_colors[0][0] << 16) +
+ (block->base_colors[0][1] << 8) +
+ block->base_colors[0][2];
+ base_color_2_value = (block->base_colors[1][0] << 16) +
+ (block->base_colors[1][1] << 8) +
+ block->base_colors[1][2];
+ /* pick distance */
+ block->distance =
+ etc2_distance_table[(src[3] & 0x4) |
+ ((src[3] & 0x1) << 1) |
+ (base_color_1_value >= base_color_2_value)];
+
+ for (i = 0; i < 3; i++) {
+ block->paint_colors[0][i] = etc2_clamp(block->base_colors[0][i] +
+ block->distance);
+ block->paint_colors[1][i] = etc2_clamp(block->base_colors[0][i] -
+ block->distance);
+ block->paint_colors[2][i] = etc2_clamp(block->base_colors[1][i] +
+ block->distance);
+ block->paint_colors[3][i] = etc2_clamp(block->base_colors[1][i] -
+ block->distance);
+ }
+ }
+ else if (B_plus_dB < 0 || B_plus_dB > 31) {
+ /* Planar mode */
+ block->is_planar_mode = true;
+
+ /* opaque bit must be set in planar mode */
+ if (!block->opaque)
+ block->opaque = true;
+
+ for (i = 0; i < 3; i++) {
+ block->base_colors[0][i] = etc2_base_color_o_planar(src, i);
+ block->base_colors[1][i] = etc2_base_color_h_planar(src, i);
+ block->base_colors[2][i] = etc2_base_color_v_planar(src, i);
+ }
+ }
+ else if (diffbit || punchthrough_alpha) {
+ /* differential mode */
+ block->is_diff_mode = true;
+
+ for (i = 0; i < 3; i++) {
+ /* Texture decode algorithm is same for differential mode in etc1
+ * & etc2.
+ */
+ block->base_colors[0][i] = etc1_base_color_diff_hi(src[i]);
+ block->base_colors[1][i] = etc1_base_color_diff_lo(src[i]);
+ }
+ }
+
+ if (block->is_ind_mode || block->is_diff_mode) {
+ int table1_idx = (src[3] >> 5) & 0x7;
+ int table2_idx = (src[3] >> 2) & 0x7;
+
+ /* Use same modifier tables as for etc1 textures if opaque bit is set
+ * or if non punchthrough texture format
+ */
+ block->modifier_tables[0] = (block->opaque || !punchthrough_alpha) ?
+ etc1_modifier_tables[table1_idx] :
+ etc2_modifier_tables_non_opaque[table1_idx];
+ block->modifier_tables[1] = (block->opaque || !punchthrough_alpha) ?
+ etc1_modifier_tables[table2_idx] :
+ etc2_modifier_tables_non_opaque[table2_idx];
+
+ block->flipped = (src[3] & 0x1);
+ }
+
+ block->pixel_indices[0] =
+ (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7];
+}
+
+static void
+etc2_rgb8_fetch_texel(const struct etc2_block *block,
+ int x, int y, uint8_t *dst,
+ GLboolean punchthrough_alpha)
+{
+ const uint8_t *base_color;
+ int modifier, bit, idx, blk;
+
+ /* get pixel index */
+ bit = y + x * 4;
+ idx = ((block->pixel_indices[0] >> (15 + bit)) & 0x2) |
+ ((block->pixel_indices[0] >> (bit)) & 0x1);
+
+ if (block->is_ind_mode || block->is_diff_mode) {
+ /* check for punchthrough_alpha format */
+ if (punchthrough_alpha) {
+ if (!block->opaque && idx == 2) {
+ dst[0] = dst[1] = dst[2] = dst[3] = 0;
+ return;
+ }
+ else
+ dst[3] = 255;
+ }
+
+ /* Use pixel index and subblock to get the modifier */
+ blk = (block->flipped) ? (y >= 2) : (x >= 2);
+ base_color = block->base_colors[blk];
+ modifier = block->modifier_tables[blk][idx];
+
+ dst[0] = etc2_clamp(base_color[0] + modifier);
+ dst[1] = etc2_clamp(base_color[1] + modifier);
+ dst[2] = etc2_clamp(base_color[2] + modifier);
+ }
+ else if (block->is_t_mode || block->is_h_mode) {
+ /* check for punchthrough_alpha format */
+ if (punchthrough_alpha) {
+ if (!block->opaque && idx == 2) {
+ dst[0] = dst[1] = dst[2] = dst[3] = 0;
+ return;
+ }
+ else
+ dst[3] = 255;
+ }
+
+ /* Use pixel index to pick one of the paint colors */
+ dst[0] = block->paint_colors[idx][0];
+ dst[1] = block->paint_colors[idx][1];
+ dst[2] = block->paint_colors[idx][2];
+ }
+ else if (block->is_planar_mode) {
+ /* {R(x, y) = clamp255((x × (RH − RO) + y × (RV − RO) + 4 × RO + 2) >> 2)
+ * {G(x, y) = clamp255((x × (GH − GO) + y × (GV − GO) + 4 × GO + 2) >> 2)
+ * {B(x, y) = clamp255((x × (BH − BO) + y × (BV − BO) + 4 × BO + 2) >> 2)
+ */
+ int red, green, blue;
+ red = (x * (block->base_colors[1][0] - block->base_colors[0][0]) +
+ y * (block->base_colors[2][0] - block->base_colors[0][0]) +
+ 4 * block->base_colors[0][0] + 2) >> 2;
+
+ green = (x * (block->base_colors[1][1] - block->base_colors[0][1]) +
+ y * (block->base_colors[2][1] - block->base_colors[0][1]) +
+ 4 * block->base_colors[0][1] + 2) >> 2;
+
+ blue = (x * (block->base_colors[1][2] - block->base_colors[0][2]) +
+ y * (block->base_colors[2][2] - block->base_colors[0][2]) +
+ 4 * block->base_colors[0][2] + 2) >> 2;
+
+ dst[0] = etc2_clamp(red);
+ dst[1] = etc2_clamp(green);
+ dst[2] = etc2_clamp(blue);
+
+ /* check for punchthrough_alpha format */
+ if (punchthrough_alpha)
+ dst[3] = 255;
+ }
+}
+
+static void
+etc2_alpha8_fetch_texel(const struct etc2_block *block,
+ int x, int y, uint8_t *dst)
+{
+ int modifier, alpha, idx;
+ /* get pixel index */
+ idx = etc2_get_pixel_index(block, x, y);
+ modifier = etc2_modifier_tables[block->table_index][idx];
+ alpha = block->base_codeword + modifier * block->multiplier;
+ dst[3] = etc2_clamp(alpha);
+}
+
+static void
+etc2_r11_fetch_texel(const struct etc2_block *block,
+ int x, int y, uint8_t *dst)
+{
+ GLint modifier, idx;
+ GLshort color;
+ /* Get pixel index */
+ idx = etc2_get_pixel_index(block, x, y);
+ modifier = etc2_modifier_tables[block->table_index][idx];
+
+ if (block->multiplier != 0)
+ /* clamp2(base codeword × 8 + 4 + modifier × multiplier × 8) */
+ color = etc2_clamp2(((block->base_codeword << 3) | 0x4) +
+ ((modifier * block->multiplier) << 3));
+ else
+ color = etc2_clamp2(((block->base_codeword << 3) | 0x4) + modifier);
+
+ /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification
+ * allows extending the color value to any number of bits. But, an
+ * implementation is not allowed to truncate the 11-bit value to less than
+ * 11 bits."
+ */
+ color = (color << 5) | (color >> 6);
+ ((GLushort *)dst)[0] = color;
+}
+
+static void
+etc2_signed_r11_fetch_texel(const struct etc2_block *block,
+ int x, int y, uint8_t *dst)
+{
+ GLint modifier, idx;
+ GLshort color;
+ GLbyte base_codeword = (GLbyte) block->base_codeword;
+
+ if (base_codeword == -128)
+ base_codeword = -127;
+
+ /* Get pixel index */
+ idx = etc2_get_pixel_index(block, x, y);
+ modifier = etc2_modifier_tables[block->table_index][idx];
+
+ if (block->multiplier != 0)
+ /* clamp3(base codeword × 8 + modifier × multiplier × 8) */
+ color = etc2_clamp3((base_codeword << 3) +
+ ((modifier * block->multiplier) << 3));
+ else
+ color = etc2_clamp3((base_codeword << 3) + modifier);
+
+ /* Extend 11 bits color value to 16 bits. OpenGL ES 3.0 specification
+ * allows extending the color value to any number of bits. But, an
+ * implementation is not allowed to truncate the 11-bit value to less than
+ * 11 bits. A negative 11-bit value must first be made positive before bit
+ * replication, and then made negative again
+ */
+ if (color >= 0)
+ color = (color << 5) | (color >> 5);
+ else {
+ color = -color;
+ color = (color << 5) | (color >> 5);
+ color = -color;
+ }
+ ((GLshort *)dst)[0] = color;
+}
+
+static void
+etc2_alpha8_parse_block(struct etc2_block *block, const uint8_t *src)
+{
+ block->base_codeword = src[0];
+ block->multiplier = (src[1] >> 4) & 0xf;
+ block->table_index = src[1] & 0xf;
+ block->pixel_indices[1] = (((uint64_t)src[2] << 40) |
+ ((uint64_t)src[3] << 32) |
+ ((uint64_t)src[4] << 24) |
+ ((uint64_t)src[5] << 16) |
+ ((uint64_t)src[6] << 8) |
+ ((uint64_t)src[7]));
+}
+
+static void
+etc2_r11_parse_block(struct etc2_block *block, const uint8_t *src)
+{
+ /* Parsing logic remains same as for etc2_alpha8_parse_block */
+ etc2_alpha8_parse_block(block, src);
+}
+
+static void
+etc2_rgba8_parse_block(struct etc2_block *block, const uint8_t *src)
+{
+ /* RGB component is parsed the same way as for MESA_FORMAT_ETC2_RGB8 */
+ etc2_rgb8_parse_block(block, src + 8,
+ false /* punchthrough_alpha */);
+ /* Parse Alpha component */
+ etc2_alpha8_parse_block(block, src);
+}
+
+static void
+etc2_rgba8_fetch_texel(const struct etc2_block *block,
+ int x, int y, uint8_t *dst)
+{
+ etc2_rgb8_fetch_texel(block, x, y, dst,
+ false /* punchthrough_alpha */);
+ etc2_alpha8_fetch_texel(block, x, y, dst);
+}
+
+static void
+etc2_unpack_rgb8(uint8_t *dst_row,
+ unsigned dst_stride,
+ const uint8_t *src_row,
+ unsigned src_stride,
+ unsigned width,
+ unsigned height)
+{
+ const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
+ struct etc2_block block;
+ unsigned x, y, i, j;
+
+ for (y = 0; y < height; y += bh) {
+ const uint8_t *src = src_row;
+
+ for (x = 0; x < width; x+= bw) {
+ etc2_rgb8_parse_block(&block, src,
+ false /* punchthrough_alpha */);
+
+ for (j = 0; j < bh; j++) {
+ uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
+ for (i = 0; i < bw; i++) {
+ etc2_rgb8_fetch_texel(&block, i, j, dst,
+ false /* punchthrough_alpha */);
+ dst[3] = 255;
+ dst += comps;
+ }
+ }
+
+ src += bs;
+ }
+
+ src_row += src_stride;
+ }
+}
+
+static void
+etc2_unpack_srgb8(uint8_t *dst_row,
+ unsigned dst_stride,
+ const uint8_t *src_row,
+ unsigned src_stride,
+ unsigned width,
+ unsigned height)
+{
+ const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
+ struct etc2_block block;
+ unsigned x, y, i, j;
+ uint8_t tmp;
+
+ for (y = 0; y < height; y += bh) {
+ const uint8_t *src = src_row;
+
+ for (x = 0; x < width; x+= bw) {
+ etc2_rgb8_parse_block(&block, src,
+ false /* punchthrough_alpha */);
+
+ for (j = 0; j < bh; j++) {
+ uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
+ for (i = 0; i < bw; i++) {
+ etc2_rgb8_fetch_texel(&block, i, j, dst,
+ false /* punchthrough_alpha */);
+ /* Convert to MESA_FORMAT_SARGB8 */
+ tmp = dst[0];
+ dst[0] = dst[2];
+ dst[2] = tmp;
+ dst[3] = 255;
+
+ dst += comps;
+ }
+ }
+ src += bs;
+ }
+
+ src_row += src_stride;
+ }
+}
+
+static void
+etc2_unpack_rgba8(uint8_t *dst_row,
+ unsigned dst_stride,
+ const uint8_t *src_row,
+ unsigned src_stride,
+ unsigned width,
+ unsigned height)
+{
+ /* If internalformat is COMPRESSED_RGBA8_ETC2_EAC, each 4 × 4 block of
+ * RGBA8888 information is compressed to 128 bits. To decode a block, the
+ * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
+ */
+ const unsigned bw = 4, bh = 4, bs = 16, comps = 4;
+ struct etc2_block block;
+ unsigned x, y, i, j;
+
+ for (y = 0; y < height; y += bh) {
+ const uint8_t *src = src_row;
+
+ for (x = 0; x < width; x+= bw) {
+ etc2_rgba8_parse_block(&block, src);
+
+ for (j = 0; j < bh; j++) {
+ uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
+ for (i = 0; i < bw; i++) {
+ etc2_rgba8_fetch_texel(&block, i, j, dst);
+ dst += comps;
+ }
+ }
+ src += bs;
+ }
+
+ src_row += src_stride;
+ }
+}
+
+static void
+etc2_unpack_srgb8_alpha8(uint8_t *dst_row,
+ unsigned dst_stride,
+ const uint8_t *src_row,
+ unsigned src_stride,
+ unsigned width,
+ unsigned height)
+{
+ /* If internalformat is COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, each 4 × 4 block
+ * of RGBA8888 information is compressed to 128 bits. To decode a block, the
+ * two 64-bit integers int64bitAlpha and int64bitColor are calculated.
+ */
+ const unsigned bw = 4, bh = 4, bs = 16, comps = 4;
+ struct etc2_block block;
+ unsigned x, y, i, j;
+ uint8_t tmp;
+
+ for (y = 0; y < height; y += bh) {
+ const uint8_t *src = src_row;
+
+ for (x = 0; x < width; x+= bw) {
+ etc2_rgba8_parse_block(&block, src);
+
+ for (j = 0; j < bh; j++) {
+ uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
+ for (i = 0; i < bw; i++) {
+ etc2_rgba8_fetch_texel(&block, i, j, dst);
+
+ /* Convert to MESA_FORMAT_SARGB8 */
+ tmp = dst[0];
+ dst[0] = dst[2];
+ dst[2] = tmp;
+ dst[3] = dst[3];
+
+ dst += comps;
+ }
+ }
+ src += bs;
+ }
+
+ src_row += src_stride;
+ }
+}
+
+static void
+etc2_unpack_r11(uint8_t *dst_row,
+ unsigned dst_stride,
+ const uint8_t *src_row,
+ unsigned src_stride,
+ unsigned width,
+ unsigned height)
+{
+ /* If internalformat is COMPRESSED_R11_EAC, each 4 × 4 block of
+ color information is compressed to 64 bits.
+ */
+ const unsigned bw = 4, bh = 4, bs = 8, comps = 1, comp_size = 2;
+ struct etc2_block block;
+ unsigned x, y, i, j;
+
+ for (y = 0; y < height; y += bh) {
+ const uint8_t *src = src_row;
+
+ for (x = 0; x < width; x+= bw) {
+ etc2_r11_parse_block(&block, src);
+
+ for (j = 0; j < bh; j++) {
+ uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size;
+ for (i = 0; i < bw; i++) {
+ etc2_r11_fetch_texel(&block, i, j, dst);
+ dst += comps * comp_size;
+ }
+ }
+ src += bs;
+ }
+
+ src_row += src_stride;
+ }
+}
+
+static void
+etc2_unpack_rg11(uint8_t *dst_row,
+ unsigned dst_stride,
+ const uint8_t *src_row,
+ unsigned src_stride,
+ unsigned width,
+ unsigned height)
+{
+ /* If internalformat is COMPRESSED_RG11_EAC, each 4 × 4 block of
+ RG color information is compressed to 128 bits.
+ */
+ const unsigned bw = 4, bh = 4, bs = 16, comps = 2, comp_size = 2;
+ struct etc2_block block;
+ unsigned x, y, i, j;
+
+ for (y = 0; y < height; y += bh) {
+ const uint8_t *src = src_row;
+
+ for (x = 0; x < width; x+= bw) {
+ /* red component */
+ etc2_r11_parse_block(&block, src);
+
+ for (j = 0; j < bh; j++) {
+ uint8_t *dst = dst_row + (y + j) * dst_stride +
+ x * comps * comp_size;
+ for (i = 0; i < bw; i++) {
+ etc2_r11_fetch_texel(&block, i, j, dst);
+ dst += comps * comp_size;
+ }
+ }
+ /* green component */
+ etc2_r11_parse_block(&block, src + 8);
+
+ for (j = 0; j < bh; j++) {
+ uint8_t *dst = dst_row + (y + j) * dst_stride +
+ x * comps * comp_size;
+ for (i = 0; i < bw; i++) {
+ etc2_r11_fetch_texel(&block, i, j, dst + comp_size);
+ dst += comps * comp_size;
+ }
+ }
+ src += bs;
+ }
+
+ src_row += src_stride;
+ }
+}
+
+static void
+etc2_unpack_signed_r11(uint8_t *dst_row,
+ unsigned dst_stride,
+ const uint8_t *src_row,
+ unsigned src_stride,
+ unsigned width,
+ unsigned height)
+{
+ /* If internalformat is COMPRESSED_SIGNED_R11_EAC, each 4 × 4 block of
+ red color information is compressed to 64 bits.
+ */
+ const unsigned bw = 4, bh = 4, bs = 8, comps = 1, comp_size = 2;
+ struct etc2_block block;
+ unsigned x, y, i, j;
+
+ for (y = 0; y < height; y += bh) {
+ const uint8_t *src = src_row;
+
+ for (x = 0; x < width; x+= bw) {
+ etc2_r11_parse_block(&block, src);
+
+ for (j = 0; j < bh; j++) {
+ uint8_t *dst = dst_row + (y + j) * dst_stride +
+ x * comps * comp_size;
+ for (i = 0; i < bw; i++) {
+ etc2_signed_r11_fetch_texel(&block, i, j, dst);
+ dst += comps * comp_size;
+ }
+ }
+ src += bs;
+ }
+
+ src_row += src_stride;
+ }
+}
+
+static void
+etc2_unpack_signed_rg11(uint8_t *dst_row,
+ unsigned dst_stride,
+ const uint8_t *src_row,
+ unsigned src_stride,
+ unsigned width,
+ unsigned height)
+{
+ /* If internalformat is COMPRESSED_SIGNED_RG11_EAC, each 4 × 4 block of
+ RG color information is compressed to 128 bits.
+ */
+ const unsigned bw = 4, bh = 4, bs = 16, comps = 2, comp_size = 2;
+ struct etc2_block block;
+ unsigned x, y, i, j;
+
+ for (y = 0; y < height; y += bh) {
+ const uint8_t *src = src_row;
+
+ for (x = 0; x < width; x+= bw) {
+ /* red component */
+ etc2_r11_parse_block(&block, src);
+
+ for (j = 0; j < bh; j++) {
+ uint8_t *dst = dst_row + (y + j) * dst_stride +
+ x * comps * comp_size;
+ for (i = 0; i < bw; i++) {
+ etc2_signed_r11_fetch_texel(&block, i, j, dst);
+ dst += comps * comp_size;
+ }
+ }
+ /* green component */
+ etc2_r11_parse_block(&block, src + 8);
+
+ for (j = 0; j < bh; j++) {
+ uint8_t *dst = dst_row + (y + j) * dst_stride +
+ x * comps * comp_size;
+ for (i = 0; i < bw; i++) {
+ etc2_signed_r11_fetch_texel(&block, i, j, dst + comp_size);
+ dst += comps * comp_size;
+ }
+ }
+ src += bs;
+ }
+
+ src_row += src_stride;
+ }
+}
+
+static void
+etc2_unpack_rgb8_punchthrough_alpha1(uint8_t *dst_row,
+ unsigned dst_stride,
+ const uint8_t *src_row,
+ unsigned src_stride,
+ unsigned width,
+ unsigned height)
+{
+ const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
+ struct etc2_block block;
+ unsigned x, y, i, j;
+
+ for (y = 0; y < height; y += bh) {
+ const uint8_t *src = src_row;
+
+ for (x = 0; x < width; x+= bw) {
+ etc2_rgb8_parse_block(&block, src,
+ true /* punchthrough_alpha */);
+ for (j = 0; j < bh; j++) {
+ uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
+ for (i = 0; i < bw; i++) {
+ etc2_rgb8_fetch_texel(&block, i, j, dst,
+ true /* punchthrough_alpha */);
+ dst += comps;
+ }
+ }
+
+ src += bs;
+ }
+
+ src_row += src_stride;
+ }
+}
+
+static void
+etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row,
+ unsigned dst_stride,
+ const uint8_t *src_row,
+ unsigned src_stride,
+ unsigned width,
+ unsigned height)
+{
+ const unsigned bw = 4, bh = 4, bs = 8, comps = 4;
+ struct etc2_block block;
+ unsigned x, y, i, j;
+ uint8_t tmp;
+
+ for (y = 0; y < height; y += bh) {
+ const uint8_t *src = src_row;
+
+ for (x = 0; x < width; x+= bw) {
+ etc2_rgb8_parse_block(&block, src,
+ true /* punchthrough_alpha */);
+ for (j = 0; j < bh; j++) {
+ uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
+ for (i = 0; i < bw; i++) {
+ etc2_rgb8_fetch_texel(&block, i, j, dst,
+ true /* punchthrough_alpha */);
+ /* Convert to MESA_FORMAT_SARGB8 */
+ tmp = dst[0];
+ dst[0] = dst[2];
+ dst[2] = tmp;
+ dst[3] = dst[3];
+
+ dst += comps;
+ }
+ }
+
+ src += bs;
+ }
+
+ src_row += src_stride;
+ }
+}
+
+/* ETC2 texture formats are valid in glCompressedTexImage2D and
+ * glCompressedTexSubImage2D functions */
+GLboolean
+_mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS)
+{
+ ASSERT(0);
+
+ return GL_FALSE;
+}
+
+GLboolean
+_mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS)
+{
+ ASSERT(0);
+
+ return GL_FALSE;
+}
+
+GLboolean
+_mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS)
+{
+ ASSERT(0);
+
+ return GL_FALSE;
+}
+
+GLboolean
+_mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS)
+{
+ ASSERT(0);
+
+ return GL_FALSE;
+}
+
+GLboolean
+_mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS)
+{
+ ASSERT(0);
+
+ return GL_FALSE;
+}
+
+GLboolean
+_mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS)
+{
+ ASSERT(0);
+
+ return GL_FALSE;
+}
+
+GLboolean
+_mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS)
+{
+ ASSERT(0);
+
+ return GL_FALSE;
+}
+
+GLboolean
+_mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS)
+{
+ ASSERT(0);
+
+ return GL_FALSE;
+}
+
+GLboolean
+_mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS)
+{
+ ASSERT(0);
+
+ return GL_FALSE;
+}
+
+GLboolean
+_mesa_texstore_etc2_srgb8_punchthrough_alpha1(TEXSTORE_PARAMS)
+{
+ ASSERT(0);
+
+ return GL_FALSE;
+}
+
+void
+_mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel)
+{
+ struct etc2_block block;
+ uint8_t dst[3];
+ const uint8_t *src;
+
+ src = texImage->Map +
+ (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
+
+ etc2_rgb8_parse_block(&block, src,
+ false /* punchthrough_alpha */);
+ etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst,
+ false /* punchthrough_alpha */);
+
+ texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
+ texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
+ texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
+ texel[ACOMP] = 1.0f;
+}
+
+void
+_mesa_fetch_texel_2d_f_etc2_srgb8(const struct swrast_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel)
+{
+ struct etc2_block block;
+ uint8_t dst[3];
+ const uint8_t *src;
+
+ src = texImage->Map +
+ (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
+
+ etc2_rgb8_parse_block(&block, src,
+ false /* punchthrough_alpha */);
+ etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst,
+ false /* punchthrough_alpha */);
+
+ texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]);
+ texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]);
+ texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]);
+ texel[ACOMP] = 1.0f;
+}
+
+void
+_mesa_fetch_texel_2d_f_etc2_rgba8_eac(const struct swrast_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel)
+{
+ struct etc2_block block;
+ uint8_t dst[4];
+ const uint8_t *src;
+
+ src = texImage->Map +
+ (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
+
+ etc2_rgba8_parse_block(&block, src);
+ etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst);
+
+ texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
+ texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
+ texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
+ texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]);
+}
+
+void
+_mesa_fetch_texel_2d_f_etc2_srgb8_alpha8_eac(const struct
+ swrast_texture_image *texImage,
+ GLint i, GLint j,
+ GLint k, GLfloat *texel)
+{
+ struct etc2_block block;
+ uint8_t dst[4];
+ const uint8_t *src;
+
+ src = texImage->Map +
+ (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
+
+ etc2_rgba8_parse_block(&block, src);
+ etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst);
+
+ texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]);
+ texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]);
+ texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]);
+ texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]);
+}
+
+void
+_mesa_fetch_texel_2d_f_etc2_r11_eac(const struct swrast_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel)
+{
+ struct etc2_block block;
+ GLushort dst;
+ const uint8_t *src;
+
+ src = texImage->Map +
+ (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
+
+ etc2_r11_parse_block(&block, src);
+ etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)&dst);
+
+ texel[RCOMP] = USHORT_TO_FLOAT(dst);
+ texel[GCOMP] = 0.0f;
+ texel[BCOMP] = 0.0f;
+ texel[ACOMP] = 1.0f;
+}
+
+void
+_mesa_fetch_texel_2d_f_etc2_rg11_eac(const struct
+ swrast_texture_image *texImage,
+ GLint i, GLint j,
+ GLint k, GLfloat *texel)
+{
+ struct etc2_block block;
+ GLushort dst[2];
+ const uint8_t *src;
+
+ src = texImage->Map +
+ (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
+
+ /* red component */
+ etc2_r11_parse_block(&block, src);
+ etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)dst);
+
+ /* green component */
+ etc2_r11_parse_block(&block, src + 8);
+ etc2_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)(dst + 1));
+
+ texel[RCOMP] = USHORT_TO_FLOAT(dst[0]);
+ texel[GCOMP] = USHORT_TO_FLOAT(dst[1]);
+ texel[BCOMP] = 0.0f;
+ texel[ACOMP] = 1.0f;
+}
+
+void
+_mesa_fetch_texel_2d_f_etc2_signed_r11_eac(const struct swrast_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel)
+{
+ struct etc2_block block;
+ GLushort dst;
+ const uint8_t *src;
+
+ src = texImage->Map +
+ (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
+
+ etc2_r11_parse_block(&block, src);
+ etc2_signed_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)&dst);
+
+ texel[RCOMP] = SHORT_TO_FLOAT(dst);
+ texel[GCOMP] = 0.0f;
+ texel[BCOMP] = 0.0f;
+ texel[ACOMP] = 1.0f;
+}
+
+void
+_mesa_fetch_texel_2d_f_etc2_signed_rg11_eac(const struct swrast_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel)
+{
+ struct etc2_block block;
+ GLushort dst[2];
+ const uint8_t *src;
+
+ src = texImage->Map +
+ (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 16;
+
+ /* red component */
+ etc2_r11_parse_block(&block, src);
+ etc2_signed_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)dst);
+
+ /* green component */
+ etc2_r11_parse_block(&block, src + 8);
+ etc2_signed_r11_fetch_texel(&block, i % 4, j % 4, (uint8_t *)(dst + 1));
+
+ texel[RCOMP] = SHORT_TO_FLOAT(dst[0]);
+ texel[GCOMP] = SHORT_TO_FLOAT(dst[1]);
+ texel[BCOMP] = 0.0f;
+ texel[ACOMP] = 1.0f;
+}
+
+void
+_mesa_fetch_texel_2d_f_etc2_rgb8_punchthrough_alpha1(
+ const struct swrast_texture_image *texImage,
+ GLint i, GLint j,
+ GLint k, GLfloat *texel)
+{
+ struct etc2_block block;
+ uint8_t dst[4];
+ const uint8_t *src;
+
+ src = texImage->Map +
+ (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
+
+ etc2_rgb8_parse_block(&block, src,
+ true /* punchthrough alpha */);
+ etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst,
+ true /* punchthrough alpha */);
+ texel[RCOMP] = UBYTE_TO_FLOAT(dst[0]);
+ texel[GCOMP] = UBYTE_TO_FLOAT(dst[1]);
+ texel[BCOMP] = UBYTE_TO_FLOAT(dst[2]);
+ texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]);
+}
+
+void
+_mesa_fetch_texel_2d_f_etc2_srgb8_punchthrough_alpha1(
+ const struct swrast_texture_image *texImage,
+ GLint i, GLint j,
+ GLint k, GLfloat *texel)
+{
+ struct etc2_block block;
+ uint8_t dst[4];
+ const uint8_t *src;
+
+ src = texImage->Map +
+ (((texImage->RowStride + 3) / 4) * (j / 4) + (i / 4)) * 8;
+
+ etc2_rgb8_parse_block(&block, src,
+ true /* punchthrough alpha */);
+ etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst,
+ true /* punchthrough alpha */);
+ texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]);
+ texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]);
+ texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]);
+ texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]);
+}
+
+/**
+ * Decode texture data in any one of following formats:
+ * `MESA_FORMAT_ETC2_RGB8`
+ * `MESA_FORMAT_ETC2_SRGB8`
+ * `MESA_FORMAT_ETC2_RGBA8_EAC`
+ * `MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC`
+ * `MESA_FORMAT_ETC2_R11_EAC`
+ * `MESA_FORMAT_ETC2_RG11_EAC`
+ * `MESA_FORMAT_ETC2_SIGNED_R11_EAC`
+ * `MESA_FORMAT_ETC2_SIGNED_RG11_EAC`
+ * `MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1`
+ * `MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1`
+ *
+ * The size of the source data must be a multiple of the ETC2 block size
+ * even if the texture image's dimensions are not aligned to 4.
+ *
+ * \param src_width in pixels
+ * \param src_height in pixels
+ * \param dst_stride in bytes
+ */
+
+void
+_mesa_unpack_etc2_format(uint8_t *dst_row,
+ unsigned dst_stride,
+ const uint8_t *src_row,
+ unsigned src_stride,
+ unsigned src_width,
+ unsigned src_height,
+ gl_format format)
+{
+ if (format == MESA_FORMAT_ETC2_RGB8)
+ etc2_unpack_rgb8(dst_row, dst_stride,
+ src_row, src_stride,
+ src_width, src_height);
+ else if (format == MESA_FORMAT_ETC2_SRGB8)
+ etc2_unpack_srgb8(dst_row, dst_stride,
+ src_row, src_stride,
+ src_width, src_height);
+ else if (format == MESA_FORMAT_ETC2_RGBA8_EAC)
+ etc2_unpack_rgba8(dst_row, dst_stride,
+ src_row, src_stride,
+ src_width, src_height);
+ else if (format == MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC)
+ etc2_unpack_srgb8_alpha8(dst_row, dst_stride,
+ src_row, src_stride,
+ src_width, src_height);
+ else if (format == MESA_FORMAT_ETC2_R11_EAC)
+ etc2_unpack_r11(dst_row, dst_stride,
+ src_row, src_stride,
+ src_width, src_height);
+ else if (format == MESA_FORMAT_ETC2_RG11_EAC)
+ etc2_unpack_rg11(dst_row, dst_stride,
+ src_row, src_stride,
+ src_width, src_height);
+ else if (format == MESA_FORMAT_ETC2_SIGNED_R11_EAC)
+ etc2_unpack_signed_r11(dst_row, dst_stride,
+ src_row, src_stride,
+ src_width, src_height);
+ else if (format == MESA_FORMAT_ETC2_SIGNED_RG11_EAC)
+ etc2_unpack_signed_rg11(dst_row, dst_stride,
+ src_row, src_stride,
+ src_width, src_height);
+ else if (format == MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1)
+ etc2_unpack_rgb8_punchthrough_alpha1(dst_row, dst_stride,
+ src_row, src_stride,
+ src_width, src_height);
+ else if (format == MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1)
+ etc2_unpack_srgb8_punchthrough_alpha1(dst_row, dst_stride,
+ src_row, src_stride,
+ src_width, src_height);
+}
diff --git a/mesalib/src/mesa/main/texcompress_etc.h b/mesalib/src/mesa/main/texcompress_etc.h
index 411e1540d..5e086d4e7 100644
--- a/mesalib/src/mesa/main/texcompress_etc.h
+++ b/mesalib/src/mesa/main/texcompress_etc.h
@@ -34,16 +34,93 @@ struct swrast_texture_image;
GLboolean
_mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS);
+GLboolean
+_mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS);
+
+GLboolean
+_mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS);
+
+GLboolean
+_mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS);
+
+GLboolean
+_mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS);
+
+GLboolean
+_mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS);
+
+GLboolean
+_mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS);
+
+GLboolean
+_mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS);
+
+GLboolean
+_mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS);
+
+GLboolean
+_mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS);
+
+GLboolean
+_mesa_texstore_etc2_srgb8_punchthrough_alpha1(TEXSTORE_PARAMS);
+
void
_mesa_fetch_texel_2d_f_etc1_rgb8(const struct swrast_texture_image *texImage,
GLint i, GLint j, GLint k, GLfloat *texel);
+void
+_mesa_fetch_texel_2d_f_etc2_rgb8(const struct swrast_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel);
+void
+_mesa_fetch_texel_2d_f_etc2_srgb8(const struct swrast_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel);
void
+_mesa_fetch_texel_2d_f_etc2_rgba8_eac(const struct swrast_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel);
+void
+_mesa_fetch_texel_2d_f_etc2_srgb8_alpha8_eac(const struct
+ swrast_texture_image *texImage,
+ GLint i, GLint j,
+ GLint k, GLfloat *texel);
+void
+_mesa_fetch_texel_2d_f_etc2_r11_eac(const struct swrast_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel);
+void
+_mesa_fetch_texel_2d_f_etc2_rg11_eac(const struct swrast_texture_image *texImage,
+ GLint i, GLint j, GLint k, GLfloat *texel);
+void
+_mesa_fetch_texel_2d_f_etc2_signed_r11_eac(const struct
+ swrast_texture_image *texImage,
+ GLint i, GLint j,
+ GLint k, GLfloat *texel);
+void
+_mesa_fetch_texel_2d_f_etc2_signed_rg11_eac(const struct
+ swrast_texture_image *texImage,
+ GLint i, GLint j,
+ GLint k, GLfloat *texel);
+void
+_mesa_fetch_texel_2d_f_etc2_rgb8_punchthrough_alpha1(
+ const struct swrast_texture_image *texImage,
+ GLint i, GLint j,
+ GLint k, GLfloat *texel);
+void
+_mesa_fetch_texel_2d_f_etc2_srgb8_punchthrough_alpha1(
+ const struct swrast_texture_image *texImage,
+ GLint i, GLint j,
+ GLint k, GLfloat *texel);
+void
_mesa_etc1_unpack_rgba8888(uint8_t *dst_row,
unsigned dst_stride,
const uint8_t *src_row,
unsigned src_stride,
unsigned src_width,
unsigned src_height);
-
+void
+_mesa_unpack_etc2_format(uint8_t *dst_row,
+ unsigned dst_stride,
+ const uint8_t *src_row,
+ unsigned src_stride,
+ unsigned src_width,
+ unsigned src_height,
+ gl_format format);
#endif
diff --git a/mesalib/src/mesa/main/texcompress_s3tc.c b/mesalib/src/mesa/main/texcompress_s3tc.c
index da7725964..476b998e0 100644
--- a/mesalib/src/mesa/main/texcompress_s3tc.c
+++ b/mesalib/src/mesa/main/texcompress_s3tc.c
@@ -45,6 +45,7 @@
#include "texcompress_s3tc.h"
#include "texstore.h"
#include "swrast/s_context.h"
+#include "format_unpack.h"
#if defined(_WIN32) || defined(WIN32)
@@ -57,33 +58,6 @@
#define DXTN_LIBNAME "libtxc_dxtn.so"
#endif
-/**
- * Convert an 8-bit sRGB value from non-linear space to a
- * linear RGB value in [0, 1].
- * Implemented with a 256-entry lookup table.
- */
-static inline GLfloat
-nonlinear_to_linear(GLubyte cs8)
-{
- static GLfloat table[256];
- static GLboolean tableReady = GL_FALSE;
- if (!tableReady) {
- /* compute lookup table now */
- GLuint i;
- for (i = 0; i < 256; i++) {
- const GLfloat cs = UBYTE_TO_FLOAT(i);
- if (cs <= 0.04045) {
- table[i] = cs / 12.92f;
- }
- else {
- table[i] = (GLfloat) pow((cs + 0.055) / 1.055, 2.4);
- }
- }
- tableReady = GL_TRUE;
- }
- return table[cs8];
-}
-
typedef void (*dxtFetchTexelFuncExt)( GLint srcRowstride, GLubyte *pixdata, GLint col, GLint row, GLvoid *texelOut );
static dxtFetchTexelFuncExt fetch_ext_rgb_dxt1 = NULL;
@@ -476,9 +450,9 @@ _mesa_fetch_texel_srgb_dxt1(const struct swrast_texture_image *texImage,
/* just sample as GLubyte and convert to float here */
GLubyte rgba[4];
fetch_texel_2d_rgb_dxt1(texImage, i, j, k, rgba);
- texel[RCOMP] = nonlinear_to_linear(rgba[RCOMP]);
- texel[GCOMP] = nonlinear_to_linear(rgba[GCOMP]);
- texel[BCOMP] = nonlinear_to_linear(rgba[BCOMP]);
+ texel[RCOMP] = _mesa_nonlinear_to_linear(rgba[RCOMP]);
+ texel[GCOMP] = _mesa_nonlinear_to_linear(rgba[GCOMP]);
+ texel[BCOMP] = _mesa_nonlinear_to_linear(rgba[BCOMP]);
texel[ACOMP] = UBYTE_TO_FLOAT(rgba[ACOMP]);
}
@@ -489,9 +463,9 @@ _mesa_fetch_texel_srgba_dxt1(const struct swrast_texture_image *texImage,
/* just sample as GLubyte and convert to float here */
GLubyte rgba[4];
fetch_texel_2d_rgba_dxt1(texImage, i, j, k, rgba);
- texel[RCOMP] = nonlinear_to_linear(rgba[RCOMP]);
- texel[GCOMP] = nonlinear_to_linear(rgba[GCOMP]);
- texel[BCOMP] = nonlinear_to_linear(rgba[BCOMP]);
+ texel[RCOMP] = _mesa_nonlinear_to_linear(rgba[RCOMP]);
+ texel[GCOMP] = _mesa_nonlinear_to_linear(rgba[GCOMP]);
+ texel[BCOMP] = _mesa_nonlinear_to_linear(rgba[BCOMP]);
texel[ACOMP] = UBYTE_TO_FLOAT(rgba[ACOMP]);
}
@@ -502,9 +476,9 @@ _mesa_fetch_texel_srgba_dxt3(const struct swrast_texture_image *texImage,
/* just sample as GLubyte and convert to float here */
GLubyte rgba[4];
fetch_texel_2d_rgba_dxt3(texImage, i, j, k, rgba);
- texel[RCOMP] = nonlinear_to_linear(rgba[RCOMP]);
- texel[GCOMP] = nonlinear_to_linear(rgba[GCOMP]);
- texel[BCOMP] = nonlinear_to_linear(rgba[BCOMP]);
+ texel[RCOMP] = _mesa_nonlinear_to_linear(rgba[RCOMP]);
+ texel[GCOMP] = _mesa_nonlinear_to_linear(rgba[GCOMP]);
+ texel[BCOMP] = _mesa_nonlinear_to_linear(rgba[BCOMP]);
texel[ACOMP] = UBYTE_TO_FLOAT(rgba[ACOMP]);
}
@@ -515,8 +489,8 @@ _mesa_fetch_texel_srgba_dxt5(const struct swrast_texture_image *texImage,
/* just sample as GLubyte and convert to float here */
GLubyte rgba[4];
fetch_texel_2d_rgba_dxt5(texImage, i, j, k, rgba);
- texel[RCOMP] = nonlinear_to_linear(rgba[RCOMP]);
- texel[GCOMP] = nonlinear_to_linear(rgba[GCOMP]);
- texel[BCOMP] = nonlinear_to_linear(rgba[BCOMP]);
+ texel[RCOMP] = _mesa_nonlinear_to_linear(rgba[RCOMP]);
+ texel[GCOMP] = _mesa_nonlinear_to_linear(rgba[GCOMP]);
+ texel[BCOMP] = _mesa_nonlinear_to_linear(rgba[BCOMP]);
texel[ACOMP] = UBYTE_TO_FLOAT(rgba[ACOMP]);
}
diff --git a/mesalib/src/mesa/main/texformat.c b/mesalib/src/mesa/main/texformat.c
index f0bc7fdb9..b3ffc6c51 100644
--- a/mesalib/src/mesa/main/texformat.c
+++ b/mesalib/src/mesa/main/texformat.c
@@ -972,6 +972,43 @@ _mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
}
}
+ if (_mesa_is_gles3(ctx)) {
+ switch (internalFormat) {
+ case GL_COMPRESSED_RGB8_ETC2:
+ RETURN_IF_SUPPORTED(MESA_FORMAT_ETC2_RGB8);
+ break;
+ case GL_COMPRESSED_SRGB8_ETC2:
+ RETURN_IF_SUPPORTED(MESA_FORMAT_ETC2_SRGB8);
+ break;
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ RETURN_IF_SUPPORTED(MESA_FORMAT_ETC2_RGBA8_EAC);
+ break;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ RETURN_IF_SUPPORTED(MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC);
+ break;
+ case GL_COMPRESSED_R11_EAC:
+ RETURN_IF_SUPPORTED(MESA_FORMAT_ETC2_R11_EAC);
+ break;
+ case GL_COMPRESSED_RG11_EAC:
+ RETURN_IF_SUPPORTED(MESA_FORMAT_ETC2_RG11_EAC);
+ break;
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ RETURN_IF_SUPPORTED(MESA_FORMAT_ETC2_SIGNED_R11_EAC);
+ break;
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ RETURN_IF_SUPPORTED(MESA_FORMAT_ETC2_SIGNED_RG11_EAC);
+ break;
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ RETURN_IF_SUPPORTED(MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1);
+ break;
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ RETURN_IF_SUPPORTED(MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1);
+ break;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
_mesa_problem(ctx, "unexpected format %s in _mesa_choose_tex_format()",
_mesa_lookup_enum_by_nr(internalFormat));
return MESA_FORMAT_NONE;
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index a720c38b8..83b7e1488 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -529,6 +529,27 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
}
}
+ if (_mesa_is_gles3(ctx)) {
+ switch (internalFormat) {
+ case GL_COMPRESSED_RGB8_ETC2:
+ case GL_COMPRESSED_SRGB8_ETC2:
+ return GL_RGB;
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ return GL_RGBA;
+ case GL_COMPRESSED_R11_EAC:
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ return GL_RED;
+ case GL_COMPRESSED_RG11_EAC:
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ return GL_RG;
+ default:
+ ; /* fallthrough */
+ }
+ }
+
if (ctx->API == API_OPENGLES) {
switch (internalFormat) {
case GL_PALETTE4_RGB8_OES:
diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c
index 1c088106f..26c5b6703 100644
--- a/mesalib/src/mesa/main/texstore.c
+++ b/mesalib/src/mesa/main/texstore.c
@@ -4124,6 +4124,18 @@ _mesa_get_texstore_func(gl_format format)
table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2;
table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2;
table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8;
+ table[MESA_FORMAT_ETC2_RGB8] = _mesa_texstore_etc2_rgb8;
+ table[MESA_FORMAT_ETC2_SRGB8] = _mesa_texstore_etc2_srgb8;
+ table[MESA_FORMAT_ETC2_RGBA8_EAC] = _mesa_texstore_etc2_rgba8_eac;
+ table[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = _mesa_texstore_etc2_srgb8_alpha8_eac;
+ table[MESA_FORMAT_ETC2_R11_EAC] = _mesa_texstore_etc2_r11_eac;
+ table[MESA_FORMAT_ETC2_RG11_EAC] = _mesa_texstore_etc2_rg11_eac;
+ table[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = _mesa_texstore_etc2_signed_r11_eac;
+ table[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = _mesa_texstore_etc2_signed_rg11_eac;
+ table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] =
+ _mesa_texstore_etc2_rgb8_punchthrough_alpha1;
+ table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] =
+ _mesa_texstore_etc2_srgb8_punchthrough_alpha1;
table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8;
table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8;
table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88;
diff --git a/mesalib/src/mesa/program/Android.mk b/mesalib/src/mesa/program/Android.mk
index 712506129..51362e0eb 100644
--- a/mesalib/src/mesa/program/Android.mk
+++ b/mesalib/src/mesa/program/Android.mk
@@ -65,6 +65,9 @@ LOCAL_GENERATED_SOURCES := \
$(intermediates)/program/program_parse.tab.c: $(LOCAL_PATH)/program_parse.y
$(mesa_local-y-to-c-and-h)
+$(intermediates)/program/program_parse.tab.h: $(intermediates)/program/program_parse.tab.c
+ @
+
$(intermediates)/program/lex.yy.c: $(LOCAL_PATH)/program_lexer.l
$(local-l-to-c)
diff --git a/mesalib/src/mesa/program/hash_table.c b/mesalib/src/mesa/program/prog_hash_table.c
index f45ed46af..f45ed46af 100644
--- a/mesalib/src/mesa/program/hash_table.c
+++ b/mesalib/src/mesa/program/prog_hash_table.c
diff --git a/mesalib/src/mesa/sources.mak b/mesalib/src/mesa/sources.mak
index 54e58c21b..8cde2c4cf 100644
--- a/mesalib/src/mesa/sources.mak
+++ b/mesalib/src/mesa/sources.mak
@@ -76,6 +76,7 @@ MAIN_FILES = \
$(SRCDIR)main/renderbuffer.c \
$(SRCDIR)main/samplerobj.c \
$(SRCDIR)main/scissor.c \
+ $(SRCDIR)main/set.c \
$(SRCDIR)main/shaderapi.c \
$(SRCDIR)main/shaderobj.c \
$(SRCDIR)main/shader_query.cpp \
@@ -247,7 +248,7 @@ STATETRACKER_FILES = \
PROGRAM_FILES = \
$(SRCDIR)program/arbprogparse.c \
- $(SRCDIR)program/hash_table.c \
+ $(SRCDIR)program/prog_hash_table.c \
$(SRCDIR)program/ir_to_mesa.cpp \
$(SRCDIR)program/program.c \
$(SRCDIR)program/program_parse_extra.c \
diff --git a/mesalib/src/mesa/state_tracker/st_atom.c b/mesalib/src/mesa/state_tracker/st_atom.c
index 102fee93b..32bcc266a 100644
--- a/mesalib/src/mesa/state_tracker/st_atom.c
+++ b/mesalib/src/mesa/state_tracker/st_atom.c
@@ -64,6 +64,8 @@ static const struct st_tracked_state *atoms[] =
&st_update_vs_constants,
&st_update_gs_constants,
&st_update_fs_constants,
+ &st_bind_vs_ubos,
+ &st_bind_fs_ubos,
&st_update_pixel_transfer,
/* this must be done after the vertex program update */
diff --git a/mesalib/src/mesa/state_tracker/st_atom.h b/mesalib/src/mesa/state_tracker/st_atom.h
index 6c7d09fba..101a3a6bd 100644
--- a/mesalib/src/mesa/state_tracker/st_atom.h
+++ b/mesalib/src/mesa/state_tracker/st_atom.h
@@ -67,6 +67,8 @@ extern const struct st_tracked_state st_finalize_textures;
extern const struct st_tracked_state st_update_fs_constants;
extern const struct st_tracked_state st_update_gs_constants;
extern const struct st_tracked_state st_update_vs_constants;
+extern const struct st_tracked_state st_bind_fs_ubos;
+extern const struct st_tracked_state st_bind_vs_ubos;
extern const struct st_tracked_state st_update_pixel_transfer;
diff --git a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
index 580393e60..961fb28a9 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
@@ -45,7 +45,7 @@
#include "st_atom.h"
#include "st_atom_constbuf.h"
#include "st_program.h"
-
+#include "st_cb_bufferobjects.h"
/**
* Pass the given program parameters to the graphics pipe as a
@@ -175,3 +175,69 @@ const struct st_tracked_state st_update_gs_constants = {
},
update_gs_constants /* update */
};
+
+static void st_bind_ubos(struct st_context *st,
+ struct gl_shader *shader,
+ unsigned shader_type)
+{
+ unsigned i;
+ struct pipe_constant_buffer cb = { 0 };
+
+ if (!shader)
+ return;
+
+ for (i = 0; i < shader->NumUniformBlocks; i++) {
+ struct gl_uniform_buffer_binding *binding;
+ struct st_buffer_object *st_obj;
+
+ binding = &st->ctx->UniformBufferBindings[shader->UniformBlocks[i].Binding];
+ st_obj = st_buffer_object(binding->BufferObject);
+ pipe_resource_reference(&cb.buffer, st_obj->buffer);
+
+ cb.buffer_size = st_obj->buffer->width0 - binding->Offset;
+
+ st->pipe->set_constant_buffer(st->pipe, shader_type, 1 + i, &cb);
+ pipe_resource_reference(&cb.buffer, NULL);
+ }
+}
+
+static void bind_vs_ubos(struct st_context *st)
+{
+ struct gl_shader_program *prog = st->ctx->Shader.CurrentVertexProgram;
+
+ if (!prog)
+ return;
+
+ st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_VERTEX], PIPE_SHADER_VERTEX);
+}
+
+const struct st_tracked_state st_bind_vs_ubos = {
+ "st_bind_vs_ubos",
+ {
+ (_NEW_PROGRAM | _NEW_BUFFER_OBJECT),
+ ST_NEW_VERTEX_PROGRAM,
+ },
+ bind_vs_ubos
+};
+
+static void bind_fs_ubos(struct st_context *st)
+{
+ struct gl_shader_program *prog = st->ctx->Shader.CurrentFragmentProgram;
+
+ if (!prog)
+ return;
+
+ st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_FRAGMENT], PIPE_SHADER_FRAGMENT);
+
+}
+
+const struct st_tracked_state st_bind_fs_ubos = {
+ "st_bind_fs_ubos",
+ {
+ (_NEW_PROGRAM | _NEW_BUFFER_OBJECT),
+ ST_NEW_FRAGMENT_PROGRAM,
+ },
+ bind_fs_ubos
+};
+
+
diff --git a/mesalib/src/mesa/state_tracker/st_atom_texture.c b/mesalib/src/mesa/state_tracker/st_atom_texture.c
index df05e83c2..dba1d829c 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_texture.c
@@ -215,13 +215,19 @@ update_single_texture(struct st_context *st,
/* Determine the format of the texture sampler view */
st_view_format = stObj->pt->format;
- {
- const struct st_texture_image *firstImage =
- st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
- const gl_format texFormat = firstImage->base.TexFormat;
- enum pipe_format firstImageFormat =
- st_mesa_format_to_pipe_format(texFormat);
+ {
+ gl_format texFormat;
+ enum pipe_format firstImageFormat;
+
+ if (texObj->Target == GL_TEXTURE_BUFFER) {
+ texFormat = stObj->base._BufferObjectFormat;
+ } else {
+ const struct st_texture_image *firstImage =
+ st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
+ texFormat = firstImage->base.TexFormat;
+ }
+ firstImageFormat = st_mesa_format_to_pipe_format(texFormat);
if ((samp->sRGBDecode == GL_SKIP_DECODE_EXT) &&
(_mesa_get_format_color_encoding(texFormat) == GL_SRGB)) {
/* Don't do sRGB->RGB conversion. Interpret the texture data as
diff --git a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c
index ac38128df..cf291c1c1 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -195,9 +195,15 @@ st_bufferobj_data(struct gl_context *ctx,
case GL_ELEMENT_ARRAY_BUFFER_ARB:
bind = PIPE_BIND_INDEX_BUFFER;
break;
+ case GL_TEXTURE_BUFFER:
+ bind = PIPE_BIND_SAMPLER_VIEW;
+ break;
case GL_TRANSFORM_FEEDBACK_BUFFER:
bind = PIPE_BIND_STREAM_OUTPUT;
break;
+ case GL_UNIFORM_BUFFER:
+ bind = PIPE_BIND_CONSTANT_BUFFER;
+ break;
default:
bind = 0;
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c
index f06814f9c..ae069eb2c 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c
@@ -48,6 +48,7 @@
#include "state_tracker/st_cb_fbo.h"
#include "state_tracker/st_cb_flush.h"
#include "state_tracker/st_cb_texture.h"
+#include "state_tracker/st_cb_bufferobjects.h"
#include "state_tracker/st_format.h"
#include "state_tracker/st_texture.h"
#include "state_tracker/st_gen_mipmap.h"
@@ -59,6 +60,7 @@
#include "pipe/p_shader_tokens.h"
#include "util/u_tile.h"
#include "util/u_blit.h"
+#include "util/u_blitter.h"
#include "util/u_format.h"
#include "util/u_surface.h"
#include "util/u_sampler.h"
@@ -922,12 +924,12 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
enum pipe_format dest_format, src_format;
- GLboolean matching_base_formats;
- GLuint color_writemask, zs_writemask, sample_count;
+ GLuint color_writemask;
struct pipe_surface *dest_surface = NULL;
GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
struct pipe_surface surf_tmpl;
- unsigned int dst_usage;
+ unsigned dst_usage;
+ unsigned blit_mask;
GLint srcY0, srcY1;
/* make sure finalize_textures has been called?
@@ -939,12 +941,6 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
return;
}
- sample_count = strb->surface->texture->nr_samples;
- /* I believe this would be legal, presumably would need to do a resolve
- for color, and for depth/stencil spec says to just use one of the
- depth/stencil samples per pixel? Need some transfer clarifications. */
- assert(sample_count < 2);
-
assert(strb);
assert(strb->surface);
assert(stImage->pt);
@@ -952,22 +948,24 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
src_format = strb->surface->format;
dest_format = stImage->pt->format;
- /*
- * Determine if the src framebuffer and dest texture have the same
- * base format. We need this to detect a case such as the framebuffer
- * being GL_RGBA but the texture being GL_RGB. If the actual hardware
- * texture format stores RGBA we need to set A=1 (overriding the
- * framebuffer's alpha values). We can't do that with the blit or
- * textured-quad paths.
- */
- matching_base_formats =
- (_mesa_get_format_base_format(strb->Base.Format) ==
- _mesa_get_format_base_format(texImage->TexFormat));
+ if (do_flip) {
+ srcY1 = strb->Base.Height - srcY - height;
+ srcY0 = srcY1 + height;
+ }
+ else {
+ srcY0 = srcY;
+ srcY1 = srcY0 + height;
+ }
if (ctx->_ImageTransferState) {
goto fallback;
}
+ /* Compressed and subsampled textures aren't supported for blitting. */
+ if (!util_format_is_plain(dest_format)) {
+ goto fallback;
+ }
+
if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
/* 1D arrays might be thought of as 2D images but the actual layout
* might not be that way. At some points, we convert OpenGL's 1D
@@ -978,53 +976,112 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
goto fallback;
}
- if (matching_base_formats &&
- src_format == dest_format &&
- !do_flip) {
- /* use surface_copy() / blit */
- struct pipe_box src_box;
- unsigned dstLevel;
+ /* Set the blit writemask. */
+ switch (texBaseFormat) {
+ case GL_DEPTH_STENCIL:
+ switch (strb->Base._BaseFormat) {
+ case GL_DEPTH_STENCIL:
+ blit_mask = PIPE_MASK_ZS;
+ break;
+ case GL_DEPTH_COMPONENT:
+ blit_mask = PIPE_MASK_Z;
+ break;
+ case GL_STENCIL_INDEX:
+ blit_mask = PIPE_MASK_S;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+ dst_usage = PIPE_BIND_DEPTH_STENCIL;
+ break;
+
+ case GL_DEPTH_COMPONENT:
+ blit_mask = PIPE_MASK_Z;
+ dst_usage = PIPE_BIND_DEPTH_STENCIL;
+ break;
- u_box_2d_zslice(srcX, srcY, strb->surface->u.tex.first_layer,
- width, height, &src_box);
+ default:
+ /* Colorbuffers.
+ *
+ * Determine if the src framebuffer and dest texture have the same
+ * base format. We need this to detect a case such as the framebuffer
+ * being GL_RGBA but the texture being GL_RGB. If the actual hardware
+ * texture format stores RGBA we need to set A=1 (overriding the
+ * framebuffer's alpha values).
+ *
+ * XXX util_blit_pixels doesn't support MSAA resolve, so always use
+ * pipe->blit
+ */
+ if (texBaseFormat == strb->Base._BaseFormat ||
+ strb->texture->nr_samples > 1) {
+ blit_mask = PIPE_MASK_RGBA;
+ }
+ else {
+ blit_mask = 0;
+ }
+ dst_usage = PIPE_BIND_RENDER_TARGET;
+ }
+ /* Blit the texture.
+ * This supports flipping, format conversions, and downsampling.
+ */
+ if (blit_mask) {
/* If stImage->pt is an independent image (not a pointer into a full
* mipmap) stImage->pt.last_level will be zero and we need to use that
* as the dest level.
*/
- dstLevel = MIN2(stImage->base.Level, stImage->pt->last_level);
-
- /* for resource_copy_region(), y=0=top, always */
- pipe->resource_copy_region(pipe,
- /* dest */
- stImage->pt,
- dstLevel,
- destX, destY, destZ + stImage->base.Face,
- /* src */
- strb->texture,
- strb->surface->u.tex.level,
- &src_box);
- return;
- }
+ unsigned dstLevel = MIN2(stImage->base.Level, stImage->pt->last_level);
+ struct pipe_blit_info blit;
+
+ memset(&blit, 0, sizeof(blit));
+ blit.src.resource = strb->texture;
+ blit.src.format = src_format;
+ blit.src.level = strb->surface->u.tex.level;
+ blit.src.box.x = srcX;
+ blit.src.box.y = srcY0;
+ blit.src.box.z = strb->surface->u.tex.first_layer;
+ blit.src.box.width = width;
+ blit.src.box.height = srcY1 - srcY0;
+ blit.src.box.depth = 1;
+ blit.dst.resource = stImage->pt;
+ blit.dst.format = dest_format;
+ blit.dst.level = dstLevel;
+ blit.dst.box.x = destX;
+ blit.dst.box.y = destY;
+ blit.dst.box.z = stImage->base.Face + destZ;
+ blit.dst.box.width = width;
+ blit.dst.box.height = height;
+ blit.dst.box.depth = 1;
+ blit.mask = blit_mask;
+ blit.filter = PIPE_TEX_FILTER_NEAREST;
+
+ /* try resource_copy_region in case the format is not supported
+ * for rendering */
+ if (util_try_blit_via_copy_region(pipe, &blit)) {
+ return; /* done */
+ }
- if (texBaseFormat == GL_DEPTH_STENCIL) {
- goto fallback;
- }
+ /* check the format support */
+ if (!screen->is_format_supported(screen, src_format,
+ PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW) ||
+ !screen->is_format_supported(screen, dest_format,
+ PIPE_TEXTURE_2D, 0,
+ dst_usage)) {
+ goto fallback;
+ }
- if (texBaseFormat == GL_DEPTH_COMPONENT) {
- color_writemask = 0;
- zs_writemask = BLIT_WRITEMASK_Z;
- dst_usage = PIPE_BIND_DEPTH_STENCIL;
- }
- else {
- color_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage);
- zs_writemask = 0;
- dst_usage = PIPE_BIND_RENDER_TARGET;
+ pipe->blit(pipe, &blit);
+ return;
}
- if ((!color_writemask && !zs_writemask) ||
+ /* try u_blit */
+ color_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage);
+
+ if (!color_writemask ||
!screen->is_format_supported(screen, src_format,
- PIPE_TEXTURE_2D, sample_count,
+ PIPE_TEXTURE_2D, 0,
PIPE_BIND_SAMPLER_VIEW) ||
!screen->is_format_supported(screen, dest_format,
PIPE_TEXTURE_2D, 0,
@@ -1032,15 +1089,6 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
goto fallback;
}
- if (do_flip) {
- srcY1 = strb->Base.Height - srcY - height;
- srcY0 = srcY1 + height;
- }
- else {
- srcY0 = srcY;
- srcY1 = srcY0 + height;
- }
-
/* Disable conditional rendering. */
if (st->render_condition) {
pipe->render_condition(pipe, NULL, 0);
@@ -1065,7 +1113,7 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
destX, destY,
destX + width, destY + height,
0.0, PIPE_TEX_MIPFILTER_NEAREST,
- color_writemask, zs_writemask);
+ color_writemask, 0);
pipe_surface_reference(&dest_surface, NULL);
/* Restore conditional rendering state. */
@@ -1182,6 +1230,20 @@ st_finalize_texture(struct gl_context *ctx,
stObj->lastLevel = stObj->base._MaxLevel;
}
+ if (tObj->Target == GL_TEXTURE_BUFFER) {
+ struct st_buffer_object *st_obj = st_buffer_object(tObj->BufferObject);
+
+ if (st_obj->buffer != stObj->pt) {
+ pipe_resource_reference(&stObj->pt, st_obj->buffer);
+ pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
+ stObj->width0 = stObj->pt->width0 / _mesa_get_format_bytes(tObj->_BufferObjectFormat);
+ stObj->height0 = 1;
+ stObj->depth0 = 1;
+ }
+ return GL_TRUE;
+
+ }
+
firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
assert(firstImage);
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index 62a736bb6..93ef7a91c 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -70,6 +70,8 @@ void st_init_limits(struct st_context *st)
struct pipe_screen *screen = st->pipe->screen;
struct gl_constants *c = &st->ctx->Const;
gl_shader_type sh;
+ boolean can_ubo = TRUE;
+ int max_const_buffers;
c->MaxTextureLevels
= _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
@@ -218,6 +220,17 @@ void st_init_limits(struct st_context *st)
options->EmitNoIndirectUniform = !screen->get_shader_param(screen, sh,
PIPE_SHADER_CAP_INDIRECT_CONST_ADDR);
+ if (pc->MaxNativeInstructions) {
+ if (options->EmitNoIndirectUniform)
+ can_ubo = FALSE;
+
+ max_const_buffers = screen->get_shader_param(screen, sh,
+ PIPE_SHADER_CAP_MAX_CONST_BUFFERS);
+ /* we need 13 buffers - 1 constant, 12 UBO */
+ if (max_const_buffers < 13)
+ can_ubo = FALSE;
+ }
+
if (options->EmitNoLoops)
options->MaxUnrollIterations = MIN2(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536);
else
@@ -251,6 +264,9 @@ void st_init_limits(struct st_context *st)
c->GLSLSkipStrictMaxVaryingLimitCheck =
screen->get_param(screen, PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS);
+
+ if (can_ubo)
+ st->ctx->Extensions.ARB_uniform_buffer_object = GL_TRUE;
}
@@ -553,7 +569,12 @@ void st_init_extensions(struct st_context *st)
/* Figure out GLSL support. */
glsl_feature_level = screen->get_param(screen, PIPE_CAP_GLSL_FEATURE_LEVEL);
- if (glsl_feature_level >= 130) {
+ if (glsl_feature_level >= 140) {
+ if (ctx->API == API_OPENGL_CORE)
+ ctx->Const.GLSLVersion = 140;
+ else
+ ctx->Const.GLSLVersion = 130;
+ } else if (glsl_feature_level >= 130) {
ctx->Const.GLSLVersion = 130;
} else {
ctx->Const.GLSLVersion = 120;
@@ -643,4 +664,6 @@ void st_init_extensions(struct st_context *st)
if (ctx->Const.MinMapBufferAlignment >= 64) {
ctx->Extensions.ARB_map_buffer_alignment = GL_TRUE;
}
+ if (screen->get_param(screen, PIPE_CAP_TEXTURE_BUFFER_OBJECTS))
+ ctx->Extensions.ARB_texture_buffer_object = GL_TRUE;
}
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index c030a6b37..a4df4e5fa 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -107,6 +107,7 @@ public:
else
this->swizzle = SWIZZLE_XYZW;
this->negate = 0;
+ this->index2D = 0;
this->type = type ? type->base_type : GLSL_TYPE_ERROR;
this->reladdr = NULL;
}
@@ -116,6 +117,18 @@ public:
this->type = type;
this->file = file;
this->index = index;
+ this->index2D = 0;
+ this->swizzle = SWIZZLE_XYZW;
+ this->negate = 0;
+ this->reladdr = NULL;
+ }
+
+ st_src_reg(gl_register_file file, int index, int type, int index2D)
+ {
+ this->type = type;
+ this->file = file;
+ this->index = index;
+ this->index2D = index2D;
this->swizzle = SWIZZLE_XYZW;
this->negate = 0;
this->reladdr = NULL;
@@ -126,6 +139,7 @@ public:
this->type = GLSL_TYPE_ERROR;
this->file = PROGRAM_UNDEFINED;
this->index = 0;
+ this->index2D = 0;
this->swizzle = 0;
this->negate = 0;
this->reladdr = NULL;
@@ -135,6 +149,7 @@ public:
gl_register_file file; /**< PROGRAM_* from Mesa */
int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
+ int index2D;
GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
int negate; /**< NEGATE_XYZW mask from mesa */
int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
@@ -183,6 +198,7 @@ st_src_reg::st_src_reg(st_dst_reg reg)
this->swizzle = SWIZZLE_XYZW;
this->negate = 0;
this->reladdr = reg.reladdr;
+ this->index2D = 0;
}
st_dst_reg::st_dst_reg(st_src_reg reg)
@@ -1873,10 +1889,46 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
assert(!"GLSL 1.30 features unsupported");
break;
- case ir_binop_ubo_load:
- assert(!"not yet supported");
- break;
+ case ir_binop_ubo_load: {
+ ir_constant *uniform_block = ir->operands[0]->as_constant();
+ ir_constant *const_offset_ir = ir->operands[1]->as_constant();
+ unsigned const_offset = const_offset_ir ? const_offset_ir->value.u[0] : 0;
+ st_src_reg index_reg = get_temp(glsl_type::uint_type);
+ st_src_reg cbuf;
+
+ cbuf.type = glsl_type::vec4_type->base_type;
+ cbuf.file = PROGRAM_CONSTANT;
+ cbuf.index = 0;
+ cbuf.index2D = uniform_block->value.u[0] + 1;
+ cbuf.reladdr = NULL;
+ cbuf.negate = 0;
+
+ assert(ir->type->is_vector() || ir->type->is_scalar());
+
+ if (const_offset_ir) {
+ index_reg = st_src_reg_for_int(const_offset / 16);
+ } else {
+ emit(ir, TGSI_OPCODE_USHR, st_dst_reg(index_reg), op[1], st_src_reg_for_int(4));
+ }
+ cbuf.swizzle = swizzle_for_size(ir->type->vector_elements);
+ cbuf.swizzle += MAKE_SWIZZLE4(const_offset % 16 / 4,
+ const_offset % 16 / 4,
+ const_offset % 16 / 4,
+ const_offset % 16 / 4);
+
+ cbuf.reladdr = ralloc(mem_ctx, st_src_reg);
+ memcpy(cbuf.reladdr, &index_reg, sizeof(index_reg));
+
+ if (ir->type->base_type == GLSL_TYPE_BOOL) {
+ emit(ir, TGSI_OPCODE_USNE, result_dst, cbuf, st_src_reg_for_int(0));
+ result_src.negate = 1;
+ emit(ir, TGSI_OPCODE_UCMP, result_dst, result_src, st_src_reg_for_int(~0), st_src_reg_for_int(0));
+ } else {
+ emit(ir, TGSI_OPCODE_MOV, result_dst, cbuf);
+ }
+ break;
+ }
case ir_quadop_vector:
/* This operation should have already been handled.
*/
@@ -2776,7 +2828,7 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
inst->tex_target = TEXTURE_RECT_INDEX;
break;
case GLSL_SAMPLER_DIM_BUF:
- assert(!"FINISHME: Implement ARB_texture_buffer_object");
+ inst->tex_target = TEXTURE_BUFFER_INDEX;
break;
case GLSL_SAMPLER_DIM_EXTERNAL:
inst->tex_target = TEXTURE_EXTERNAL_INDEX;
@@ -4061,7 +4113,7 @@ dst_register(struct st_translate *t,
static struct ureg_src
src_register(struct st_translate *t,
gl_register_file file,
- GLint index)
+ GLint index, GLint index2D)
{
switch(file) {
case PROGRAM_UNDEFINED:
@@ -4081,7 +4133,13 @@ src_register(struct st_translate *t,
return t->constants[index];
case PROGRAM_STATE_VAR:
case PROGRAM_CONSTANT: /* ie, immediate */
- if (index < 0)
+ if (index2D) {
+ struct ureg_src src;
+ src = ureg_src_register(TGSI_FILE_CONSTANT, 0);
+ src.Dimension = 1;
+ src.DimensionIndex = index2D;
+ return src;
+ } else if (index < 0)
return ureg_DECL_constant(t->ureg, 0);
else
return t->constants[index];
@@ -4160,7 +4218,7 @@ translate_dst(struct st_translate *t,
static struct ureg_src
translate_src(struct st_translate *t, const st_src_reg *src_reg)
{
- struct ureg_src src = src_register(t, src_reg->file, src_reg->index);
+ struct ureg_src src = src_register(t, src_reg->file, src_reg->index, src_reg->index2D);
src = ureg_swizzle(src,
GET_SWZ(src_reg->swizzle, 0) & 0x3,
@@ -4202,14 +4260,17 @@ translate_tex_offset(struct st_translate *t,
const struct tgsi_texture_offset *in_offset)
{
struct tgsi_texture_offset offset;
+ struct ureg_src imm_src;
assert(in_offset->File == PROGRAM_IMMEDIATE);
+ imm_src = t->immediates[in_offset->Index];
+ offset.File = imm_src.File;
+ offset.Index = imm_src.Index;
+ offset.SwizzleX = imm_src.SwizzleX;
+ offset.SwizzleY = imm_src.SwizzleY;
+ offset.SwizzleZ = imm_src.SwizzleZ;
offset.File = TGSI_FILE_IMMEDIATE;
- offset.Index = in_offset->Index;
- offset.SwizzleX = in_offset->SwizzleX;
- offset.SwizzleY = in_offset->SwizzleY;
- offset.SwizzleZ = in_offset->SwizzleZ;
offset.Padding = 0;
return offset;
@@ -4754,6 +4815,14 @@ st_translate_program(
}
}
}
+
+ if (program->shader_program) {
+ unsigned num_ubos = program->shader_program->NumUniformBlocks;
+
+ for (i = 0; i < num_ubos; i++) {
+ ureg_DECL_constant2D(t->ureg, 0, program->shader_program->UniformBlocks[i].UniformBufferSize / 4, i + 1);
+ }
+ }
/* Emit immediate values.
*/
@@ -5060,6 +5129,8 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
do_mat_op_to_vec(ir);
lower_instructions(ir, what_to_lower);
+ lower_ubo_reference(prog->_LinkedShaders[i], ir);
+
progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;
progress = do_common_optimization(ir, true, true,
@@ -5090,6 +5161,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
|| progress;
progress = do_vec_index_to_cond_assign(ir) || progress;
+
} while (progress);
validate_ir_tree(ir);
diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c
index 0b9add95e..b065db0ac 100644
--- a/mesalib/src/mesa/state_tracker/st_manager.c
+++ b/mesalib/src/mesa/state_tracker/st_manager.c
@@ -398,7 +398,7 @@ st_visual_to_context_mode(const struct st_visual *visual,
UTIL_FORMAT_COLORSPACE_RGB, 3);
}
- if (visual->samples) {
+ if (visual->samples > 1) {
mode->sampleBuffers = 1;
mode->samples = visual->samples;
}
@@ -789,7 +789,7 @@ st_manager_flush_frontbuffer(struct st_context *st)
/* never a dummy fb */
assert(&stfb->Base != _mesa_get_incomplete_framebuffer());
- stfb->iface->flush_front(stfb->iface, ST_ATTACHMENT_FRONT_LEFT);
+ stfb->iface->flush_front(&st->iface, stfb->iface, ST_ATTACHMENT_FRONT_LEFT);
}
/**
@@ -899,7 +899,7 @@ static const struct st_api st_gl_api = {
ST_PROFILE_OPENGL_ES2_MASK |
#endif
0,
- 0,
+ ST_API_FEATURE_MS_VISUALS_MASK,
st_api_destroy,
st_api_get_proc_address,
st_api_create_context,
diff --git a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 81a870f86..e326bcc70 100644
--- a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -269,6 +269,7 @@ st_translate_texture_target( GLuint textarget,
}
switch( textarget ) {
+ case TEXTURE_BUFFER_INDEX: return TGSI_TEXTURE_BUFFER;
case TEXTURE_1D_INDEX: return TGSI_TEXTURE_1D;
case TEXTURE_2D_INDEX: return TGSI_TEXTURE_2D;
case TEXTURE_3D_INDEX: return TGSI_TEXTURE_3D;
diff --git a/mesalib/src/mesa/swrast/s_texfetch.c b/mesalib/src/mesa/swrast/s_texfetch.c
index 7bfe3b941..86b01a0b3 100644
--- a/mesalib/src/mesa/swrast/s_texfetch.c
+++ b/mesalib/src/mesa/swrast/s_texfetch.c
@@ -1029,6 +1029,66 @@ texfetch_funcs[] =
NULL
},
{
+ MESA_FORMAT_ETC2_RGB8,
+ NULL,
+ _mesa_fetch_texel_2d_f_etc2_rgb8,
+ NULL
+ },
+ {
+ MESA_FORMAT_ETC2_SRGB8,
+ NULL,
+ _mesa_fetch_texel_2d_f_etc2_srgb8,
+ NULL
+ },
+ {
+ MESA_FORMAT_ETC2_RGBA8_EAC,
+ NULL,
+ _mesa_fetch_texel_2d_f_etc2_rgba8_eac,
+ NULL
+ },
+ {
+ MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC,
+ NULL,
+ _mesa_fetch_texel_2d_f_etc2_srgb8_alpha8_eac,
+ NULL
+ },
+ {
+ MESA_FORMAT_ETC2_R11_EAC,
+ NULL,
+ _mesa_fetch_texel_2d_f_etc2_r11_eac,
+ NULL
+ },
+ {
+ MESA_FORMAT_ETC2_RG11_EAC,
+ NULL,
+ _mesa_fetch_texel_2d_f_etc2_rg11_eac,
+ NULL
+ },
+ {
+ MESA_FORMAT_ETC2_SIGNED_R11_EAC,
+ NULL,
+ _mesa_fetch_texel_2d_f_etc2_signed_r11_eac,
+ NULL
+ },
+ {
+ MESA_FORMAT_ETC2_SIGNED_RG11_EAC,
+ NULL,
+ _mesa_fetch_texel_2d_f_etc2_signed_rg11_eac,
+ NULL
+ },
+ {
+ MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1,
+ NULL,
+ _mesa_fetch_texel_2d_f_etc2_rgb8_punchthrough_alpha1,
+ NULL
+ },
+ {
+ MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1,
+ NULL,
+ _mesa_fetch_texel_2d_f_etc2_srgb8_punchthrough_alpha1,
+ NULL
+ },
+ {
MESA_FORMAT_SIGNED_A8,
fetch_texel_1d_signed_a8,
fetch_texel_2d_signed_a8,
diff --git a/pixman/configure.ac b/pixman/configure.ac
index 45b709dcf..81f068d9c 100644
--- a/pixman/configure.ac
+++ b/pixman/configure.ac
@@ -860,7 +860,7 @@ AC_CACHE_VAL(ac_cv_tls, [
#error OpenBSD has broken __thread support
#endif
-int $kw test;], [], ac_cv_tls=$kw)
+int $kw test;], [], [ac_cv_tls=$kw; break])
done
])
AC_MSG_RESULT($ac_cv_tls)
diff --git a/pixman/demos/Makefile.am b/pixman/demos/Makefile.am
index f324f5f5b..3f2a3fad6 100644
--- a/pixman/demos/Makefile.am
+++ b/pixman/demos/Makefile.am
@@ -6,7 +6,8 @@ AM_LDFLAGS = $(OPENMP_CFLAGS)
LDADD = $(top_builddir)/pixman/libpixman-1.la -lm $(GTK_LIBS) $(PNG_LIBS)
INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman $(GTK_CFLAGS) $(PNG_CFLAGS)
-GTK_UTILS = gtk-utils.c gtk-utils.h ../test/utils.c ../test/utils.h
+GTK_UTILS = gtk-utils.c gtk-utils.h ../test/utils.c ../test/utils.h \
+ ../test/utils-prng.c ../test/utils-prng.h
DEMOS = \
clip-test \
@@ -14,6 +15,7 @@ DEMOS = \
composite-test \
gradient-test \
radial-test \
+ conical-test \
alpha-test \
screen-test \
convolution-test \
@@ -22,9 +24,10 @@ DEMOS = \
quad2quad \
checkerboard \
srgb-trap-test \
- srgb-test
+ srgb-test \
+ scale
-EXTRA_DIST = parrot.c parrot.jpg
+EXTRA_DIST = parrot.c parrot.jpg scale.ui
gradient_test_SOURCES = gradient-test.c $(GTK_UTILS)
alpha_test_SOURCES = alpha-test.c $(GTK_UTILS)
@@ -35,10 +38,12 @@ trap_test_SOURCES = trap-test.c $(GTK_UTILS)
screen_test_SOURCES = screen-test.c $(GTK_UTILS)
convolution_test_SOURCES = convolution-test.c $(GTK_UTILS)
radial_test_SOURCES = radial-test.c $(GTK_UTILS)
+conical_test_SOURCES = conical-test.c $(GTK_UTILS)
tri_test_SOURCES = tri-test.c $(GTK_UTILS)
checkerboard_SOURCES = checkerboard.c $(GTK_UTILS)
srgb_test_SOURCES = srgb-test.c $(GTK_UTILS)
srgb_trap_test_SOURCES = srgb-trap-test.c $(GTK_UTILS)
+scale_SOURCES = scale.c $(GTK_UTILS)
noinst_PROGRAMS = $(DEMOS)
diff --git a/pixman/demos/conical-test.c b/pixman/demos/conical-test.c
new file mode 100644
index 000000000..1e08e42f7
--- /dev/null
+++ b/pixman/demos/conical-test.c
@@ -0,0 +1,134 @@
+#include "../test/utils.h"
+#include "gtk-utils.h"
+
+#define SIZE 128
+#define GRADIENTS_PER_ROW 7
+#define NUM_ROWS ((NUM_GRADIENTS + GRADIENTS_PER_ROW - 1) / GRADIENTS_PER_ROW)
+#define WIDTH (SIZE * GRADIENTS_PER_ROW)
+#define HEIGHT (SIZE * NUM_ROWS)
+#define NUM_GRADIENTS 35
+
+#define double_to_color(x) \
+ (((uint32_t) ((x)*65536)) - (((uint32_t) ((x)*65536)) >> 16))
+
+#define PIXMAN_STOP(offset,r,g,b,a) \
+ { pixman_double_to_fixed (offset), \
+ { \
+ double_to_color (r), \
+ double_to_color (g), \
+ double_to_color (b), \
+ double_to_color (a) \
+ } \
+ }
+
+
+static const pixman_gradient_stop_t stops[] = {
+ PIXMAN_STOP (0.25, 1, 0, 0, 0.7),
+ PIXMAN_STOP (0.5, 1, 1, 0, 0.7),
+ PIXMAN_STOP (0.75, 0, 1, 0, 0.7),
+ PIXMAN_STOP (1.0, 0, 0, 1, 0.7)
+};
+
+#define NUM_STOPS (sizeof (stops) / sizeof (stops[0]))
+
+static pixman_image_t *
+create_conical (int index)
+{
+ pixman_point_fixed_t c;
+ double angle;
+
+ c.x = pixman_double_to_fixed (0);
+ c.y = pixman_double_to_fixed (0);
+
+ angle = (0.5 / NUM_GRADIENTS + index / (double)NUM_GRADIENTS) * 720 - 180;
+
+ return pixman_image_create_conical_gradient (
+ &c, pixman_double_to_fixed (angle), stops, NUM_STOPS);
+}
+
+#define CHECK_SIZE 25
+
+static void
+fill_checkerboard (pixman_image_t *image, int width, int height)
+{
+#define C1 0xaaaa
+#define C2 0x8888
+
+ pixman_color_t check1 = { C1, C1, C1, 0xffff };
+ pixman_color_t check2 = { C2, C2, C2, 0xffff };
+ pixman_image_t *c1, *c2;
+ int i, j;
+
+ c1 = pixman_image_create_solid_fill (&check1);
+ c2 = pixman_image_create_solid_fill (&check2);
+
+ for (j = 0; j < height; j += CHECK_SIZE)
+ {
+ for (i = 0; i < width; i += CHECK_SIZE)
+ {
+ pixman_image_t *src;
+
+ if ((((i / CHECK_SIZE) ^ (j / CHECK_SIZE)) & 1) == 0)
+ src = c1;
+ else
+ src = c2;
+
+ pixman_image_composite32 (PIXMAN_OP_SRC, src, NULL, image,
+ 0, 0, 0, 0, i, j,
+ CHECK_SIZE, CHECK_SIZE);
+ }
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ pixman_transform_t transform;
+ pixman_image_t *src_img, *dest_img;
+ int i;
+
+ enable_divbyzero_exceptions ();
+
+ dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
+ WIDTH, HEIGHT,
+ NULL, 0);
+
+ fill_checkerboard (dest_img, WIDTH, HEIGHT);
+
+ pixman_transform_init_identity (&transform);
+
+ pixman_transform_translate (NULL, &transform,
+ pixman_double_to_fixed (0.5),
+ pixman_double_to_fixed (0.5));
+
+ pixman_transform_scale (NULL, &transform,
+ pixman_double_to_fixed (SIZE),
+ pixman_double_to_fixed (SIZE));
+ pixman_transform_translate (NULL, &transform,
+ pixman_double_to_fixed (0.5),
+ pixman_double_to_fixed (0.5));
+
+ for (i = 0; i < NUM_GRADIENTS; i++)
+ {
+ int column = i % GRADIENTS_PER_ROW;
+ int row = i / GRADIENTS_PER_ROW;
+
+ src_img = create_conical (i);
+ pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
+
+ pixman_image_set_transform (src_img, &transform);
+
+ pixman_image_composite32 (
+ PIXMAN_OP_OVER, src_img, NULL,dest_img,
+ 0, 0, 0, 0, column * SIZE, row * SIZE,
+ SIZE, SIZE);
+
+ pixman_image_unref (src_img);
+ }
+
+ show_image (dest_img);
+
+ pixman_image_unref (dest_img);
+
+ return 0;
+}
diff --git a/pixman/demos/gtk-utils.c b/pixman/demos/gtk-utils.c
index 8291a1ed2..d7e946ded 100644
--- a/pixman/demos/gtk-utils.c
+++ b/pixman/demos/gtk-utils.c
@@ -3,6 +3,72 @@
#include "../test/utils.h"
#include "gtk-utils.h"
+pixman_image_t *
+pixman_image_from_file (const char *filename, pixman_format_code_t format)
+{
+ GdkPixbuf *pixbuf;
+ pixman_image_t *image;
+ int width, height;
+ uint32_t *data, *d;
+ uint8_t *gdk_data;
+ int n_channels;
+ int j, i;
+ int stride;
+
+ if (!(pixbuf = gdk_pixbuf_new_from_file (filename, NULL)))
+ return NULL;
+
+ image = NULL;
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+ gdk_data = gdk_pixbuf_get_pixels (pixbuf);
+ stride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ if (!(data = malloc (width * height * sizeof (uint32_t))))
+ goto out;
+
+ d = data;
+ for (j = 0; j < height; ++j)
+ {
+ uint8_t *gdk_line = gdk_data;
+
+ for (i = 0; i < width; ++i)
+ {
+ int r, g, b, a;
+ uint32_t pixel;
+
+ r = gdk_line[0];
+ g = gdk_line[1];
+ b = gdk_line[2];
+
+ if (n_channels == 4)
+ a = gdk_line[3];
+ else
+ a = 0xff;
+
+ r = (r * a + 127) / 255;
+ g = (g * a + 127) / 255;
+ b = (b * a + 127) / 255;
+
+ pixel = (a << 24) | (r << 16) | (g << 8) | b;
+
+ *d++ = pixel;
+ gdk_line += n_channels;
+ }
+
+ gdk_data += stride;
+ }
+
+ image = pixman_image_create_bits (
+ format, width, height, data, width * 4);
+
+out:
+ g_object_unref (pixbuf);
+ return image;
+}
+
GdkPixbuf *
pixbuf_from_argb32 (uint32_t *bits,
int width,
diff --git a/pixman/demos/gtk-utils.h b/pixman/demos/gtk-utils.h
index 55cb7018a..36be4def6 100644
--- a/pixman/demos/gtk-utils.h
+++ b/pixman/demos/gtk-utils.h
@@ -6,6 +6,9 @@
void show_image (pixman_image_t *image);
+pixman_image_t *
+pixman_image_from_file (const char *filename, pixman_format_code_t format);
+
GdkPixbuf *pixbuf_from_argb32 (uint32_t *bits,
int width,
int height,
diff --git a/pixman/demos/scale.c b/pixman/demos/scale.c
new file mode 100644
index 000000000..9100ff72a
--- /dev/null
+++ b/pixman/demos/scale.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright 2012, Red Hat, Inc.
+ * Copyright 2012, Soren Sandmann
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Soren Sandmann <soren.sandmann@gmail.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <math.h>
+#include <gtk/gtk.h>
+#include <pixman.h>
+#include <stdlib.h>
+#include "gtk-utils.h"
+
+typedef struct
+{
+ GtkBuilder * builder;
+ pixman_image_t * original;
+ GtkAdjustment * scale_x_adjustment;
+ GtkAdjustment * scale_y_adjustment;
+ GtkAdjustment * rotate_adjustment;
+ int scaled_width;
+ int scaled_height;
+} app_t;
+
+static GtkWidget *
+get_widget (app_t *app, const char *name)
+{
+ GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (app->builder, name));
+
+ if (!widget)
+ g_error ("Widget %s not found\n", name);
+
+ return widget;
+}
+
+static double
+min4 (double a, double b, double c, double d)
+{
+ double m1, m2;
+
+ m1 = MIN (a, b);
+ m2 = MIN (c, d);
+ return MIN (m1, m2);
+}
+
+static double
+max4 (double a, double b, double c, double d)
+{
+ double m1, m2;
+
+ m1 = MAX (a, b);
+ m2 = MAX (c, d);
+ return MAX (m1, m2);
+}
+
+static void
+compute_extents (pixman_f_transform_t *trans, double *sx, double *sy)
+{
+ double min_x, max_x, min_y, max_y;
+ pixman_f_vector_t v[4] =
+ {
+ { { 1, 1, 1 } },
+ { { -1, 1, 1 } },
+ { { -1, -1, 1 } },
+ { { 1, -1, 1 } },
+ };
+
+ pixman_f_transform_point (trans, &v[0]);
+ pixman_f_transform_point (trans, &v[1]);
+ pixman_f_transform_point (trans, &v[2]);
+ pixman_f_transform_point (trans, &v[3]);
+
+ min_x = min4 (v[0].v[0], v[1].v[0], v[2].v[0], v[3].v[0]);
+ max_x = max4 (v[0].v[0], v[1].v[0], v[2].v[0], v[3].v[0]);
+ min_y = min4 (v[0].v[1], v[1].v[1], v[2].v[1], v[3].v[1]);
+ max_y = max4 (v[0].v[1], v[1].v[1], v[2].v[1], v[3].v[1]);
+
+ *sx = (max_x - min_x) / 2.0;
+ *sy = (max_y - min_y) / 2.0;
+}
+
+typedef struct
+{
+ char name [20];
+ pixman_kernel_t value;
+} named_int_t;
+
+static const named_int_t filters[] =
+{
+ { "Box", PIXMAN_KERNEL_BOX },
+ { "Impulse", PIXMAN_KERNEL_IMPULSE },
+ { "Linear", PIXMAN_KERNEL_LINEAR },
+ { "Cubic", PIXMAN_KERNEL_CUBIC },
+ { "Lanczos2", PIXMAN_KERNEL_LANCZOS2 },
+ { "Lanczos3", PIXMAN_KERNEL_LANCZOS3 },
+ { "Lanczos3 Stretched", PIXMAN_KERNEL_LANCZOS3_STRETCHED },
+ { "Gaussian", PIXMAN_KERNEL_GAUSSIAN },
+};
+
+static const named_int_t repeats[] =
+{
+ { "None", PIXMAN_REPEAT_NONE },
+ { "Normal", PIXMAN_REPEAT_NORMAL },
+ { "Reflect", PIXMAN_REPEAT_REFLECT },
+ { "Pad", PIXMAN_REPEAT_PAD },
+};
+
+static pixman_kernel_t
+get_value (app_t *app, const named_int_t table[], const char *box_name)
+{
+ GtkComboBox *box = GTK_COMBO_BOX (get_widget (app, box_name));
+
+ return table[gtk_combo_box_get_active (box)].value;
+}
+
+static void
+copy_to_counterpart (app_t *app, GObject *object)
+{
+ static const char *xy_map[] =
+ {
+ "reconstruct_x_combo_box", "reconstruct_y_combo_box",
+ "sample_x_combo_box", "sample_y_combo_box",
+ "scale_x_adjustment", "scale_y_adjustment",
+ };
+ GObject *counterpart = NULL;
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (xy_map); i += 2)
+ {
+ GObject *x = gtk_builder_get_object (app->builder, xy_map[i]);
+ GObject *y = gtk_builder_get_object (app->builder, xy_map[i + 1]);
+
+ if (object == x)
+ counterpart = y;
+ if (object == y)
+ counterpart = x;
+ }
+
+ if (!counterpart)
+ return;
+
+ if (GTK_IS_COMBO_BOX (counterpart))
+ {
+ gtk_combo_box_set_active (
+ GTK_COMBO_BOX (counterpart),
+ gtk_combo_box_get_active (
+ GTK_COMBO_BOX (object)));
+ }
+ else if (GTK_IS_ADJUSTMENT (counterpart))
+ {
+ gtk_adjustment_set_value (
+ GTK_ADJUSTMENT (counterpart),
+ gtk_adjustment_get_value (
+ GTK_ADJUSTMENT (object)));
+ }
+}
+
+static double
+to_scale (double v)
+{
+ return pow (1.15, v);
+}
+
+static void
+rescale (GtkWidget *may_be_null, app_t *app)
+{
+ pixman_f_transform_t ftransform;
+ pixman_transform_t transform;
+ double new_width, new_height;
+ double fscale_x, fscale_y;
+ double rotation;
+ pixman_fixed_t *params;
+ int n_params;
+ double sx, sy;
+
+ pixman_f_transform_init_identity (&ftransform);
+
+ if (may_be_null && gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (get_widget (app, "lock_checkbutton"))))
+ {
+ copy_to_counterpart (app, G_OBJECT (may_be_null));
+ }
+
+ fscale_x = gtk_adjustment_get_value (app->scale_x_adjustment);
+ fscale_y = gtk_adjustment_get_value (app->scale_y_adjustment);
+ rotation = gtk_adjustment_get_value (app->rotate_adjustment);
+
+ fscale_x = to_scale (fscale_x);
+ fscale_y = to_scale (fscale_y);
+
+ new_width = pixman_image_get_width (app->original) * fscale_x;
+ new_height = pixman_image_get_height (app->original) * fscale_y;
+
+ pixman_f_transform_scale (&ftransform, NULL, fscale_x, fscale_y);
+
+ pixman_f_transform_translate (&ftransform, NULL, - new_width / 2.0, - new_height / 2.0);
+
+ rotation = (rotation / 360.0) * 2 * M_PI;
+ pixman_f_transform_rotate (&ftransform, NULL, cos (rotation), sin (rotation));
+
+ pixman_f_transform_translate (&ftransform, NULL, new_width / 2.0, new_height / 2.0);
+
+ pixman_f_transform_invert (&ftransform, &ftransform);
+
+ compute_extents (&ftransform, &sx, &sy);
+
+ pixman_transform_from_pixman_f_transform (&transform, &ftransform);
+ pixman_image_set_transform (app->original, &transform);
+
+ params = pixman_filter_create_separable_convolution (
+ &n_params,
+ sx * 65536.0 + 0.5,
+ sy * 65536.0 + 0.5,
+ get_value (app, filters, "reconstruct_x_combo_box"),
+ get_value (app, filters, "reconstruct_y_combo_box"),
+ get_value (app, filters, "sample_x_combo_box"),
+ get_value (app, filters, "sample_y_combo_box"),
+ 4, 4);
+
+ pixman_image_set_filter (app->original, PIXMAN_FILTER_SEPARABLE_CONVOLUTION, params, n_params);
+
+ pixman_image_set_repeat (
+ app->original, get_value (app, repeats, "repeat_combo_box"));
+
+ free (params);
+
+ app->scaled_width = ceil (new_width);
+ app->scaled_height = ceil (new_height);
+
+ gtk_widget_set_size_request (
+ get_widget (app, "drawing_area"), new_width + 0.5, new_height + 0.5);
+
+ gtk_widget_queue_draw (
+ get_widget (app, "drawing_area"));
+}
+
+static gboolean
+on_expose (GtkWidget *da, GdkEvent *event, gpointer data)
+{
+ app_t *app = data;
+ GdkRectangle *area = &event->expose.area;
+ cairo_surface_t *surface;
+ pixman_image_t *tmp;
+ cairo_t *cr;
+ uint32_t *pixels;
+
+ pixels = calloc (1, area->width * area->height * 4);
+ tmp = pixman_image_create_bits (
+ PIXMAN_a8r8g8b8, area->width, area->height, pixels, area->width * 4);
+
+ if (area->x < app->scaled_width && area->y < app->scaled_height)
+ {
+ pixman_image_composite (
+ PIXMAN_OP_SRC,
+ app->original, NULL, tmp,
+ area->x, area->y, 0, 0, 0, 0,
+ app->scaled_width - area->x, app->scaled_height - area->y);
+ }
+
+ surface = cairo_image_surface_create_for_data (
+ (uint8_t *)pixels, CAIRO_FORMAT_ARGB32,
+ area->width, area->height, area->width * 4);
+
+ cr = gdk_cairo_create (da->window);
+
+ cairo_set_source_surface (cr, surface, area->x, area->y);
+
+ cairo_paint (cr);
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+ free (pixels);
+ pixman_image_unref (tmp);
+
+ return TRUE;
+}
+
+static void
+set_up_combo_box (app_t *app, const char *box_name,
+ int n_entries, const named_int_t table[])
+{
+ GtkWidget *widget = get_widget (app, box_name);
+ GtkListStore *model;
+ GtkCellRenderer *cell;
+ int i;
+
+ model = gtk_list_store_new (1, G_TYPE_STRING);
+
+ cell = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), cell,
+ "text", 0,
+ NULL);
+
+ gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (model));
+
+ for (i = 0; i < n_entries; ++i)
+ {
+ const named_int_t *info = &(table[i]);
+ GtkTreeIter iter;
+
+ gtk_list_store_append (model, &iter);
+ gtk_list_store_set (model, &iter, 0, info->name, -1);
+ }
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+
+ g_signal_connect (widget, "changed", G_CALLBACK (rescale), app);
+}
+
+static void
+set_up_filter_box (app_t *app, const char *box_name)
+{
+ set_up_combo_box (app, box_name, G_N_ELEMENTS (filters), filters);
+}
+
+static char *
+format_value (GtkWidget *widget, double value)
+{
+ return g_strdup_printf ("%.4f", to_scale (value));
+}
+
+static app_t *
+app_new (pixman_image_t *original)
+{
+ GtkWidget *widget;
+ app_t *app = g_malloc (sizeof *app);
+ GError *err = NULL;
+
+ app->builder = gtk_builder_new ();
+ app->original = original;
+
+ if (!gtk_builder_add_from_file (app->builder, "scale.ui", &err))
+ g_error ("Could not read file scale.ui: %s", err->message);
+
+ app->scale_x_adjustment =
+ GTK_ADJUSTMENT (gtk_builder_get_object (app->builder, "scale_x_adjustment"));
+ app->scale_y_adjustment =
+ GTK_ADJUSTMENT (gtk_builder_get_object (app->builder, "scale_y_adjustment"));
+ app->rotate_adjustment =
+ GTK_ADJUSTMENT (gtk_builder_get_object (app->builder, "rotate_adjustment"));
+
+ g_signal_connect (app->scale_x_adjustment, "value_changed", G_CALLBACK (rescale), app);
+ g_signal_connect (app->scale_y_adjustment, "value_changed", G_CALLBACK (rescale), app);
+ g_signal_connect (app->rotate_adjustment, "value_changed", G_CALLBACK (rescale), app);
+
+ widget = get_widget (app, "scale_x_scale");
+ gtk_scale_add_mark (GTK_SCALE (widget), 0.0, GTK_POS_LEFT, NULL);
+ g_signal_connect (widget, "format_value", G_CALLBACK (format_value), app);
+ widget = get_widget (app, "scale_y_scale");
+ gtk_scale_add_mark (GTK_SCALE (widget), 0.0, GTK_POS_LEFT, NULL);
+ g_signal_connect (widget, "format_value", G_CALLBACK (format_value), app);
+ widget = get_widget (app, "rotate_scale");
+ gtk_scale_add_mark (GTK_SCALE (widget), 0.0, GTK_POS_LEFT, NULL);
+
+ widget = get_widget (app, "drawing_area");
+ g_signal_connect (widget, "expose_event", G_CALLBACK (on_expose), app);
+
+ set_up_filter_box (app, "reconstruct_x_combo_box");
+ set_up_filter_box (app, "reconstruct_y_combo_box");
+ set_up_filter_box (app, "sample_x_combo_box");
+ set_up_filter_box (app, "sample_y_combo_box");
+
+ set_up_combo_box (
+ app, "repeat_combo_box", G_N_ELEMENTS (repeats), repeats);
+
+ g_signal_connect (
+ gtk_builder_get_object (app->builder, "lock_checkbutton"),
+ "toggled", G_CALLBACK (rescale), app);
+
+ rescale (NULL, app);
+
+ return app;
+}
+
+int
+main (int argc, char **argv)
+{
+ GtkWidget *window;
+ pixman_image_t *image;
+ app_t *app;
+
+ gtk_init (&argc, &argv);
+
+ if (argc < 2)
+ {
+ printf ("%s <image file>\n", argv[0]);
+ return -1;
+ }
+
+ if (!(image = pixman_image_from_file (argv[1], PIXMAN_a8r8g8b8)))
+ {
+ printf ("Could not load image \"%s\"\n", argv[1]);
+ return -1;
+ }
+
+ app = app_new (image);
+
+ window = get_widget (app, "main");
+
+ g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
+
+ gtk_window_set_default_size (GTK_WINDOW (window), 1024, 768);
+
+ gtk_widget_show_all (window);
+
+ gtk_main ();
+
+ return 0;
+}
diff --git a/pixman/demos/scale.ui b/pixman/demos/scale.ui
new file mode 100644
index 000000000..f7c0c805f
--- /dev/null
+++ b/pixman/demos/scale.ui
@@ -0,0 +1,302 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 2.12 -->
+ <!-- interface-naming-policy toplevel-contextual -->
+ <object class="GtkAdjustment" id="rotate_adjustment">
+ <property name="lower">-180</property>
+ <property name="upper">190</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ <property name="page_size">10</property>
+ </object>
+ <object class="GtkAdjustment" id="scale_y_adjustment">
+ <property name="lower">-32</property>
+ <property name="upper">42</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ <property name="page_size">10</property>
+ </object>
+ <object class="GtkAdjustment" id="scale_x_adjustment">
+ <property name="lower">-32</property>
+ <property name="upper">42</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ <property name="page_size">10</property>
+ </object>
+ <object class="GtkWindow" id="main">
+ <child>
+ <object class="GtkHBox" id="u">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport" id="viewport1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkDrawingArea" id="drawing_area">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="box1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkHBox" id="box2">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkVBox" id="box3">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Scale X&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVScale" id="scale_x_scale">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">scale_x_adjustment</property>
+ <property name="fill_level">32</property>
+ <property name="value_pos">right</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="box4">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Scale Y&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVScale" id="scale_y_scale">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">scale_y_adjustment</property>
+ <property name="fill_level">32</property>
+ <property name="value_pos">right</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="box5">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Rotate&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVScale" id="rotate_scale">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">rotate_adjustment</property>
+ <property name="fill_level">180</property>
+ <property name="value_pos">right</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">6</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="box6">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkCheckButton"
+ id="lock_checkbutton">
+ <property name="label" translatable="yes">Lock X and Y Dimensions</property>
+ <property name="xalign">0.0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">6</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="grid1">
+ <property name="visible">True</property>
+ <property name="column_spacing">8</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">&lt;b&gt;Reconstruct X:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">&lt;b&gt;Reconstruct Y:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">&lt;b&gt;Sample X:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">&lt;b&gt;Sample Y:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">&lt;b&gt;Repeat:&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="reconstruct_x_combo_box">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="reconstruct_y_combo_box">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="sample_x_combo_box">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="sample_y_combo_box">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="repeat_combo_box">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="padding">6</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/pixman/demos/zone_plate.png b/pixman/demos/zone_plate.png
new file mode 100644
index 000000000..519291d6d
--- /dev/null
+++ b/pixman/demos/zone_plate.png
Binary files differ
diff --git a/pixman/pixman/Makefile.sources b/pixman/pixman/Makefile.sources
index 5351fb03d..c624eb9a8 100644
--- a/pixman/pixman/Makefile.sources
+++ b/pixman/pixman/Makefile.sources
@@ -6,6 +6,7 @@ libpixman_sources = \
pixman-combine32.c \
pixman-combine-float.c \
pixman-conical-gradient.c \
+ pixman-filter.c \
pixman-x86.c \
pixman-mips.c \
pixman-arm.c \
diff --git a/pixman/pixman/pixman-bits-image.c b/pixman/pixman/pixman-bits-image.c
index 7787ef1b8..86d80c3f5 100644
--- a/pixman/pixman/pixman-bits-image.c
+++ b/pixman/pixman/pixman-bits-image.c
@@ -426,6 +426,104 @@ bits_image_fetch_pixel_convolution (bits_image_t *image,
return ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot));
}
+static uint32_t
+bits_image_fetch_pixel_separable_convolution (bits_image_t *image,
+ pixman_fixed_t x,
+ pixman_fixed_t y,
+ get_pixel_t get_pixel)
+{
+ pixman_fixed_t *params = image->common.filter_params;
+ pixman_repeat_t repeat_mode = image->common.repeat;
+ int width = image->width;
+ int height = image->height;
+ int cwidth = pixman_fixed_to_int (params[0]);
+ int cheight = pixman_fixed_to_int (params[1]);
+ int x_phase_bits = pixman_fixed_to_int (params[2]);
+ int y_phase_bits = pixman_fixed_to_int (params[3]);
+ int x_phase_shift = 16 - x_phase_bits;
+ int y_phase_shift = 16 - y_phase_bits;
+ int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1;
+ int y_off = ((cheight << 16) - pixman_fixed_1) >> 1;
+ pixman_fixed_t *y_params;
+ int srtot, sgtot, sbtot, satot;
+ int32_t x1, x2, y1, y2;
+ int32_t px, py;
+ int i, j;
+
+ /* Round x and y to the middle of the closest phase before continuing. This
+ * ensures that the convolution matrix is aligned right, since it was
+ * positioned relative to a particular phase (and not relative to whatever
+ * exact fraction we happen to get here).
+ */
+ x = ((x >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
+ y = ((y >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
+
+ px = (x & 0xffff) >> x_phase_shift;
+ py = (y & 0xffff) >> y_phase_shift;
+
+ y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight;
+
+ x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
+ y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
+ x2 = x1 + cwidth;
+ y2 = y1 + cheight;
+
+ srtot = sgtot = sbtot = satot = 0;
+
+ for (i = y1; i < y2; ++i)
+ {
+ pixman_fixed_48_16_t fy = *y_params++;
+ pixman_fixed_t *x_params = params + 4 + px * cwidth;
+
+ if (fy)
+ {
+ for (j = x1; j < x2; ++j)
+ {
+ pixman_fixed_t fx = *x_params++;
+ int rx = j;
+ int ry = i;
+
+ if (fx)
+ {
+ pixman_fixed_t f;
+ uint32_t pixel;
+
+ if (repeat_mode != PIXMAN_REPEAT_NONE)
+ {
+ repeat (repeat_mode, &rx, width);
+ repeat (repeat_mode, &ry, height);
+
+ pixel = get_pixel (image, rx, ry, FALSE);
+ }
+ else
+ {
+ pixel = get_pixel (image, rx, ry, TRUE);
+ }
+
+ f = (fy * fx + 0x8000) >> 16;
+
+ srtot += (int)RED_8 (pixel) * f;
+ sgtot += (int)GREEN_8 (pixel) * f;
+ sbtot += (int)BLUE_8 (pixel) * f;
+ satot += (int)ALPHA_8 (pixel) * f;
+ }
+ }
+ }
+ }
+
+ satot = (satot + 0x8000) >> 16;
+ srtot = (srtot + 0x8000) >> 16;
+ sgtot = (sgtot + 0x8000) >> 16;
+ sbtot = (sbtot + 0x8000) >> 16;
+
+ satot = CLIP (satot, 0, 0xff);
+ srtot = CLIP (srtot, 0, 0xff);
+ sgtot = CLIP (sgtot, 0, 0xff);
+ sbtot = CLIP (sbtot, 0, 0xff);
+
+ return ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot));
+}
+
static force_inline uint32_t
bits_image_fetch_pixel_filtered (bits_image_t *image,
pixman_fixed_t x,
@@ -449,6 +547,10 @@ bits_image_fetch_pixel_filtered (bits_image_t *image,
return bits_image_fetch_pixel_convolution (image, x, y, get_pixel);
break;
+ case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
+ return bits_image_fetch_pixel_separable_convolution (image, x, y, get_pixel);
+ break;
+
default:
break;
}
@@ -618,11 +720,155 @@ bits_image_fetch_general (pixman_iter_t *iter,
return buffer;
}
-static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
typedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x);
static force_inline void
+bits_image_fetch_separable_convolution_affine (pixman_image_t * image,
+ int offset,
+ int line,
+ int width,
+ uint32_t * buffer,
+ const uint32_t * mask,
+
+ convert_pixel_t convert_pixel,
+ pixman_format_code_t format,
+ pixman_repeat_t repeat_mode)
+{
+ bits_image_t *bits = &image->bits;
+ pixman_fixed_t *params = image->common.filter_params;
+ int cwidth = pixman_fixed_to_int (params[0]);
+ int cheight = pixman_fixed_to_int (params[1]);
+ int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1;
+ int y_off = ((cheight << 16) - pixman_fixed_1) >> 1;
+ int x_phase_bits = pixman_fixed_to_int (params[2]);
+ int y_phase_bits = pixman_fixed_to_int (params[3]);
+ int x_phase_shift = 16 - x_phase_bits;
+ int y_phase_shift = 16 - y_phase_bits;
+ pixman_fixed_t vx, vy;
+ pixman_fixed_t ux, uy;
+ pixman_vector_t v;
+ int k;
+
+ /* reference point is the center of the pixel */
+ v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2;
+ v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2;
+ v.vector[2] = pixman_fixed_1;
+
+ if (!pixman_transform_point_3d (image->common.transform, &v))
+ return;
+
+ ux = image->common.transform->matrix[0][0];
+ uy = image->common.transform->matrix[1][0];
+
+ vx = v.vector[0];
+ vy = v.vector[1];
+
+ for (k = 0; k < width; ++k)
+ {
+ pixman_fixed_t *y_params;
+ int satot, srtot, sgtot, sbtot;
+ pixman_fixed_t x, y;
+ int32_t x1, x2, y1, y2;
+ int32_t px, py;
+ int i, j;
+
+ if (mask && !mask[k])
+ goto next;
+
+ /* Round x and y to the middle of the closest phase before continuing. This
+ * ensures that the convolution matrix is aligned right, since it was
+ * positioned relative to a particular phase (and not relative to whatever
+ * exact fraction we happen to get here).
+ */
+ x = ((vx >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
+ y = ((vy >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
+
+ px = (x & 0xffff) >> x_phase_shift;
+ py = (y & 0xffff) >> y_phase_shift;
+
+ x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off);
+ y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off);
+ x2 = x1 + cwidth;
+ y2 = y1 + cheight;
+
+ satot = srtot = sgtot = sbtot = 0;
+
+ y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight;
+
+ for (i = y1; i < y2; ++i)
+ {
+ pixman_fixed_t fy = *y_params++;
+
+ if (fy)
+ {
+ pixman_fixed_t *x_params = params + 4 + px * cwidth;
+
+ for (j = x1; j < x2; ++j)
+ {
+ pixman_fixed_t fx = *x_params++;
+ int rx = j;
+ int ry = i;
+
+ if (fx)
+ {
+ pixman_fixed_t f;
+ uint32_t pixel, mask;
+ uint8_t *row;
+
+ mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
+
+ if (repeat_mode != PIXMAN_REPEAT_NONE)
+ {
+ repeat (repeat_mode, &rx, bits->width);
+ repeat (repeat_mode, &ry, bits->height);
+
+ row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry;
+ pixel = convert_pixel (row, rx) | mask;
+ }
+ else
+ {
+ if (rx < 0 || ry < 0 || rx >= bits->width || ry >= bits->height)
+ {
+ pixel = 0;
+ }
+ else
+ {
+ row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry;
+ pixel = convert_pixel (row, rx) | mask;
+ }
+ }
+
+ f = ((pixman_fixed_32_32_t)fx * fy + 0x8000) >> 16;
+ srtot += (int)RED_8 (pixel) * f;
+ sgtot += (int)GREEN_8 (pixel) * f;
+ sbtot += (int)BLUE_8 (pixel) * f;
+ satot += (int)ALPHA_8 (pixel) * f;
+ }
+ }
+ }
+ }
+
+ satot = (satot + 0x8000) >> 16;
+ srtot = (srtot + 0x8000) >> 16;
+ sgtot = (sgtot + 0x8000) >> 16;
+ sbtot = (sbtot + 0x8000) >> 16;
+
+ satot = CLIP (satot, 0, 0xff);
+ srtot = CLIP (srtot, 0, 0xff);
+ sgtot = CLIP (sgtot, 0, 0xff);
+ sbtot = CLIP (sbtot, 0, 0xff);
+
+ buffer[k] = (satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot << 0);
+
+ next:
+ vx += ux;
+ vy += uy;
+ }
+}
+
+static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static force_inline void
bits_image_fetch_bilinear_affine (pixman_image_t * image,
int offset,
int line,
@@ -871,6 +1117,23 @@ convert_r5g6b5 (const uint8_t *row, int x)
return CONVERT_0565_TO_0888 (*((uint16_t *)row + x));
}
+#define MAKE_SEPARABLE_CONVOLUTION_FETCHER(name, format, repeat_mode) \
+ static uint32_t * \
+ bits_image_fetch_separable_convolution_affine_ ## name (pixman_iter_t *iter, \
+ const uint32_t * mask) \
+ { \
+ bits_image_fetch_separable_convolution_affine ( \
+ iter->image, \
+ iter->x, iter->y++, \
+ iter->width, \
+ iter->buffer, mask, \
+ convert_ ## format, \
+ PIXMAN_ ## format, \
+ repeat_mode); \
+ \
+ return iter->buffer; \
+ }
+
#define MAKE_BILINEAR_FETCHER(name, format, repeat_mode) \
static uint32_t * \
bits_image_fetch_bilinear_affine_ ## name (pixman_iter_t *iter, \
@@ -903,7 +1166,8 @@ convert_r5g6b5 (const uint8_t *row, int x)
#define MAKE_FETCHERS(name, format, repeat_mode) \
MAKE_NEAREST_FETCHER (name, format, repeat_mode) \
- MAKE_BILINEAR_FETCHER (name, format, repeat_mode)
+ MAKE_BILINEAR_FETCHER (name, format, repeat_mode) \
+ MAKE_SEPARABLE_CONVOLUTION_FETCHER (name, format, repeat_mode)
MAKE_FETCHERS (pad_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_PAD)
MAKE_FETCHERS (none_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_NONE)
@@ -1153,6 +1417,20 @@ static const fetcher_info_t fetcher_info[] =
FAST_PATH_AFFINE_TRANSFORM | \
FAST_PATH_NEAREST_FILTER)
+#define GENERAL_SEPARABLE_CONVOLUTION_FLAGS \
+ (FAST_PATH_NO_ALPHA_MAP | \
+ FAST_PATH_NO_ACCESSORS | \
+ FAST_PATH_HAS_TRANSFORM | \
+ FAST_PATH_AFFINE_TRANSFORM | \
+ FAST_PATH_SEPARABLE_CONVOLUTION_FILTER)
+
+#define SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat) \
+ { PIXMAN_ ## format, \
+ GENERAL_SEPARABLE_CONVOLUTION_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \
+ bits_image_fetch_separable_convolution_affine_ ## name, \
+ _pixman_image_get_scanline_generic_float \
+ },
+
#define BILINEAR_AFFINE_FAST_PATH(name, format, repeat) \
{ PIXMAN_ ## format, \
GENERAL_BILINEAR_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \
@@ -1168,6 +1446,7 @@ static const fetcher_info_t fetcher_info[] =
},
#define AFFINE_FAST_PATHS(name, format, repeat) \
+ SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat) \
BILINEAR_AFFINE_FAST_PATH(name, format, repeat) \
NEAREST_AFFINE_FAST_PATH(name, format, repeat)
diff --git a/pixman/pixman/pixman-filter.c b/pixman/pixman/pixman-filter.c
new file mode 100644
index 000000000..c9d2dc74c
--- /dev/null
+++ b/pixman/pixman/pixman-filter.c
@@ -0,0 +1,340 @@
+/*
+ * Copyright 2012, Red Hat, Inc.
+ * Copyright 2012, Soren Sandmann
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Soren Sandmann <soren.sandmann@gmail.com>
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <assert.h>
+#include <config.h>
+#include "pixman-private.h"
+
+typedef double (* kernel_func_t) (double x);
+
+typedef struct
+{
+ pixman_kernel_t kernel;
+ kernel_func_t func;
+ double width;
+} filter_info_t;
+
+static double
+impulse_kernel (double x)
+{
+ return (x == 0.0)? 1.0 : 0.0;
+}
+
+static double
+box_kernel (double x)
+{
+ return 1;
+}
+
+static double
+linear_kernel (double x)
+{
+ return 1 - fabs (x);
+}
+
+static double
+gaussian_kernel (double x)
+{
+#define SQRT2 (1.4142135623730950488016887242096980785696718753769480)
+#define SIGMA (SQRT2 / 2.0)
+
+ return exp (- x * x / (2 * SIGMA * SIGMA)) / (SIGMA * sqrt (2.0 * M_PI));
+}
+
+static double
+sinc (double x)
+{
+ if (x == 0.0)
+ return 1.0;
+ else
+ return sin (M_PI * x) / (M_PI * x);
+}
+
+static double
+lanczos (double x, int n)
+{
+ return sinc (x) * sinc (x * (1.0 / n));
+}
+
+static double
+lanczos2_kernel (double x)
+{
+ return lanczos (x, 2);
+}
+
+static double
+lanczos3_kernel (double x)
+{
+ return lanczos (x, 3);
+}
+
+static double
+nice_kernel (double x)
+{
+ return lanczos3_kernel (x * 0.75);
+}
+
+static double
+general_cubic (double x, double B, double C)
+{
+ double ax = fabs(x);
+
+ if (ax < 1)
+ {
+ return ((12 - 9 * B - 6 * C) * ax * ax * ax +
+ (-18 + 12 * B + 6 * C) * ax * ax + (6 - 2 * B)) / 6;
+ }
+ else if (ax >= 1 && ax < 2)
+ {
+ return ((-B - 6 * C) * ax * ax * ax +
+ (6 * B + 30 * C) * ax * ax + (-12 * B - 48 * C) *
+ ax + (8 * B + 24 * C)) / 6;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static double
+cubic_kernel (double x)
+{
+ /* This is the Mitchell-Netravali filter.
+ *
+ * (0.0, 0.5) would give us the Catmull-Rom spline,
+ * but that one seems to be indistinguishable from Lanczos2.
+ */
+ return general_cubic (x, 1/3.0, 1/3.0);
+}
+
+static const filter_info_t filters[] =
+{
+ { PIXMAN_KERNEL_IMPULSE, impulse_kernel, 0.0 },
+ { PIXMAN_KERNEL_BOX, box_kernel, 1.0 },
+ { PIXMAN_KERNEL_LINEAR, linear_kernel, 2.0 },
+ { PIXMAN_KERNEL_CUBIC, cubic_kernel, 4.0 },
+ { PIXMAN_KERNEL_GAUSSIAN, gaussian_kernel, 6 * SIGMA },
+ { PIXMAN_KERNEL_LANCZOS2, lanczos2_kernel, 4.0 },
+ { PIXMAN_KERNEL_LANCZOS3, lanczos3_kernel, 6.0 },
+ { PIXMAN_KERNEL_LANCZOS3_STRETCHED, nice_kernel, 8.0 },
+};
+
+/* This function scales @kernel2 by @scale, then
+ * aligns @x1 in @kernel1 with @x2 in @kernel2 and
+ * and integrates the product of the kernels across @width.
+ *
+ * This function assumes that the intervals are within
+ * the kernels in question. E.g., the caller must not
+ * try to integrate a linear kernel ouside of [-1:1]
+ */
+static double
+integral (pixman_kernel_t kernel1, double x1,
+ pixman_kernel_t kernel2, double scale, double x2,
+ double width)
+{
+ /* If the integration interval crosses zero, break it into
+ * two separate integrals. This ensures that filters such
+ * as LINEAR that are not differentiable at 0 will still
+ * integrate properly.
+ */
+ if (x1 < 0 && x1 + width > 0)
+ {
+ return
+ integral (kernel1, x1, kernel2, scale, x2, - x1) +
+ integral (kernel1, 0, kernel2, scale, x2 - x1, width + x1);
+ }
+ else if (x2 < 0 && x2 + width > 0)
+ {
+ return
+ integral (kernel1, x1, kernel2, scale, x2, - x2) +
+ integral (kernel1, x1 - x2, kernel2, scale, 0, width + x2);
+ }
+ else if (kernel1 == PIXMAN_KERNEL_IMPULSE)
+ {
+ assert (width == 0.0);
+ return filters[kernel2].func (x2 * scale);
+ }
+ else if (kernel2 == PIXMAN_KERNEL_IMPULSE)
+ {
+ assert (width == 0.0);
+ return filters[kernel1].func (x1);
+ }
+ else
+ {
+ /* Integration via Simpson's rule */
+#define N_SEGMENTS 128
+#define SAMPLE(a1, a2) \
+ (filters[kernel1].func ((a1)) * filters[kernel2].func ((a2) * scale))
+
+ double s = 0.0;
+ double h = width / (double)N_SEGMENTS;
+ int i;
+
+ s = SAMPLE (x1, x2);
+
+ for (i = 1; i < N_SEGMENTS; i += 2)
+ {
+ double a1 = x1 + h * i;
+ double a2 = x2 + h * i;
+
+ s += 2 * SAMPLE (a1, a2);
+
+ if (i >= 2 && i < N_SEGMENTS - 1)
+ s += 4 * SAMPLE (a1, a2);
+ }
+
+ s += SAMPLE (x1 + width, x2 + width);
+
+ return h * s * (1.0 / 3.0);
+ }
+}
+
+static pixman_fixed_t *
+create_1d_filter (int *width,
+ pixman_kernel_t reconstruct,
+ pixman_kernel_t sample,
+ double scale,
+ int n_phases)
+{
+ pixman_fixed_t *params, *p;
+ double step;
+ double size;
+ int i;
+
+ size = scale * filters[sample].width + filters[reconstruct].width;
+ *width = ceil (size);
+
+ p = params = malloc (*width * n_phases * sizeof (pixman_fixed_t));
+
+ step = 1.0 / n_phases;
+
+ for (i = 0; i < n_phases; ++i)
+ {
+ double frac = step / 2.0 + i * step;
+ pixman_fixed_t new_total;
+ int x, x1, x2;
+ double total;
+
+ /* Sample convolution of reconstruction and sampling
+ * filter. See rounding.txt regarding the rounding
+ * and sample positions.
+ */
+
+ x1 = ceil (frac - *width / 2.0 - 0.5);
+ x2 = x1 + *width;
+
+ total = 0;
+ for (x = x1; x < x2; ++x)
+ {
+ double pos = x + 0.5 - frac;
+ double rlow = - filters[reconstruct].width / 2.0;
+ double rhigh = rlow + filters[reconstruct].width;
+ double slow = pos - scale * filters[sample].width / 2.0;
+ double shigh = slow + scale * filters[sample].width;
+ double c = 0.0;
+ double ilow, ihigh;
+
+ if (rhigh >= slow && rlow <= shigh)
+ {
+ ilow = MAX (slow, rlow);
+ ihigh = MIN (shigh, rhigh);
+
+ c = integral (reconstruct, ilow,
+ sample, 1.0 / scale, ilow - pos,
+ ihigh - ilow);
+ }
+
+ total += c;
+ *p++ = (pixman_fixed_t)(c * 65535.0 + 0.5);
+ }
+
+ /* Normalize */
+ p -= *width;
+ total = 1 / total;
+ new_total = 0;
+ for (x = x1; x < x2; ++x)
+ {
+ pixman_fixed_t t = (*p) * total + 0.5;
+
+ new_total += t;
+ *p++ = t;
+ }
+
+ if (new_total != pixman_fixed_1)
+ *(p - *width / 2) += (pixman_fixed_1 - new_total);
+ }
+
+ return params;
+}
+
+/* Create the parameter list for a SEPARABLE_CONVOLUTION filter
+ * with the given kernels and scale parameters
+ */
+PIXMAN_EXPORT pixman_fixed_t *
+pixman_filter_create_separable_convolution (int *n_values,
+ pixman_fixed_t scale_x,
+ pixman_fixed_t scale_y,
+ pixman_kernel_t reconstruct_x,
+ pixman_kernel_t reconstruct_y,
+ pixman_kernel_t sample_x,
+ pixman_kernel_t sample_y,
+ int subsample_bits_x,
+ int subsample_bits_y)
+{
+ double sx = fabs (pixman_fixed_to_double (scale_x));
+ double sy = fabs (pixman_fixed_to_double (scale_y));
+ pixman_fixed_t *horz, *vert, *params;
+ int subsample_x, subsample_y;
+ int width, height;
+
+ subsample_x = (1 << subsample_bits_x);
+ subsample_y = (1 << subsample_bits_y);
+
+ horz = create_1d_filter (&width, reconstruct_x, sample_x, sx, subsample_x);
+ vert = create_1d_filter (&height, reconstruct_y, sample_y, sy, subsample_y);
+
+ *n_values = 4 + width * subsample_x + height * subsample_y;
+
+ params = malloc (*n_values * sizeof (pixman_fixed_t));
+
+ params[0] = pixman_int_to_fixed (width);
+ params[1] = pixman_int_to_fixed (height);
+ params[2] = pixman_int_to_fixed (subsample_bits_x);
+ params[3] = pixman_int_to_fixed (subsample_bits_y);
+
+ memcpy (params + 4, horz,
+ width * subsample_x * sizeof (pixman_fixed_t));
+ memcpy (params + 4 + width * subsample_x, vert,
+ height * subsample_y * sizeof (pixman_fixed_t));
+
+ free (horz);
+ free (vert);
+
+ return params;
+}
diff --git a/pixman/pixman/pixman-image.c b/pixman/pixman/pixman-image.c
index d9c303441..6f076d5c6 100644
--- a/pixman/pixman/pixman-image.c
+++ b/pixman/pixman/pixman-image.c
@@ -373,6 +373,10 @@ compute_image_info (pixman_image_t *image)
case PIXMAN_FILTER_CONVOLUTION:
break;
+ case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
+ flags |= FAST_PATH_SEPARABLE_CONVOLUTION_FILTER;
+ break;
+
default:
flags |= FAST_PATH_NO_CONVOLUTION_FILTER;
break;
@@ -515,8 +519,9 @@ compute_image_info (pixman_image_t *image)
* if all channels are opaque, so we simply turn it off
* unconditionally for those images.
*/
- if (image->common.alpha_map ||
- image->common.filter == PIXMAN_FILTER_CONVOLUTION ||
+ if (image->common.alpha_map ||
+ image->common.filter == PIXMAN_FILTER_CONVOLUTION ||
+ image->common.filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION ||
image->common.component_alpha)
{
flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE);
@@ -679,6 +684,19 @@ pixman_image_set_filter (pixman_image_t * image,
if (params == common->filter_params && filter == common->filter)
return TRUE;
+ if (filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION)
+ {
+ int width = pixman_fixed_to_int (params[0]);
+ int height = pixman_fixed_to_int (params[1]);
+ int x_phase_bits = pixman_fixed_to_int (params[2]);
+ int y_phase_bits = pixman_fixed_to_int (params[3]);
+ int n_x_phases = (1 << x_phase_bits);
+ int n_y_phases = (1 << y_phase_bits);
+
+ return_val_if_fail (
+ n_params == 4 + n_x_phases * width + n_y_phases * height, FALSE);
+ }
+
new_params = NULL;
if (params)
{
diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h
index c0a6bc0a5..99125a17e 100644
--- a/pixman/pixman/pixman-private.h
+++ b/pixman/pixman/pixman-private.h
@@ -687,6 +687,7 @@ _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
#define FAST_PATH_SAMPLES_COVER_CLIP_NEAREST (1 << 23)
#define FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR (1 << 24)
#define FAST_PATH_BITS_IMAGE (1 << 25)
+#define FAST_PATH_SEPARABLE_CONVOLUTION_FILTER (1 << 26)
#define FAST_PATH_PAD_REPEAT \
(FAST_PATH_NO_NONE_REPEAT | \
diff --git a/pixman/pixman/pixman.c b/pixman/pixman/pixman.c
index e0ccd87d8..0661f41b0 100644
--- a/pixman/pixman/pixman.c
+++ b/pixman/pixman/pixman.c
@@ -455,6 +455,14 @@ analyze_extent (pixman_image_t *image,
height = params[1];
break;
+ case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
+ params = image->common.filter_params;
+ x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
+ y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
+ width = params[0];
+ height = params[1];
+ break;
+
case PIXMAN_FILTER_GOOD:
case PIXMAN_FILTER_BEST:
case PIXMAN_FILTER_BILINEAR:
diff --git a/pixman/pixman/pixman.h b/pixman/pixman/pixman.h
index 33ebf3f64..7ff9fb52a 100644
--- a/pixman/pixman/pixman.h
+++ b/pixman/pixman/pixman.h
@@ -292,7 +292,28 @@ typedef enum
PIXMAN_FILTER_BEST,
PIXMAN_FILTER_NEAREST,
PIXMAN_FILTER_BILINEAR,
- PIXMAN_FILTER_CONVOLUTION
+ PIXMAN_FILTER_CONVOLUTION,
+
+ /* The SEPARABLE_CONVOLUTION filter takes the following parameters:
+ *
+ * width: integer given as 16.16 fixpoint number
+ * height: integer given as 16.16 fixpoint number
+ * x_phase_bits: integer given as 16.16 fixpoint
+ * y_phase_bits: integer given as 16.16 fixpoint
+ * xtables: (1 << x_phase_bits) tables of size width
+ * ytables: (1 << y_phase_bits) tables of size height
+ *
+ * When sampling at (x, y), the location is first rounded to one of
+ * n_x_phases * n_y_phases subpixel positions. These subpixel positions
+ * determine an xtable and a ytable to use.
+ *
+ * Conceptually a width x height matrix is then formed in which each entry
+ * is the product of the corresponding entries in the x and y tables.
+ * This matrix is then aligned with the image pixels such that its center
+ * is as close as possible to the subpixel location chosen earlier. Then
+ * the image is convolved with the matrix and the resulting pixel returned.
+ */
+ PIXMAN_FILTER_SEPARABLE_CONVOLUTION
} pixman_filter_t;
typedef enum
@@ -810,6 +831,33 @@ int pixman_image_get_height (pixman_image_t
int pixman_image_get_stride (pixman_image_t *image); /* in bytes */
int pixman_image_get_depth (pixman_image_t *image);
pixman_format_code_t pixman_image_get_format (pixman_image_t *image);
+
+typedef enum
+{
+ PIXMAN_KERNEL_IMPULSE,
+ PIXMAN_KERNEL_BOX,
+ PIXMAN_KERNEL_LINEAR,
+ PIXMAN_KERNEL_CUBIC,
+ PIXMAN_KERNEL_GAUSSIAN,
+ PIXMAN_KERNEL_LANCZOS2,
+ PIXMAN_KERNEL_LANCZOS3,
+ PIXMAN_KERNEL_LANCZOS3_STRETCHED /* Jim Blinn's 'nice' filter */
+} pixman_kernel_t;
+
+/* Create the parameter list for a SEPARABLE_CONVOLUTION filter
+ * with the given kernels and scale parameters.
+ */
+pixman_fixed_t *
+pixman_filter_create_separable_convolution (int *n_values,
+ pixman_fixed_t scale_x,
+ pixman_fixed_t scale_y,
+ pixman_kernel_t reconstruct_x,
+ pixman_kernel_t reconstruct_y,
+ pixman_kernel_t sample_x,
+ pixman_kernel_t sample_y,
+ int subsample_bits_x,
+ int subsample_bits_y);
+
pixman_bool_t pixman_image_fill_rectangles (pixman_op_t op,
pixman_image_t *image,
const pixman_color_t *color,
diff --git a/pixman/pixman/rounding.txt b/pixman/pixman/rounding.txt
index 1a19f450f..b52b08439 100644
--- a/pixman/pixman/rounding.txt
+++ b/pixman/pixman/rounding.txt
@@ -132,3 +132,36 @@ And so the final formula for the index k of x0 in the image is:
Computing the result is then simply a matter of convolving all the
pixels starting at k with all the samples in the matrix.
+
+
+--- SEPARABLE_CONVOLUTION
+
+For this filter, x is first rounded to one of n regularly spaced
+subpixel positions. This subpixel position determines which of n
+convolution matrices is being used.
+
+Then, as in a regular convolution filter, the first pixel to be used
+is determined:
+
+ k = floor (x - (width - 1) / 2.0 - e)
+
+and then the image pixels starting there are convolved with the chosen
+matrix. If we write x = xi + frac, where xi is an integer, we get
+
+ k = xi + floor (frac - (width - 1) / 2.0 - e)
+
+so the location of k relative to x is given by:
+
+ (k + 0.5 - x) = xi + floor (frac - (width - 1) / 2.0 - e) + 0.5 - x
+
+ = floor (frac - (width - 1) / 2.0 - e) + 0.5 - frac
+
+which means the contents of the matrix corresponding to (frac) should
+contain width samplings of the function, with the first sample at:
+
+ floor (frac - (width - 1) / 2.0 - e) + 0.5 - frac
+
+This filter is called separable because each of the k x k convolution
+matrices is specified with two k-wide vectors, one for each dimension,
+where each entry in the matrix is computed as the product of the
+corresponding entries in the vectors.
diff --git a/pixman/test/Makefile.sources b/pixman/test/Makefile.sources
index 077897161..8c0b505df 100644
--- a/pixman/test/Makefile.sources
+++ b/pixman/test/Makefile.sources
@@ -1,5 +1,6 @@
# Tests (sorted by expected completion time)
TESTPROGRAMS = \
+ prng-test \
a1-trap-test \
pdf-op-test \
region-test \
@@ -33,8 +34,10 @@ BENCHMARKS = \
# Utility functions
libutils_sources = \
utils.c \
+ utils-prng.c \
$(NULL)
libutils_headers = \
utils.h \
+ utils-prng.h \
$(NULL)
diff --git a/pixman/test/affine-test.c b/pixman/test/affine-test.c
index daa86c81d..f60ec14eb 100644
--- a/pixman/test/affine-test.c
+++ b/pixman/test/affine-test.c
@@ -48,18 +48,18 @@ test_composite (int testnum,
uint32_t crc32;
FLOAT_REGS_CORRUPTION_DETECTOR_START ();
- lcg_srand (testnum);
+ prng_srand (testnum);
- src_bpp = (lcg_rand_n (2) == 0) ? 2 : 4;
- dst_bpp = (lcg_rand_n (2) == 0) ? 2 : 4;
- op = (lcg_rand_n (2) == 0) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER;
+ src_bpp = (prng_rand_n (2) == 0) ? 2 : 4;
+ dst_bpp = (prng_rand_n (2) == 0) ? 2 : 4;
+ op = (prng_rand_n (2) == 0) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER;
- src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1;
- src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1;
- dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1;
- dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1;
- src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp;
- dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp;
+ src_width = prng_rand_n (MAX_SRC_WIDTH) + 1;
+ src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1;
+ dst_width = prng_rand_n (MAX_DST_WIDTH) + 1;
+ dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1;
+ src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp;
+ dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp;
if (src_stride & 3)
src_stride += 2;
@@ -67,26 +67,23 @@ test_composite (int testnum,
if (dst_stride & 3)
dst_stride += 2;
- src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2);
- src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2);
- dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2);
- dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2);
- w = lcg_rand_n (dst_width * 3 / 2 - dst_x);
- h = lcg_rand_n (dst_height * 3 / 2 - dst_y);
+ src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2);
+ src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2);
+ dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2);
+ dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2);
+ w = prng_rand_n (dst_width * 3 / 2 - dst_x);
+ h = prng_rand_n (dst_height * 3 / 2 - dst_y);
srcbuf = (uint32_t *)malloc (src_stride * src_height);
dstbuf = (uint32_t *)malloc (dst_stride * dst_height);
- for (i = 0; i < src_stride * src_height; i++)
- *((uint8_t *)srcbuf + i) = lcg_rand_n (256);
+ prng_randmemset (srcbuf, src_stride * src_height, 0);
+ prng_randmemset (dstbuf, dst_stride * dst_height, 0);
- for (i = 0; i < dst_stride * dst_height; i++)
- *((uint8_t *)dstbuf + i) = lcg_rand_n (256);
-
- src_fmt = src_bpp == 4 ? (lcg_rand_n (2) == 0 ?
+ src_fmt = src_bpp == 4 ? (prng_rand_n (2) == 0 ?
PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;
- dst_fmt = dst_bpp == 4 ? (lcg_rand_n (2) == 0 ?
+ dst_fmt = dst_bpp == 4 ? (prng_rand_n (2) == 0 ?
PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;
src_img = pixman_image_create_bits (
@@ -100,29 +97,29 @@ test_composite (int testnum,
pixman_transform_init_identity (&transform);
- if (lcg_rand_n (3) > 0)
+ if (prng_rand_n (3) > 0)
{
- scale_x = -65536 * 3 + lcg_rand_N (65536 * 6);
- if (lcg_rand_n (2))
- scale_y = -65536 * 3 + lcg_rand_N (65536 * 6);
+ scale_x = -65536 * 3 + prng_rand_n (65536 * 6);
+ if (prng_rand_n (2))
+ scale_y = -65536 * 3 + prng_rand_n (65536 * 6);
else
scale_y = scale_x;
pixman_transform_init_scale (&transform, scale_x, scale_y);
}
- if (lcg_rand_n (3) > 0)
+ if (prng_rand_n (3) > 0)
{
- translate_x = -65536 * 3 + lcg_rand_N (6 * 65536);
- if (lcg_rand_n (2))
- translate_y = -65536 * 3 + lcg_rand_N (6 * 65536);
+ translate_x = -65536 * 3 + prng_rand_n (6 * 65536);
+ if (prng_rand_n (2))
+ translate_y = -65536 * 3 + prng_rand_n (6 * 65536);
else
translate_y = translate_x;
pixman_transform_translate (&transform, NULL, translate_x, translate_y);
}
- if (lcg_rand_n (4) > 0)
+ if (prng_rand_n (4) > 0)
{
int c, s, tx = 0, ty = 0;
- switch (lcg_rand_n (4))
+ switch (prng_rand_n (4))
{
case 0:
/* 90 degrees */
@@ -145,32 +142,32 @@ test_composite (int testnum,
break;
default:
/* arbitrary rotation */
- c = lcg_rand_N (2 * 65536) - 65536;
- s = lcg_rand_N (2 * 65536) - 65536;
+ c = prng_rand_n (2 * 65536) - 65536;
+ s = prng_rand_n (2 * 65536) - 65536;
break;
}
pixman_transform_rotate (&transform, NULL, c, s);
pixman_transform_translate (&transform, NULL, tx, ty);
}
- if (lcg_rand_n (8) == 0)
+ if (prng_rand_n (8) == 0)
{
/* Flip random bits */
int maxflipcount = 8;
while (maxflipcount--)
{
- int i = lcg_rand_n (2);
- int j = lcg_rand_n (3);
- int bitnum = lcg_rand_n (32);
+ int i = prng_rand_n (2);
+ int j = prng_rand_n (3);
+ int bitnum = prng_rand_n (32);
transform.matrix[i][j] ^= 1 << bitnum;
- if (lcg_rand_n (2))
+ if (prng_rand_n (2))
break;
}
}
pixman_image_set_transform (src_img, &transform);
- switch (lcg_rand_n (4))
+ switch (prng_rand_n (4))
{
case 0:
repeat = PIXMAN_REPEAT_NONE;
@@ -193,7 +190,7 @@ test_composite (int testnum,
}
pixman_image_set_repeat (src_img, repeat);
- if (lcg_rand_n (2))
+ if (prng_rand_n (2))
pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0);
else
pixman_image_set_filter (src_img, PIXMAN_FILTER_BILINEAR, NULL, 0);
@@ -220,19 +217,19 @@ test_composite (int testnum,
printf ("w=%d, h=%d\n", w, h);
}
- if (lcg_rand_n (8) == 0)
+ if (prng_rand_n (8) == 0)
{
pixman_box16_t clip_boxes[2];
- int n = lcg_rand_n (2) + 1;
+ int n = prng_rand_n (2) + 1;
for (i = 0; i < n; i++)
{
- clip_boxes[i].x1 = lcg_rand_n (src_width);
- clip_boxes[i].y1 = lcg_rand_n (src_height);
+ clip_boxes[i].x1 = prng_rand_n (src_width);
+ clip_boxes[i].y1 = prng_rand_n (src_height);
clip_boxes[i].x2 =
- clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1);
+ clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1);
clip_boxes[i].y2 =
- clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1);
+ clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1);
if (verbose)
{
@@ -248,18 +245,18 @@ test_composite (int testnum,
pixman_region_fini (&clip);
}
- if (lcg_rand_n (8) == 0)
+ if (prng_rand_n (8) == 0)
{
pixman_box16_t clip_boxes[2];
- int n = lcg_rand_n (2) + 1;
+ int n = prng_rand_n (2) + 1;
for (i = 0; i < n; i++)
{
- clip_boxes[i].x1 = lcg_rand_n (dst_width);
- clip_boxes[i].y1 = lcg_rand_n (dst_height);
+ clip_boxes[i].x1 = prng_rand_n (dst_width);
+ clip_boxes[i].y1 = prng_rand_n (dst_height);
clip_boxes[i].x2 =
- clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1);
+ clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1);
clip_boxes[i].y2 =
- clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1);
+ clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1);
if (verbose)
{
@@ -310,11 +307,11 @@ test_composite (int testnum,
}
#if BILINEAR_INTERPOLATION_BITS == 8
-#define CHECKSUM 0x344413F0
+#define CHECKSUM 0x97097336
#elif BILINEAR_INTERPOLATION_BITS == 7
-#define CHECKSUM 0xC8181A76
+#define CHECKSUM 0x31D2DC21
#elif BILINEAR_INTERPOLATION_BITS == 4
-#define CHECKSUM 0xD672A457
+#define CHECKSUM 0x8B925154
#else
#define CHECKSUM 0x00000000
#endif
diff --git a/pixman/test/alpha-loop.c b/pixman/test/alpha-loop.c
index e4d90a988..eca761537 100644
--- a/pixman/test/alpha-loop.c
+++ b/pixman/test/alpha-loop.c
@@ -8,9 +8,14 @@
int
main (int argc, char **argv)
{
- uint8_t *alpha = make_random_bytes (WIDTH * HEIGHT);
- uint32_t *src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
- uint32_t *dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+ uint8_t *alpha;
+ uint32_t *src, *dest;
+
+ prng_srand (0);
+
+ alpha = make_random_bytes (WIDTH * HEIGHT);
+ src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+ dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
pixman_image_t *a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, (uint32_t *)alpha, WIDTH);
pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4);
diff --git a/pixman/test/alphamap.c b/pixman/test/alphamap.c
index 0c5757ea3..1a6fca55a 100644
--- a/pixman/test/alphamap.c
+++ b/pixman/test/alphamap.c
@@ -307,6 +307,8 @@ main (int argc, char **argv)
{
int i, j, a, b, x, y;
+ prng_srand (0);
+
for (i = 0; i < ARRAY_LENGTH (formats); ++i)
{
for (j = 0; j < ARRAY_LENGTH (formats); ++j)
diff --git a/pixman/test/blitters-test.c b/pixman/test/blitters-test.c
index 30d69124c..9bde99c62 100644
--- a/pixman/test/blitters-test.c
+++ b/pixman/test/blitters-test.c
@@ -25,7 +25,7 @@ create_random_image (pixman_format_code_t *allowed_formats,
int max_extra_stride,
pixman_format_code_t *used_fmt)
{
- int n = 0, i, width, height, stride;
+ int n = 0, width, height, stride;
pixman_format_code_t fmt;
uint32_t *buf;
pixman_image_t *img;
@@ -33,28 +33,20 @@ create_random_image (pixman_format_code_t *allowed_formats,
while (allowed_formats[n] != PIXMAN_null)
n++;
- if (n > N_MOST_LIKELY_FORMATS && lcg_rand_n (4) != 0)
+ if (n > N_MOST_LIKELY_FORMATS && prng_rand_n (4) != 0)
n = N_MOST_LIKELY_FORMATS;
- fmt = allowed_formats[lcg_rand_n (n)];
+ fmt = allowed_formats[prng_rand_n (n)];
- width = lcg_rand_n (max_width) + 1;
- height = lcg_rand_n (max_height) + 1;
+ width = prng_rand_n (max_width) + 1;
+ height = prng_rand_n (max_height) + 1;
stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 +
- lcg_rand_n (max_extra_stride + 1);
+ prng_rand_n (max_extra_stride + 1);
stride = (stride + 3) & ~3;
/* do the allocation */
buf = aligned_malloc (64, stride * height);
- /* initialize image with random data */
- for (i = 0; i < stride * height; i++)
- {
- /* generation is biased to having more 0 or 255 bytes as
- * they are more likely to be special-cased in code
- */
- *((uint8_t *)buf + i) = lcg_rand_n (4) ? lcg_rand_n (256) :
- (lcg_rand_n (2) ? 0 : 255);
- }
+ prng_randmemset (buf, stride * height, RANDMEMSET_MORE_00_AND_FF);
img = pixman_image_create_bits (fmt, width, height, buf, stride);
@@ -67,7 +59,7 @@ create_random_image (pixman_format_code_t *allowed_formats,
pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)]));
}
- if (lcg_rand_n (16) == 0)
+ if (prng_rand_n (16) == 0)
pixman_image_set_filter (img, PIXMAN_FILTER_BILINEAR, NULL, 0);
image_endian_swap (img);
@@ -251,11 +243,11 @@ test_composite (int testnum, int verbose)
if (max_extra_stride > 8)
max_extra_stride = 8;
- lcg_srand (testnum);
+ prng_srand (testnum);
- op = op_list[lcg_rand_n (ARRAY_LENGTH (op_list))];
+ op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))];
- if (lcg_rand_n (8))
+ if (prng_rand_n (8))
{
/* normal image */
src_img = create_random_image (img_fmt_list, max_width, max_height,
@@ -284,10 +276,10 @@ test_composite (int testnum, int verbose)
dstbuf = pixman_image_get_data (dst_img);
srcbuf = pixman_image_get_data (src_img);
- src_x = lcg_rand_n (src_width);
- src_y = lcg_rand_n (src_height);
- dst_x = lcg_rand_n (dst_width);
- dst_y = lcg_rand_n (dst_height);
+ src_x = prng_rand_n (src_width);
+ src_y = prng_rand_n (src_height);
+ dst_x = prng_rand_n (dst_width);
+ dst_y = prng_rand_n (dst_height);
mask_img = NULL;
mask_fmt = PIXMAN_null;
@@ -296,10 +288,10 @@ test_composite (int testnum, int verbose)
maskbuf = NULL;
if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) &&
- (lcg_rand_n (4) == 0))
+ (prng_rand_n (4) == 0))
{
/* PIXBUF */
- mask_fmt = lcg_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
+ mask_fmt = prng_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
mask_img = pixman_image_create_bits (mask_fmt,
src_width,
src_height,
@@ -309,9 +301,9 @@ test_composite (int testnum, int verbose)
mask_y = src_y;
maskbuf = srcbuf;
}
- else if (lcg_rand_n (2))
+ else if (prng_rand_n (2))
{
- if (lcg_rand_n (2))
+ if (prng_rand_n (2))
{
mask_img = create_random_image (mask_fmt_list, max_width, max_height,
max_extra_stride, &mask_fmt);
@@ -324,16 +316,16 @@ test_composite (int testnum, int verbose)
pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
}
- if (lcg_rand_n (2))
+ if (prng_rand_n (2))
pixman_image_set_component_alpha (mask_img, 1);
- mask_x = lcg_rand_n (pixman_image_get_width (mask_img));
- mask_y = lcg_rand_n (pixman_image_get_height (mask_img));
+ mask_x = prng_rand_n (pixman_image_get_width (mask_img));
+ mask_y = prng_rand_n (pixman_image_get_height (mask_img));
}
- w = lcg_rand_n (dst_width - dst_x + 1);
- h = lcg_rand_n (dst_height - dst_y + 1);
+ w = prng_rand_n (dst_width - dst_x + 1);
+ h = prng_rand_n (dst_height - dst_y + 1);
if (verbose)
{
@@ -390,6 +382,8 @@ main (int argc, const char *argv[])
{
int i;
+ prng_srand (0);
+
for (i = 1; i <= 8; i++)
{
initialize_palette (&(rgb_palette[i]), i, TRUE);
@@ -397,6 +391,6 @@ main (int argc, const char *argv[])
}
return fuzzer_test_main("blitters", 2000000,
- 0x46136E0A,
+ 0xD8265D5E,
test_composite, argc, argv);
}
diff --git a/pixman/test/combiner-test.c b/pixman/test/combiner-test.c
index c438ae62e..01f63a56e 100644
--- a/pixman/test/combiner-test.c
+++ b/pixman/test/combiner-test.c
@@ -67,7 +67,7 @@ static const pixman_op_t op_list[] =
static float
rand_float (void)
{
- uint32_t u = lcg_rand_u32();
+ uint32_t u = prng_rand();
return *(float *)&u;
}
@@ -123,7 +123,7 @@ main ()
impl = _pixman_internal_only_get_implementation();
- lcg_srand (0);
+ prng_srand (0);
for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
{
diff --git a/pixman/test/composite-traps-test.c b/pixman/test/composite-traps-test.c
index 9fc94a4d6..2983eae83 100644
--- a/pixman/test/composite-traps-test.c
+++ b/pixman/test/composite-traps-test.c
@@ -26,7 +26,7 @@ static pixman_op_t operators[] =
};
#define RANDOM_ELT(array) \
- ((array)[lcg_rand_n(ARRAY_LENGTH((array)))])
+ ((array)[prng_rand_n(ARRAY_LENGTH((array)))])
static void
destroy_bits (pixman_image_t *image, void *data)
@@ -37,7 +37,7 @@ destroy_bits (pixman_image_t *image, void *data)
static pixman_fixed_t
random_fixed (int n)
{
- return lcg_rand_N (n << 16);
+ return prng_rand_n (n << 16);
}
/*
@@ -75,17 +75,17 @@ test_composite (int testnum,
FLOAT_REGS_CORRUPTION_DETECTOR_START ();
- lcg_srand (testnum);
+ prng_srand (testnum);
op = RANDOM_ELT (operators);
mask_format = RANDOM_ELT (mask_formats);
/* Create source image */
- if (lcg_rand_n (4) == 0)
+ if (prng_rand_n (4) == 0)
{
src_img = pixman_image_create_solid_fill (
- &(colors[lcg_rand_n (ARRAY_LENGTH (colors))]));
+ &(colors[prng_rand_n (ARRAY_LENGTH (colors))]));
src_x = 10;
src_y = 234;
@@ -94,13 +94,13 @@ test_composite (int testnum,
{
pixman_format_code_t src_format = RANDOM_ELT(formats);
int src_bpp = (PIXMAN_FORMAT_BPP (src_format) + 7) / 8;
- int src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1;
- int src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1;
- int src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp;
+ int src_width = prng_rand_n (MAX_SRC_WIDTH) + 1;
+ int src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1;
+ int src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp;
uint32_t *bits;
- src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2);
- src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2);
+ src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2);
+ src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2);
src_stride = (src_stride + 3) & ~3;
@@ -111,19 +111,19 @@ test_composite (int testnum,
pixman_image_set_destroy_function (src_img, destroy_bits, bits);
- if (lcg_rand_n (8) == 0)
+ if (prng_rand_n (8) == 0)
{
pixman_box16_t clip_boxes[2];
- int n = lcg_rand_n (2) + 1;
+ int n = prng_rand_n (2) + 1;
for (i = 0; i < n; i++)
{
- clip_boxes[i].x1 = lcg_rand_n (src_width);
- clip_boxes[i].y1 = lcg_rand_n (src_height);
+ clip_boxes[i].x1 = prng_rand_n (src_width);
+ clip_boxes[i].y1 = prng_rand_n (src_height);
clip_boxes[i].x2 =
- clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1);
+ clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1);
clip_boxes[i].y2 =
- clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1);
+ clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1);
if (verbose)
{
@@ -146,15 +146,15 @@ test_composite (int testnum,
{
dst_format = RANDOM_ELT(formats);
dst_bpp = (PIXMAN_FORMAT_BPP (dst_format) + 7) / 8;
- dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1;
- dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1;
- dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp;
+ dst_width = prng_rand_n (MAX_DST_WIDTH) + 1;
+ dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1;
+ dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp;
dst_stride = (dst_stride + 3) & ~3;
dst_bits = (uint32_t *)make_random_bytes (dst_stride * dst_height);
- dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2);
- dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2);
+ dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2);
+ dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2);
dst_img = pixman_image_create_bits (
dst_format, dst_width, dst_height, dst_bits, dst_stride);
@@ -166,7 +166,7 @@ test_composite (int testnum,
{
int i;
- n_traps = lcg_rand_n (25);
+ n_traps = prng_rand_n (25);
traps = fence_malloc (n_traps * sizeof (pixman_trapezoid_t));
for (i = 0; i < n_traps; ++i)
@@ -186,18 +186,18 @@ test_composite (int testnum,
}
}
- if (lcg_rand_n (8) == 0)
+ if (prng_rand_n (8) == 0)
{
pixman_box16_t clip_boxes[2];
- int n = lcg_rand_n (2) + 1;
+ int n = prng_rand_n (2) + 1;
for (i = 0; i < n; i++)
{
- clip_boxes[i].x1 = lcg_rand_n (dst_width);
- clip_boxes[i].y1 = lcg_rand_n (dst_height);
+ clip_boxes[i].x1 = prng_rand_n (dst_width);
+ clip_boxes[i].y1 = prng_rand_n (dst_height);
clip_boxes[i].x2 =
- clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1);
+ clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1);
clip_boxes[i].y2 =
- clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1);
+ clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1);
if (verbose)
{
@@ -251,6 +251,6 @@ test_composite (int testnum,
int
main (int argc, const char *argv[])
{
- return fuzzer_test_main("composite traps", 40000, 0x33BFAA55,
+ return fuzzer_test_main("composite traps", 40000, 0x749BCC57,
test_composite, argc, argv);
}
diff --git a/pixman/test/composite.c b/pixman/test/composite.c
index 2930fb75b..09752c5c7 100644
--- a/pixman/test/composite.c
+++ b/pixman/test/composite.c
@@ -725,19 +725,19 @@ image_fini (image_t *info)
static int
random_size (void)
{
- return lcg_rand_n (ARRAY_LENGTH (sizes));
+ return prng_rand_n (ARRAY_LENGTH (sizes));
}
static int
random_color (void)
{
- return lcg_rand_n (ARRAY_LENGTH (colors));
+ return prng_rand_n (ARRAY_LENGTH (colors));
}
static int
random_format (void)
{
- return lcg_rand_n (ARRAY_LENGTH (formats));
+ return prng_rand_n (ARRAY_LENGTH (formats));
}
static pixman_bool_t
@@ -748,15 +748,15 @@ run_test (uint32_t seed)
int ca;
int ok;
- lcg_srand (seed);
+ prng_srand (seed);
image_init (&dst, random_color(), random_format(), 1);
image_init (&src, random_color(), random_format(), random_size());
image_init (&mask, random_color(), random_format(), random_size());
- op = &(operators [lcg_rand_n (ARRAY_LENGTH (operators))]);
+ op = &(operators [prng_rand_n (ARRAY_LENGTH (operators))]);
- ca = lcg_rand_n (3);
+ ca = prng_rand_n (3);
switch (ca)
{
diff --git a/pixman/test/glyph-test.c b/pixman/test/glyph-test.c
index 501cc2e6f..1811add73 100644
--- a/pixman/test/glyph-test.c
+++ b/pixman/test/glyph-test.c
@@ -107,7 +107,7 @@ random_format (const pixman_format_code_t *formats)
i = 0;
while (formats[i] != PIXMAN_null)
++i;
- return formats[lcg_rand_n (i)];
+ return formats[prng_rand_n (i)];
}
static pixman_image_t *
@@ -122,27 +122,27 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
int i;
pixman_image_destroy_func_t destroy;
- if ((flags & ALLOW_SOLID) && lcg_rand_n (4) == 0)
+ if ((flags & ALLOW_SOLID) && prng_rand_n (4) == 0)
{
pixman_color_t color;
- color.alpha = lcg_rand_u32();
- color.red = lcg_rand_u32();
- color.green = lcg_rand_u32();
- color.blue = lcg_rand_u32();
+ color.alpha = prng_rand();
+ color.red = prng_rand();
+ color.green = prng_rand();
+ color.blue = prng_rand();
return pixman_image_create_solid_fill (&color);
}
- width = lcg_rand_n (max_size) + 1;
- height = lcg_rand_n (max_size) + 1;
+ width = prng_rand_n (max_size) + 1;
+ height = prng_rand_n (max_size) + 1;
format = random_format (formats);
bpp = PIXMAN_FORMAT_BPP (format);
- stride = (width * bpp + 7) / 8 + lcg_rand_n (17);
+ stride = (width * bpp + 7) / 8 + prng_rand_n (17);
stride = (stride + 3) & ~3;
- if (lcg_rand_n (64) == 0)
+ if (prng_rand_n (64) == 0)
{
if (!(data = (uint32_t *)make_random_bytes (stride * height)))
{
@@ -153,34 +153,28 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
}
else
{
- uint8_t *d8;
-
data = malloc (stride * height);
-
- d8 = (uint8_t *)data;
- for (i = 0; i < height * stride; ++i)
- d8[i] = lcg_rand_n (256);
-
+ prng_randmemset (data, height * stride, 0);
destroy = destroy_malloced;
}
image = pixman_image_create_bits (format, width, height, data, stride);
pixman_image_set_destroy_function (image, destroy, data);
- if ((flags & ALLOW_CLIPPED) && lcg_rand_n (8) == 0)
+ if ((flags & ALLOW_CLIPPED) && prng_rand_n (8) == 0)
{
pixman_box16_t clip_boxes[8];
pixman_region16_t clip;
- int n = lcg_rand_n (8) + 1;
+ int n = prng_rand_n (8) + 1;
for (i = 0; i < n; i++)
{
- clip_boxes[i].x1 = lcg_rand_n (width);
- clip_boxes[i].y1 = lcg_rand_n (height);
+ clip_boxes[i].x1 = prng_rand_n (width);
+ clip_boxes[i].y1 = prng_rand_n (height);
clip_boxes[i].x2 =
- clip_boxes[i].x1 + lcg_rand_n (width - clip_boxes[i].x1);
+ clip_boxes[i].x1 + prng_rand_n (width - clip_boxes[i].x1);
clip_boxes[i].y2 =
- clip_boxes[i].y1 + lcg_rand_n (height - clip_boxes[i].y1);
+ clip_boxes[i].y1 + prng_rand_n (height - clip_boxes[i].y1);
}
pixman_region_init_rects (&clip, clip_boxes, n);
@@ -188,27 +182,27 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
pixman_region_fini (&clip);
}
- if ((flags & ALLOW_SOURCE_CLIPPING) && lcg_rand_n (4) == 0)
+ if ((flags & ALLOW_SOURCE_CLIPPING) && prng_rand_n (4) == 0)
{
pixman_image_set_source_clipping (image, TRUE);
pixman_image_set_has_client_clip (image, TRUE);
}
- if ((flags & ALLOW_ALPHA_MAP) && lcg_rand_n (16) == 0)
+ if ((flags & ALLOW_ALPHA_MAP) && prng_rand_n (16) == 0)
{
pixman_image_t *alpha_map;
int alpha_x, alpha_y;
- alpha_x = lcg_rand_n (width);
- alpha_y = lcg_rand_n (height);
+ alpha_x = prng_rand_n (width);
+ alpha_y = prng_rand_n (height);
alpha_map =
create_image (max_size, formats, (flags & ~(ALLOW_ALPHA_MAP | ALLOW_SOLID)));
pixman_image_set_alpha_map (image, alpha_map, alpha_x, alpha_y);
pixman_image_unref (alpha_map);
}
- if ((flags & ALLOW_REPEAT) && lcg_rand_n (2) == 0)
- pixman_image_set_repeat (image, lcg_rand_n (4));
+ if ((flags & ALLOW_REPEAT) && prng_rand_n (2) == 0)
+ pixman_image_set_repeat (image, prng_rand_n (4));
image_endian_swap (image);
@@ -230,7 +224,7 @@ test_glyphs (int testnum, int verbose)
int n_glyphs, i;
pixman_glyph_cache_t *cache;
- lcg_srand (testnum);
+ prng_srand (testnum);
cache = pixman_glyph_cache_create ();
@@ -245,13 +239,13 @@ test_glyphs (int testnum, int verbose)
pixman_glyph_cache_freeze (cache);
- n_glyphs = lcg_rand_n (MAX_GLYPHS);
+ n_glyphs = prng_rand_n (MAX_GLYPHS);
for (i = 0; i < n_glyphs; ++i)
glyph_images[i] = create_image (32, glyph_formats, 0);
for (i = 0; i < 4 * n_glyphs; ++i)
{
- int g = lcg_rand_n (n_glyphs);
+ int g = prng_rand_n (n_glyphs);
pixman_image_t *glyph_img = glyph_images[g];
void *key1 = KEY1 (glyph_img);
void *key2 = KEY2 (glyph_img);
@@ -264,21 +258,21 @@ test_glyphs (int testnum, int verbose)
}
glyphs[i].glyph = glyph;
- glyphs[i].x = lcg_rand_n (128);
- glyphs[i].y = lcg_rand_n (128);
+ glyphs[i].x = prng_rand_n (128);
+ glyphs[i].y = prng_rand_n (128);
}
- if (lcg_rand_n (2) == 0)
+ if (prng_rand_n (2) == 0)
{
- int src_x = lcg_rand_n (300) - 150;
- int src_y = lcg_rand_n (300) - 150;
- int mask_x = lcg_rand_n (64) - 32;
- int mask_y = lcg_rand_n (64) - 32;
- int dest_x = lcg_rand_n (64) - 32;
- int dest_y = lcg_rand_n (64) - 32;
- int width = lcg_rand_n (64);
- int height = lcg_rand_n (64);
- pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))];
+ int src_x = prng_rand_n (300) - 150;
+ int src_y = prng_rand_n (300) - 150;
+ int mask_x = prng_rand_n (64) - 32;
+ int mask_y = prng_rand_n (64) - 32;
+ int dest_x = prng_rand_n (64) - 32;
+ int dest_y = prng_rand_n (64) - 32;
+ int width = prng_rand_n (64);
+ int height = prng_rand_n (64);
+ pixman_op_t op = operators[prng_rand_n (ARRAY_LENGTH (operators))];
pixman_format_code_t format = random_format (glyph_formats);
pixman_composite_glyphs (
@@ -292,11 +286,11 @@ test_glyphs (int testnum, int verbose)
}
else
{
- pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))];
- int src_x = lcg_rand_n (300) - 150;
- int src_y = lcg_rand_n (300) - 150;
- int dest_x = lcg_rand_n (64) - 32;
- int dest_y = lcg_rand_n (64) - 32;
+ pixman_op_t op = operators[prng_rand_n (ARRAY_LENGTH (operators))];
+ int src_x = prng_rand_n (300) - 150;
+ int src_y = prng_rand_n (300) - 150;
+ int dest_x = prng_rand_n (64) - 32;
+ int dest_y = prng_rand_n (64) - 32;
pixman_composite_glyphs_no_mask (
op, source, dest,
@@ -333,6 +327,6 @@ int
main (int argc, const char *argv[])
{
return fuzzer_test_main ("glyph", 30000,
- 0x79E74996,
+ 0xFA478A79,
test_glyphs, argc, argv);
}
diff --git a/pixman/test/prng-test.c b/pixman/test/prng-test.c
new file mode 100644
index 000000000..0a3ad5e8f
--- /dev/null
+++ b/pixman/test/prng-test.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2012 Siarhei Siamashka <siarhei.siamashka@gmail.com>
+ *
+ * Based on the public domain implementation of small noncryptographic PRNG
+ * authored by Bob Jenkins: http://burtleburtle.net/bob/rand/smallprng.html
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include "utils-prng.h"
+#include "utils.h"
+
+/* The original code from http://www.burtleburtle.net/bob/rand/smallprng.html */
+
+typedef uint32_t u4;
+typedef struct ranctx { u4 a; u4 b; u4 c; u4 d; } ranctx;
+
+#define rot(x,k) (((x)<<(k))|((x)>>(32-(k))))
+u4 ranval( ranctx *x ) {
+ u4 e = x->a - rot(x->b, 27);
+ x->a = x->b ^ rot(x->c, 17);
+ x->b = x->c + x->d;
+ x->c = x->d + e;
+ x->d = e + x->a;
+ return x->d;
+}
+
+void raninit( ranctx *x, u4 seed ) {
+ u4 i;
+ x->a = 0xf1ea5eed, x->b = x->c = x->d = seed;
+ for (i=0; i<20; ++i) {
+ (void)ranval(x);
+ }
+}
+
+/*****************************************************************************/
+
+#define BUFSIZE (8 * 1024 * 1024)
+#define N 50
+
+void bench (void)
+{
+ double t1, t2;
+ int i;
+ prng_t prng;
+ uint8_t *buf = aligned_malloc (16, BUFSIZE + 1);
+
+ prng_srand_r (&prng, 1234);
+ t1 = gettime();
+ for (i = 0; i < N; i++)
+ prng_randmemset_r (&prng, buf, BUFSIZE, 0);
+ t2 = gettime();
+ printf ("aligned randmemset : %.2f MB/s\n",
+ (double)BUFSIZE * N / 1000000. / (t2 - t1));
+
+ t1 = gettime();
+ for (i = 0; i < N; i++)
+ prng_randmemset_r (&prng, buf + 1, BUFSIZE, 0);
+ t2 = gettime();
+ printf ("unaligned randmemset : %.2f MB/s\n",
+ (double)BUFSIZE * N / 1000000. / (t2 - t1));
+
+ t1 = gettime();
+ for (i = 0; i < N; i++)
+ {
+ prng_randmemset_r (&prng, buf, BUFSIZE, RANDMEMSET_MORE_00_AND_FF);
+ }
+ t2 = gettime ();
+ printf ("aligned randmemset (more 00 and FF) : %.2f MB/s\n",
+ (double)BUFSIZE * N / 1000000. / (t2 - t1));
+
+ t1 = gettime();
+ for (i = 0; i < N; i++)
+ {
+ prng_randmemset_r (&prng, buf + 1, BUFSIZE, RANDMEMSET_MORE_00_AND_FF);
+ }
+ t2 = gettime ();
+ printf ("unaligned randmemset (more 00 and FF) : %.2f MB/s\n",
+ (double)BUFSIZE * N / 1000000. / (t2 - t1));
+
+ free (buf);
+}
+
+#define SMALLBUFSIZE 100
+
+int main (int argc, char *argv[])
+{
+ const uint32_t ref_crc[RANDMEMSET_MORE_00_AND_FF + 1] =
+ {
+ 0xBA06763D, 0x103FC550, 0x8B59ABA5, 0xD82A0F39
+ };
+ uint32_t crc1, crc2;
+ uint32_t ref, seed, seed0, seed1, seed2, seed3;
+ prng_rand_128_data_t buf;
+ uint8_t *bytebuf = aligned_malloc(16, SMALLBUFSIZE + 1);
+ ranctx x;
+ prng_t prng;
+ prng_randmemset_flags_t flags;
+
+ if (argc > 1 && strcmp(argv[1], "-bench") == 0)
+ {
+ bench ();
+ return 0;
+ }
+
+ /* basic test */
+ raninit (&x, 0);
+ prng_srand_r (&prng, 0);
+ assert (ranval (&x) == prng_rand_r (&prng));
+
+ /* test for simd code */
+ seed = 0;
+ prng_srand_r (&prng, seed);
+ seed0 = (seed = seed * 1103515245 + 12345);
+ seed1 = (seed = seed * 1103515245 + 12345);
+ seed2 = (seed = seed * 1103515245 + 12345);
+ seed3 = (seed = seed * 1103515245 + 12345);
+ prng_rand_128_r (&prng, &buf);
+
+ raninit (&x, seed0);
+ ref = ranval (&x);
+ assert (ref == buf.w[0]);
+
+ raninit (&x, seed1);
+ ref = ranval (&x);
+ assert (ref == buf.w[1]);
+
+ raninit (&x, seed2);
+ ref = ranval (&x);
+ assert (ref == buf.w[2]);
+
+ raninit (&x, seed3);
+ ref = ranval (&x);
+ assert (ref == buf.w[3]);
+
+ /* test for randmemset */
+ for (flags = 0; flags <= RANDMEMSET_MORE_00_AND_FF; flags++)
+ {
+ prng_srand_r (&prng, 1234);
+ prng_randmemset_r (&prng, bytebuf, 16, flags);
+ prng_randmemset_r (&prng, bytebuf + 16, SMALLBUFSIZE - 17, flags);
+ crc1 = compute_crc32 (0, bytebuf, SMALLBUFSIZE - 1);
+ prng_srand_r (&prng, 1234);
+ prng_randmemset_r (&prng, bytebuf + 1, SMALLBUFSIZE - 1, flags);
+ crc2 = compute_crc32 (0, bytebuf + 1, SMALLBUFSIZE - 1);
+ assert (ref_crc[flags] == crc1);
+ assert (ref_crc[flags] == crc2);
+ }
+
+ free (bytebuf);
+
+ return 0;
+}
diff --git a/pixman/test/region-contains-test.c b/pixman/test/region-contains-test.c
index 9524e2888..096e65179 100644
--- a/pixman/test/region-contains-test.c
+++ b/pixman/test/region-contains-test.c
@@ -9,16 +9,16 @@ make_random_region (pixman_region32_t *region)
pixman_region32_init (region);
- n_boxes = lcg_rand_n (64);
+ n_boxes = prng_rand_n (64);
while (n_boxes--)
{
int32_t x, y;
uint32_t w, h;
- x = (int32_t)lcg_rand_u32() >> 2;
- y = (int32_t)lcg_rand_u32() >> 2;
- w = lcg_rand_u32() >> 2;
- h = lcg_rand_u32() >> 2;
+ x = (int32_t)prng_rand() >> 2;
+ y = (int32_t)prng_rand() >> 2;
+ w = prng_rand() >> 2;
+ h = prng_rand() >> 2;
pixman_region32_union_rect (region, region, x, y, w, h);
}
@@ -37,12 +37,12 @@ random_coord (pixman_region32_t *region, pixman_bool_t x)
int n_boxes;
int begin, end;
- if (lcg_rand_n (14))
+ if (prng_rand_n (14))
{
bb = pixman_region32_rectangles (region, &n_boxes);
if (n_boxes == 0)
goto use_extent;
- b = bb + lcg_rand_n (n_boxes);
+ b = bb + prng_rand_n (n_boxes);
}
else
{
@@ -62,12 +62,12 @@ random_coord (pixman_region32_t *region, pixman_bool_t x)
end = b->y2;
}
- switch (lcg_rand_n (5))
+ switch (prng_rand_n (5))
{
case 0:
- return begin - lcg_rand_u32();
+ return begin - prng_rand();
case 1:
- return end + lcg_rand_u32 ();
+ return end + prng_rand ();
case 2:
return end;
case 3:
@@ -111,14 +111,14 @@ test_region_contains_rectangle (int i, int verbose)
pixman_region32_t region;
uint32_t r, r1, r2, r3, r4, crc32;
- lcg_srand (i);
+ prng_srand (i);
make_random_region (&region);
box.x1 = random_coord (&region, TRUE);
- box.x2 = box.x1 + lcg_rand_u32 ();
+ box.x2 = box.x1 + prng_rand ();
box.y1 = random_coord (&region, FALSE);
- box.y2 = box.y1 + lcg_rand_u32 ();
+ box.y2 = box.y1 + prng_rand ();
if (verbose)
{
@@ -163,7 +163,7 @@ main (int argc, const char *argv[])
{
return fuzzer_test_main ("region_contains",
1000000,
- 0xD2BF8C73,
+ 0x548E0F3F,
test_region_contains_rectangle,
argc, argv);
}
diff --git a/pixman/test/region-test.c b/pixman/test/region-test.c
index 9d5a41eb9..bfc219bc7 100644
--- a/pixman/test/region-test.c
+++ b/pixman/test/region-test.c
@@ -32,6 +32,8 @@ main ()
0xffff
};
+ prng_srand (0);
+
/* This used to go into an infinite loop before pixman-region.c
* was fixed to not use explict "short" variables
*/
@@ -91,10 +93,10 @@ main ()
/* Add some random rectangles */
for (j = 0; j < 64; j++)
pixman_region32_union_rect (&r1, &r1,
- lcg_rand_n (image_size),
- lcg_rand_n (image_size),
- lcg_rand_n (25),
- lcg_rand_n (25));
+ prng_rand_n (image_size),
+ prng_rand_n (image_size),
+ prng_rand_n (25),
+ prng_rand_n (25));
/* Clip to image size */
pixman_region32_init_rect (&r2, 0, 0, image_size, image_size);
diff --git a/pixman/test/rotate-test.c b/pixman/test/rotate-test.c
index a0488ef22..9d2a620cb 100644
--- a/pixman/test/rotate-test.c
+++ b/pixman/test/rotate-test.c
@@ -43,13 +43,13 @@ static const pixman_transform_t transforms[] =
};
#define RANDOM_FORMAT() \
- (formats[lcg_rand_n (ARRAY_LENGTH (formats))])
+ (formats[prng_rand_n (ARRAY_LENGTH (formats))])
#define RANDOM_OP() \
- (ops[lcg_rand_n (ARRAY_LENGTH (ops))])
+ (ops[prng_rand_n (ARRAY_LENGTH (ops))])
#define RANDOM_TRANSFORM() \
- (&(transforms[lcg_rand_n (ARRAY_LENGTH (transforms))]))
+ (&(transforms[prng_rand_n (ARRAY_LENGTH (transforms))]))
static void
on_destroy (pixman_image_t *image, void *data)
@@ -63,10 +63,8 @@ make_image (void)
pixman_format_code_t format = RANDOM_FORMAT();
uint32_t *bytes = malloc (WIDTH * HEIGHT * 4);
pixman_image_t *image;
- int i;
- for (i = 0; i < WIDTH * HEIGHT * 4; ++i)
- ((uint8_t *)bytes)[i] = lcg_rand_n (256);
+ prng_randmemset (bytes, WIDTH * HEIGHT * 4, 0);
image = pixman_image_create_bits (
format, WIDTH, HEIGHT, bytes, WIDTH * 4);
@@ -86,7 +84,7 @@ test_transform (int testnum, int verbose)
pixman_image_t *src, *dest;
uint32_t crc;
- lcg_srand (testnum);
+ prng_srand (testnum);
src = make_image ();
dest = make_image ();
@@ -108,6 +106,6 @@ int
main (int argc, const char *argv[])
{
return fuzzer_test_main ("rotate", 15000,
- 0x5236FD9F,
+ 0xECF5E426,
test_transform, argc, argv);
}
diff --git a/pixman/test/scaling-helpers-test.c b/pixman/test/scaling-helpers-test.c
index 33ec47c85..cd5ace0b2 100644
--- a/pixman/test/scaling-helpers-test.c
+++ b/pixman/test/scaling-helpers-test.c
@@ -52,14 +52,15 @@ int
main (void)
{
int i;
+ prng_srand (0);
for (i = 0; i < 10000; i++)
{
int32_t left_pad1, left_tz1, width1, right_tz1, right_pad1;
int32_t left_pad2, left_tz2, width2, right_tz2, right_pad2;
- pixman_fixed_t vx = lcg_rand_N(10000 << 16) - (3000 << 16);
- int32_t width = lcg_rand_N(10000);
- int32_t source_image_width = lcg_rand_N(10000) + 1;
- pixman_fixed_t unit_x = lcg_rand_N(10 << 16) + 1;
+ pixman_fixed_t vx = prng_rand_n(10000 << 16) - (3000 << 16);
+ int32_t width = prng_rand_n(10000);
+ int32_t source_image_width = prng_rand_n(10000) + 1;
+ pixman_fixed_t unit_x = prng_rand_n(10 << 16) + 1;
width1 = width2 = width;
bilinear_pad_repeat_get_scanline_bounds_ref (source_image_width,
diff --git a/pixman/test/scaling-test.c b/pixman/test/scaling-test.c
index 035410333..64c12dd7c 100644
--- a/pixman/test/scaling-test.c
+++ b/pixman/test/scaling-test.c
@@ -26,7 +26,7 @@ get_format (int bpp)
{
if (bpp == 4)
{
- switch (lcg_rand_n (4))
+ switch (prng_rand_n (4))
{
default:
case 0:
@@ -80,11 +80,11 @@ test_composite (int testnum,
uint32_t crc32;
FLOAT_REGS_CORRUPTION_DETECTOR_START ();
- lcg_srand (testnum);
+ prng_srand (testnum);
- src_bpp = (lcg_rand_n (2) == 0) ? 2 : 4;
- dst_bpp = (lcg_rand_n (2) == 0) ? 2 : 4;
- switch (lcg_rand_n (3))
+ src_bpp = (prng_rand_n (2) == 0) ? 2 : 4;
+ dst_bpp = (prng_rand_n (2) == 0) ? 2 : 4;
+ switch (prng_rand_n (3))
{
case 0:
op = PIXMAN_OP_SRC;
@@ -97,24 +97,24 @@ test_composite (int testnum,
break;
}
- src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1;
- src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1;
+ src_width = prng_rand_n (MAX_SRC_WIDTH) + 1;
+ src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1;
- if (lcg_rand_n (2))
+ if (prng_rand_n (2))
{
- mask_width = lcg_rand_n (MAX_SRC_WIDTH) + 1;
- mask_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1;
+ mask_width = prng_rand_n (MAX_SRC_WIDTH) + 1;
+ mask_height = prng_rand_n (MAX_SRC_HEIGHT) + 1;
}
else
{
mask_width = mask_height = 1;
}
- dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1;
- dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1;
- src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp;
- mask_stride = mask_width * mask_bpp + lcg_rand_n (MAX_STRIDE) * mask_bpp;
- dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp;
+ dst_width = prng_rand_n (MAX_DST_WIDTH) + 1;
+ dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1;
+ src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp;
+ mask_stride = mask_width * mask_bpp + prng_rand_n (MAX_STRIDE) * mask_bpp;
+ dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp;
if (src_stride & 3)
src_stride += 2;
@@ -127,27 +127,22 @@ test_composite (int testnum,
if (dst_stride & 3)
dst_stride += 2;
- src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2);
- src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2);
- mask_x = -(mask_width / 4) + lcg_rand_n (mask_width * 3 / 2);
- mask_y = -(mask_height / 4) + lcg_rand_n (mask_height * 3 / 2);
- dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2);
- dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2);
- w = lcg_rand_n (dst_width * 3 / 2 - dst_x);
- h = lcg_rand_n (dst_height * 3 / 2 - dst_y);
+ src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2);
+ src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2);
+ mask_x = -(mask_width / 4) + prng_rand_n (mask_width * 3 / 2);
+ mask_y = -(mask_height / 4) + prng_rand_n (mask_height * 3 / 2);
+ dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2);
+ dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2);
+ w = prng_rand_n (dst_width * 3 / 2 - dst_x);
+ h = prng_rand_n (dst_height * 3 / 2 - dst_y);
srcbuf = (uint32_t *)malloc (src_stride * src_height);
maskbuf = (uint32_t *)malloc (mask_stride * mask_height);
dstbuf = (uint32_t *)malloc (dst_stride * dst_height);
- for (i = 0; i < src_stride * src_height; i++)
- *((uint8_t *)srcbuf + i) = lcg_rand_n (256);
-
- for (i = 0; i < mask_stride * mask_height; i++)
- *((uint8_t *)maskbuf + i) = lcg_rand_n (256);
-
- for (i = 0; i < dst_stride * dst_height; i++)
- *((uint8_t *)dstbuf + i) = lcg_rand_n (256);
+ prng_randmemset (srcbuf, src_stride * src_height, 0);
+ prng_randmemset (maskbuf, mask_stride * mask_height, 0);
+ prng_randmemset (dstbuf, dst_stride * dst_height, 0);
src_fmt = get_format (src_bpp);
dst_fmt = get_format (dst_bpp);
@@ -164,29 +159,29 @@ test_composite (int testnum,
image_endian_swap (src_img);
image_endian_swap (dst_img);
- if (lcg_rand_n (4) > 0)
+ if (prng_rand_n (4) > 0)
{
- scale_x = -32768 * 3 + lcg_rand_N (65536 * 5);
- scale_y = -32768 * 3 + lcg_rand_N (65536 * 5);
- translate_x = lcg_rand_N (65536);
- translate_y = lcg_rand_N (65536);
+ scale_x = -32768 * 3 + prng_rand_n (65536 * 5);
+ scale_y = -32768 * 3 + prng_rand_n (65536 * 5);
+ translate_x = prng_rand_n (65536);
+ translate_y = prng_rand_n (65536);
pixman_transform_init_scale (&transform, scale_x, scale_y);
pixman_transform_translate (&transform, NULL, translate_x, translate_y);
pixman_image_set_transform (src_img, &transform);
}
- if (lcg_rand_n (2) > 0)
+ if (prng_rand_n (2) > 0)
{
- mask_scale_x = -32768 * 3 + lcg_rand_N (65536 * 5);
- mask_scale_y = -32768 * 3 + lcg_rand_N (65536 * 5);
- mask_translate_x = lcg_rand_N (65536);
- mask_translate_y = lcg_rand_N (65536);
+ mask_scale_x = -32768 * 3 + prng_rand_n (65536 * 5);
+ mask_scale_y = -32768 * 3 + prng_rand_n (65536 * 5);
+ mask_translate_x = prng_rand_n (65536);
+ mask_translate_y = prng_rand_n (65536);
pixman_transform_init_scale (&transform, mask_scale_x, mask_scale_y);
pixman_transform_translate (&transform, NULL, mask_translate_x, mask_translate_y);
pixman_image_set_transform (mask_img, &transform);
}
- switch (lcg_rand_n (4))
+ switch (prng_rand_n (4))
{
case 0:
mask_repeat = PIXMAN_REPEAT_NONE;
@@ -209,7 +204,7 @@ test_composite (int testnum,
}
pixman_image_set_repeat (mask_img, mask_repeat);
- switch (lcg_rand_n (4))
+ switch (prng_rand_n (4))
{
case 0:
repeat = PIXMAN_REPEAT_NONE;
@@ -232,12 +227,12 @@ test_composite (int testnum,
}
pixman_image_set_repeat (src_img, repeat);
- if (lcg_rand_n (2))
+ if (prng_rand_n (2))
pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0);
else
pixman_image_set_filter (src_img, PIXMAN_FILTER_BILINEAR, NULL, 0);
- if (lcg_rand_n (2))
+ if (prng_rand_n (2))
pixman_image_set_filter (mask_img, PIXMAN_FILTER_NEAREST, NULL, 0);
else
pixman_image_set_filter (mask_img, PIXMAN_FILTER_BILINEAR, NULL, 0);
@@ -256,19 +251,19 @@ test_composite (int testnum,
printf ("w=%d, h=%d\n", w, h);
}
- if (lcg_rand_n (8) == 0)
+ if (prng_rand_n (8) == 0)
{
pixman_box16_t clip_boxes[2];
- int n = lcg_rand_n (2) + 1;
+ int n = prng_rand_n (2) + 1;
for (i = 0; i < n; i++)
{
- clip_boxes[i].x1 = lcg_rand_n (src_width);
- clip_boxes[i].y1 = lcg_rand_n (src_height);
+ clip_boxes[i].x1 = prng_rand_n (src_width);
+ clip_boxes[i].y1 = prng_rand_n (src_height);
clip_boxes[i].x2 =
- clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1);
+ clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1);
clip_boxes[i].y2 =
- clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1);
+ clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1);
if (verbose)
{
@@ -284,19 +279,19 @@ test_composite (int testnum,
pixman_region_fini (&clip);
}
- if (lcg_rand_n (8) == 0)
+ if (prng_rand_n (8) == 0)
{
pixman_box16_t clip_boxes[2];
- int n = lcg_rand_n (2) + 1;
+ int n = prng_rand_n (2) + 1;
for (i = 0; i < n; i++)
{
- clip_boxes[i].x1 = lcg_rand_n (mask_width);
- clip_boxes[i].y1 = lcg_rand_n (mask_height);
+ clip_boxes[i].x1 = prng_rand_n (mask_width);
+ clip_boxes[i].y1 = prng_rand_n (mask_height);
clip_boxes[i].x2 =
- clip_boxes[i].x1 + lcg_rand_n (mask_width - clip_boxes[i].x1);
+ clip_boxes[i].x1 + prng_rand_n (mask_width - clip_boxes[i].x1);
clip_boxes[i].y2 =
- clip_boxes[i].y1 + lcg_rand_n (mask_height - clip_boxes[i].y1);
+ clip_boxes[i].y1 + prng_rand_n (mask_height - clip_boxes[i].y1);
if (verbose)
{
@@ -312,18 +307,18 @@ test_composite (int testnum,
pixman_region_fini (&clip);
}
- if (lcg_rand_n (8) == 0)
+ if (prng_rand_n (8) == 0)
{
pixman_box16_t clip_boxes[2];
- int n = lcg_rand_n (2) + 1;
+ int n = prng_rand_n (2) + 1;
for (i = 0; i < n; i++)
{
- clip_boxes[i].x1 = lcg_rand_n (dst_width);
- clip_boxes[i].y1 = lcg_rand_n (dst_height);
+ clip_boxes[i].x1 = prng_rand_n (dst_width);
+ clip_boxes[i].y1 = prng_rand_n (dst_height);
clip_boxes[i].x2 =
- clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1);
+ clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1);
clip_boxes[i].y2 =
- clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1);
+ clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1);
if (verbose)
{
@@ -337,7 +332,7 @@ test_composite (int testnum,
pixman_region_fini (&clip);
}
- if (lcg_rand_n (2) == 0)
+ if (prng_rand_n (2) == 0)
pixman_image_composite (op, src_img, NULL, dst_img,
src_x, src_y, 0, 0, dst_x, dst_y, w, h);
else
@@ -380,11 +375,11 @@ test_composite (int testnum,
}
#if BILINEAR_INTERPOLATION_BITS == 8
-#define CHECKSUM 0x107B67ED
+#define CHECKSUM 0x9096E6B6
#elif BILINEAR_INTERPOLATION_BITS == 7
-#define CHECKSUM 0x30EC0CF0
+#define CHECKSUM 0xCE8EC6BA
#elif BILINEAR_INTERPOLATION_BITS == 4
-#define CHECKSUM 0x87B496BC
+#define CHECKSUM 0xAB1D39BE
#else
#define CHECKSUM 0x00000000
#endif
diff --git a/pixman/test/stress-test.c b/pixman/test/stress-test.c
index 059250dd4..ee55c21ea 100644
--- a/pixman/test/stress-test.c
+++ b/pixman/test/stress-test.c
@@ -74,7 +74,7 @@ static pixman_filter_t filters[] =
static int
get_size (void)
{
- switch (lcg_rand_n (28))
+ switch (prng_rand_n (28))
{
case 0:
return 1;
@@ -84,10 +84,10 @@ get_size (void)
default:
case 2:
- return lcg_rand_n (100);
+ return prng_rand_n (100);
case 4:
- return lcg_rand_n (2000) + 1000;
+ return prng_rand_n (2000) + 1000;
case 5:
return 65535;
@@ -96,7 +96,7 @@ get_size (void)
return 65536;
case 7:
- return lcg_rand_N (64000) + 63000;
+ return prng_rand_n (64000) + 63000;
}
}
@@ -164,7 +164,7 @@ real_writer (void *src, uint32_t value, int size)
static uint32_t
fake_reader (const void *src, int size)
{
- uint32_t r = lcg_rand_u32 ();
+ uint32_t r = prng_rand ();
assert (size == 1 || size == 2 || size == 4);
@@ -182,16 +182,16 @@ log_rand (void)
{
uint32_t mask;
- mask = (1 << lcg_rand_n (10)) - 1;
+ mask = (1 << prng_rand_n (10)) - 1;
- return (lcg_rand_u32 () & mask) - (mask >> 1);
+ return (prng_rand () & mask) - (mask >> 1);
}
static int32_t
rand_x (pixman_image_t *image)
{
if (image->type == BITS)
- return lcg_rand_n (image->bits.width);
+ return prng_rand_n (image->bits.width);
else
return log_rand ();
}
@@ -200,7 +200,7 @@ static int32_t
rand_y (pixman_image_t *image)
{
if (image->type == BITS)
- return lcg_rand_n (image->bits.height);
+ return prng_rand_n (image->bits.height);
else
return log_rand ();
}
@@ -220,7 +220,7 @@ create_random_bits_image (void)
int n_coefficients = 0;
/* format */
- format = image_formats[lcg_rand_n (ARRAY_LENGTH (image_formats))];
+ format = image_formats[prng_rand_n (ARRAY_LENGTH (image_formats))];
indexed = NULL;
if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
@@ -246,7 +246,7 @@ create_random_bits_image (void)
while ((uint64_t)width * height > 200000)
{
- if (lcg_rand_n(2) == 0)
+ if (prng_rand_n(2) == 0)
height = 200000 / width;
else
width = 200000 / height;
@@ -258,11 +258,11 @@ create_random_bits_image (void)
width = 1;
/* bits */
- switch (lcg_rand_n (7))
+ switch (prng_rand_n (7))
{
default:
case 0:
- stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+ stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17);
stride = (stride + 3) & (~3);
bits = (uint32_t *)make_random_bytes (height * stride);
break;
@@ -273,7 +273,7 @@ create_random_bits_image (void)
break;
case 2: /* Zero-filled */
- stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+ stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17);
stride = (stride + 3) & (~3);
bits = fence_malloc (height * stride);
if (!bits)
@@ -282,7 +282,7 @@ create_random_bits_image (void)
break;
case 3: /* Filled with 0xFF */
- stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+ stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17);
stride = (stride + 3) & (~3);
bits = fence_malloc (height * stride);
if (!bits)
@@ -298,7 +298,7 @@ create_random_bits_image (void)
break;
case 5: /* bits is a real pointer, has read/write functions */
- stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+ stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17);
stride = (stride + 3) & (~3);
bits = fence_malloc (height * stride);
if (!bits)
@@ -309,7 +309,7 @@ create_random_bits_image (void)
break;
case 6: /* bits is a real pointer, stride is negative */
- stride = (width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17));
+ stride = (width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17));
stride = (stride + 3) & (~3);
bits = (uint32_t *)make_random_bytes (height * stride);
if (!bits)
@@ -320,11 +320,11 @@ create_random_bits_image (void)
}
/* Filter */
- filter = filters[lcg_rand_n (ARRAY_LENGTH (filters))];
+ filter = filters[prng_rand_n (ARRAY_LENGTH (filters))];
if (filter == PIXMAN_FILTER_CONVOLUTION)
{
- int width = lcg_rand_n (3);
- int height = lcg_rand_n (4);
+ int width = prng_rand_n (3);
+ int height = prng_rand_n (4);
n_coefficients = width * height + 2;
coefficients = malloc (n_coefficients * sizeof (pixman_fixed_t));
@@ -334,7 +334,7 @@ create_random_bits_image (void)
int i;
for (i = 0; i < width * height; ++i)
- coefficients[i + 2] = lcg_rand_u32();
+ coefficients[i + 2] = prng_rand();
coefficients[0] = width << 16;
coefficients[1] = height << 16;
@@ -380,11 +380,11 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
/* Set properties that are generic to all images */
/* Repeat */
- repeat = repeats[lcg_rand_n (ARRAY_LENGTH (repeats))];
+ repeat = repeats[prng_rand_n (ARRAY_LENGTH (repeats))];
pixman_image_set_repeat (image, repeat);
/* Alpha map */
- if (allow_alpha_map && lcg_rand_n (4) == 0)
+ if (allow_alpha_map && prng_rand_n (4) == 0)
{
pixman_image_t *alpha_map;
int16_t x, y;
@@ -405,17 +405,17 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
}
/* Component alpha */
- pixman_image_set_component_alpha (image, lcg_rand_n (3) == 0);
+ pixman_image_set_component_alpha (image, prng_rand_n (3) == 0);
/* Clip region */
- if (lcg_rand_n (8) < 2)
+ if (prng_rand_n (8) < 2)
{
pixman_region32_t region;
int i, n_rects;
pixman_region32_init (&region);
- switch (lcg_rand_n (12))
+ switch (prng_rand_n (12))
{
case 0:
n_rects = 0;
@@ -434,7 +434,7 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
break;
default:
- n_rects = lcg_rand_n (100);
+ n_rects = prng_rand_n (100);
break;
}
@@ -452,7 +452,7 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
&region, &region, x, y, width, height);
}
- if (image->type == BITS && lcg_rand_n (8) != 0)
+ if (image->type == BITS && prng_rand_n (8) != 0)
{
uint32_t width, height;
int x, y;
@@ -463,10 +463,10 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
*/
for (i = 0; i < 5; ++i)
{
- x = lcg_rand_n (2 * image->bits.width) - image->bits.width;
- y = lcg_rand_n (2 * image->bits.height) - image->bits.height;
- width = lcg_rand_n (image->bits.width) - x + 10;
- height = lcg_rand_n (image->bits.height) - y + 10;
+ x = prng_rand_n (2 * image->bits.width) - image->bits.width;
+ y = prng_rand_n (2 * image->bits.height) - image->bits.height;
+ width = prng_rand_n (image->bits.width) - x + 10;
+ height = prng_rand_n (image->bits.height) - y + 10;
if (width + x < x)
width = INT32_MAX - x;
@@ -484,13 +484,13 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
}
/* Whether source clipping is enabled */
- pixman_image_set_source_clipping (image, !!lcg_rand_n (2));
+ pixman_image_set_source_clipping (image, !!prng_rand_n (2));
/* Client clip */
- pixman_image_set_has_client_clip (image, !!lcg_rand_n (2));
+ pixman_image_set_has_client_clip (image, !!prng_rand_n (2));
/* Transform */
- if (lcg_rand_n (5) < 2)
+ if (prng_rand_n (5) < 2)
{
pixman_transform_t xform;
int i, j, k;
@@ -504,39 +504,39 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
for (k = 0; k < 3; ++k)
{
- switch (lcg_rand_n (4))
+ switch (prng_rand_n (4))
{
case 0:
/* rotation */
- c = lcg_rand_N (2 * 65536) - 65536;
- s = lcg_rand_N (2 * 65536) - 65536;
+ c = prng_rand_n (2 * 65536) - 65536;
+ s = prng_rand_n (2 * 65536) - 65536;
pixman_transform_rotate (&xform, NULL, c, s);
break;
case 1:
/* translation */
- tx = lcg_rand_u32();
- ty = lcg_rand_u32();
+ tx = prng_rand();
+ ty = prng_rand();
pixman_transform_translate (&xform, NULL, tx, ty);
break;
case 2:
/* scale */
- sx = lcg_rand_u32();
- sy = lcg_rand_u32();
+ sx = prng_rand();
+ sy = prng_rand();
pixman_transform_scale (&xform, NULL, sx, sy);
break;
case 3:
- if (lcg_rand_n (16) == 0)
+ if (prng_rand_n (16) == 0)
{
/* random */
for (i = 0; i < 3; ++i)
for (j = 0; j < 3; ++j)
- xform.matrix[i][j] = lcg_rand_u32();
+ xform.matrix[i][j] = prng_rand();
break;
}
- else if (lcg_rand_n (16) == 0)
+ else if (prng_rand_n (16) == 0)
{
/* zero */
memset (&xform, 0, sizeof xform);
@@ -554,10 +554,10 @@ random_color (void)
{
pixman_color_t color =
{
- lcg_rand() & 0xffff,
- lcg_rand() & 0xffff,
- lcg_rand() & 0xffff,
- lcg_rand() & 0xffff,
+ prng_rand() & 0xffff,
+ prng_rand() & 0xffff,
+ prng_rand() & 0xffff,
+ prng_rand() & 0xffff,
};
return color;
@@ -581,7 +581,7 @@ create_random_stops (int *n_stops)
int i;
pixman_gradient_stop_t *stops;
- *n_stops = lcg_rand_n (50) + 1;
+ *n_stops = prng_rand_n (50) + 1;
step = pixman_fixed_1 / *n_stops;
@@ -646,8 +646,8 @@ create_random_radial_image (void)
inner_c = create_random_point();
outer_c = create_random_point();
- inner_r = lcg_rand();
- outer_r = lcg_rand();
+ inner_r = prng_rand();
+ outer_r = prng_rand();
stops = create_random_stops (&n_stops);
@@ -672,7 +672,7 @@ create_random_conical_image (void)
pixman_image_t *result;
c = create_random_point();
- angle = lcg_rand();
+ angle = prng_rand();
stops = create_random_stops (&n_stops);
@@ -691,7 +691,7 @@ create_random_image (void)
{
pixman_image_t *result;
- switch (lcg_rand_n (5))
+ switch (prng_rand_n (5))
{
default:
case 0:
@@ -793,7 +793,7 @@ run_test (uint32_t seed, pixman_bool_t verbose, uint32_t mod)
printf ("Seed 0x%08x\n", seed);
}
- lcg_srand (seed);
+ prng_srand (seed);
source = create_random_image ();
mask = create_random_image ();
@@ -803,7 +803,7 @@ run_test (uint32_t seed, pixman_bool_t verbose, uint32_t mod)
{
set_general_properties (dest, TRUE);
- op = op_list [lcg_rand_n (ARRAY_LENGTH (op_list))];
+ op = op_list [prng_rand_n (ARRAY_LENGTH (op_list))];
pixman_image_composite32 (op,
source, mask, dest,
diff --git a/pixman/test/utils-prng.c b/pixman/test/utils-prng.c
new file mode 100644
index 000000000..7c2dd6a9a
--- /dev/null
+++ b/pixman/test/utils-prng.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright © 2012 Siarhei Siamashka <siarhei.siamashka@gmail.com>
+ *
+ * Based on the public domain implementation of small noncryptographic PRNG
+ * authored by Bob Jenkins: http://burtleburtle.net/bob/rand/smallprng.html
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "utils.h"
+#include "utils-prng.h"
+
+void smallprng_srand_r (smallprng_t *x, uint32_t seed)
+{
+ uint32_t i;
+ x->a = 0xf1ea5eed, x->b = x->c = x->d = seed;
+ for (i = 0; i < 20; ++i)
+ smallprng_rand_r (x);
+}
+
+/*
+ * Set a 32-bit seed for PRNG
+ *
+ * LCG is used here for generating independent seeds for different
+ * smallprng instances (in the case if smallprng is also used for
+ * generating these seeds, "Big Crush" test from TestU01 detects
+ * some problems in the glued 'prng_rand_128_r' output data).
+ * Actually we might be even better using some cryptographic
+ * hash for this purpose, but LCG seems to be also enough for
+ * passing "Big Crush".
+ */
+void prng_srand_r (prng_t *x, uint32_t seed)
+{
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+ int i;
+ prng_rand_128_data_t dummy;
+ smallprng_srand_r (&x->p0, seed);
+ x->a[0] = x->a[1] = x->a[2] = x->a[3] = 0xf1ea5eed;
+ x->b[0] = x->c[0] = x->d[0] = (seed = seed * 1103515245 + 12345);
+ x->b[1] = x->c[1] = x->d[1] = (seed = seed * 1103515245 + 12345);
+ x->b[2] = x->c[2] = x->d[2] = (seed = seed * 1103515245 + 12345);
+ x->b[3] = x->c[3] = x->d[3] = (seed = seed * 1103515245 + 12345);
+ for (i = 0; i < 20; ++i)
+ prng_rand_128_r (x, &dummy);
+#else
+ smallprng_srand_r (&x->p0, seed);
+ smallprng_srand_r (&x->p1, (seed = seed * 1103515245 + 12345));
+ smallprng_srand_r (&x->p2, (seed = seed * 1103515245 + 12345));
+ smallprng_srand_r (&x->p3, (seed = seed * 1103515245 + 12345));
+ smallprng_srand_r (&x->p4, (seed = seed * 1103515245 + 12345));
+#endif
+}
+
+static force_inline void
+store_rand_128_data (void *addr, prng_rand_128_data_t *d, int aligned)
+{
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+ if (aligned)
+ {
+ *(uint8x16 *)addr = d->vb;
+ return;
+ }
+#endif
+ /* we could try something better for unaligned writes (packed attribute),
+ * but GCC is not very reliable: http://gcc.gnu.org/PR55454 */
+ memcpy (addr, d, 16);
+}
+
+/*
+ * Helper function and the actual code for "prng_randmemset_r" function
+ */
+static force_inline void
+randmemset_internal (prng_t *prng,
+ uint8_t *buf,
+ size_t size,
+ prng_randmemset_flags_t flags,
+ int aligned)
+{
+ prng_t local_prng = *prng;
+ prng_rand_128_data_t randdata;
+
+ while (size >= 16)
+ {
+ prng_rand_128_data_t t;
+ if (flags == 0)
+ {
+ prng_rand_128_r (&local_prng, &randdata);
+ }
+ else
+ {
+ prng_rand_128_r (&local_prng, &t);
+ prng_rand_128_r (&local_prng, &randdata);
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+ if (flags & RANDMEMSET_MORE_FF)
+ {
+ const uint8x16 const_C0 =
+ {
+ 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
+ };
+ randdata.vb |= (t.vb >= const_C0);
+ }
+ if (flags & RANDMEMSET_MORE_00)
+ {
+ const uint8x16 const_40 =
+ {
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
+ };
+ randdata.vb &= (t.vb >= const_40);
+ }
+#else
+ #define PROCESS_ONE_LANE(i) \
+ if (flags & RANDMEMSET_MORE_FF) \
+ { \
+ uint32_t mask_ff = (t.w[i] & (t.w[i] << 1)) & 0x80808080; \
+ mask_ff |= mask_ff >> 1; \
+ mask_ff |= mask_ff >> 2; \
+ mask_ff |= mask_ff >> 4; \
+ randdata.w[i] |= mask_ff; \
+ } \
+ if (flags & RANDMEMSET_MORE_00) \
+ { \
+ uint32_t mask_00 = (t.w[i] | (t.w[i] << 1)) & 0x80808080; \
+ mask_00 |= mask_00 >> 1; \
+ mask_00 |= mask_00 >> 2; \
+ mask_00 |= mask_00 >> 4; \
+ randdata.w[i] &= mask_00; \
+ }
+
+ PROCESS_ONE_LANE (0)
+ PROCESS_ONE_LANE (1)
+ PROCESS_ONE_LANE (2)
+ PROCESS_ONE_LANE (3)
+#endif
+ }
+ if (is_little_endian ())
+ {
+ store_rand_128_data (buf, &randdata, aligned);
+ buf += 16;
+ }
+ else
+ {
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+ const uint8x16 bswap_shufflemask =
+ {
+ 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
+ };
+ randdata.vb = __builtin_shuffle (randdata.vb, bswap_shufflemask);
+ store_rand_128_data (buf, &randdata, aligned);
+ buf += 16;
+#else
+ uint8_t t1, t2, t3, t4;
+ #define STORE_ONE_LANE(i) \
+ t1 = randdata.b[i * 4 + 3]; \
+ t2 = randdata.b[i * 4 + 2]; \
+ t3 = randdata.b[i * 4 + 1]; \
+ t4 = randdata.b[i * 4 + 0]; \
+ *buf++ = t1; \
+ *buf++ = t2; \
+ *buf++ = t3; \
+ *buf++ = t4;
+
+ STORE_ONE_LANE (0)
+ STORE_ONE_LANE (1)
+ STORE_ONE_LANE (2)
+ STORE_ONE_LANE (3)
+#endif
+ }
+ size -= 16;
+ }
+ while (size > 0)
+ {
+ uint8_t randbyte = prng_rand_r (&local_prng) & 0xFF;
+ if (flags != 0)
+ {
+ uint8_t t = prng_rand_r (&local_prng) & 0xFF;
+ if ((flags & RANDMEMSET_MORE_FF) && (t >= 0xC0))
+ randbyte = 0xFF;
+ if ((flags & RANDMEMSET_MORE_00) && (t < 0x40))
+ randbyte = 0x00;
+ }
+ *buf++ = randbyte;
+ size--;
+ }
+ *prng = local_prng;
+}
+
+/*
+ * Fill memory buffer with random data. Flags argument may be used
+ * to tweak some statistics properties:
+ * RANDMEMSET_MORE_00 - set ~25% of bytes to 0x00
+ * RANDMEMSET_MORE_FF - set ~25% of bytes to 0xFF
+ */
+void prng_randmemset_r (prng_t *prng,
+ void *voidbuf,
+ size_t size,
+ prng_randmemset_flags_t flags)
+{
+ uint8_t *buf = (uint8_t *)voidbuf;
+ if ((uintptr_t)buf & 15)
+ {
+ /* unaligned buffer */
+ if (flags == 0)
+ randmemset_internal (prng, buf, size, 0, 0);
+ else if (flags == RANDMEMSET_MORE_00_AND_FF)
+ randmemset_internal (prng, buf, size, RANDMEMSET_MORE_00_AND_FF, 0);
+ else
+ randmemset_internal (prng, buf, size, flags, 0);
+ }
+ else
+ {
+ /* aligned buffer */
+ if (flags == 0)
+ randmemset_internal (prng, buf, size, 0, 1);
+ else if (flags == RANDMEMSET_MORE_00_AND_FF)
+ randmemset_internal (prng, buf, size, RANDMEMSET_MORE_00_AND_FF, 1);
+ else
+ randmemset_internal (prng, buf, size, flags, 1);
+ }
+}
diff --git a/pixman/test/utils-prng.h b/pixman/test/utils-prng.h
new file mode 100644
index 000000000..285107f08
--- /dev/null
+++ b/pixman/test/utils-prng.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright © 2012 Siarhei Siamashka <siarhei.siamashka@gmail.com>
+ *
+ * Based on the public domain implementation of small noncryptographic PRNG
+ * authored by Bob Jenkins: http://burtleburtle.net/bob/rand/smallprng.html
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __UTILS_PRNG_H__
+#define __UTILS_PRNG_H__
+
+/*
+ * This file provides a fast SIMD-optimized noncryptographic PRNG (pseudorandom
+ * number generator), with the output good enough to pass "Big Crush" tests
+ * from TestU01 (http://en.wikipedia.org/wiki/TestU01).
+ *
+ * SIMD code uses http://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
+ * which is a GCC specific extension. There is also a slower alternative
+ * code path, which should work with any C compiler.
+ *
+ * The "prng_t" structure keeps the internal state of the random number
+ * generator. It is possible to have multiple instances of the random number
+ * generator active at the same time, in this case each of them needs to have
+ * its own "prng_t". All the functions take a pointer to "prng_t"
+ * as the first argument.
+ *
+ * Functions:
+ *
+ * ----------------------------------------------------------------------------
+ * void prng_srand_r (prng_t *prng, uint32_t seed);
+ *
+ * Initialize the pseudorandom number generator. The sequence of preudorandom
+ * numbers is deterministic and only depends on "seed". Any two generators
+ * initialized with the same seed will produce exactly the same sequence.
+ *
+ * ----------------------------------------------------------------------------
+ * uint32_t prng_rand_r (prng_t *prng);
+ *
+ * Generate a single uniformly distributed 32-bit pseudorandom value.
+ *
+ * ----------------------------------------------------------------------------
+ * void prng_randmemset_r (prng_t *prng,
+ * void *buffer,
+ * size_t size,
+ * prng_randmemset_flags_t flags);
+ *
+ * Fills the memory buffer "buffer" with "size" bytes of pseudorandom data.
+ * The "flags" argument may be used to tweak some statistics properties:
+ * RANDMEMSET_MORE_00 - set ~25% of bytes to 0x00
+ * RANDMEMSET_MORE_FF - set ~25% of bytes to 0xFF
+ * The flags can be combined. This allows a bit better simulation of typical
+ * pixel data, which normally contains a lot of fully transparent or fully
+ * opaque pixels.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "pixman-private.h"
+
+/*****************************************************************************/
+
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
+#define GCC_VECTOR_EXTENSIONS_SUPPORTED
+typedef uint32_t uint32x4 __attribute__ ((vector_size(16)));
+typedef uint8_t uint8x16 __attribute__ ((vector_size(16)));
+#endif
+
+typedef struct
+{
+ uint32_t a, b, c, d;
+} smallprng_t;
+
+typedef struct
+{
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+ uint32x4 a, b, c, d;
+#else
+ smallprng_t p1, p2, p3, p4;
+#endif
+ smallprng_t p0;
+} prng_t;
+
+typedef union
+{
+ uint8_t b[16];
+ uint32_t w[4];
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+ uint8x16 vb;
+ uint32x4 vw;
+#endif
+} prng_rand_128_data_t;
+
+/*****************************************************************************/
+
+static force_inline uint32_t
+smallprng_rand_r (smallprng_t *x)
+{
+ uint32_t e = x->a - ((x->b << 27) + (x->b >> (32 - 27)));
+ x->a = x->b ^ ((x->c << 17) ^ (x->c >> (32 - 17)));
+ x->b = x->c + x->d;
+ x->c = x->d + e;
+ x->d = e + x->a;
+ return x->d;
+}
+
+/* Generate 4 bytes (32-bits) of random data */
+static force_inline uint32_t
+prng_rand_r (prng_t *x)
+{
+ return smallprng_rand_r (&x->p0);
+}
+
+/* Generate 16 bytes (128-bits) of random data */
+static force_inline void
+prng_rand_128_r (prng_t *x, prng_rand_128_data_t *data)
+{
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+ uint32x4 e = x->a - ((x->b << 27) + (x->b >> (32 - 27)));
+ x->a = x->b ^ ((x->c << 17) ^ (x->c >> (32 - 17)));
+ x->b = x->c + x->d;
+ x->c = x->d + e;
+ x->d = e + x->a;
+ data->vw = x->d;
+#else
+ data->w[0] = smallprng_rand_r (&x->p1);
+ data->w[1] = smallprng_rand_r (&x->p2);
+ data->w[2] = smallprng_rand_r (&x->p3);
+ data->w[3] = smallprng_rand_r (&x->p4);
+#endif
+}
+
+typedef enum
+{
+ RANDMEMSET_MORE_00 = 1, /* ~25% chance for 0x00 bytes */
+ RANDMEMSET_MORE_FF = 2, /* ~25% chance for 0xFF bytes */
+ RANDMEMSET_MORE_00_AND_FF = (RANDMEMSET_MORE_00 | RANDMEMSET_MORE_FF)
+} prng_randmemset_flags_t;
+
+/* Set the 32-bit seed for PRNG */
+void prng_srand_r (prng_t *prng, uint32_t seed);
+
+/* Fill memory buffer with random data */
+void prng_randmemset_r (prng_t *prng,
+ void *buffer,
+ size_t size,
+ prng_randmemset_flags_t flags);
+
+#endif
diff --git a/pixman/test/utils.c b/pixman/test/utils.c
index c887a6db9..66c8dcb89 100644
--- a/pixman/test/utils.c
+++ b/pixman/test/utils.c
@@ -27,10 +27,11 @@
#include <png.h>
#endif
-/* Random number seed
+/* Random number generator state
*/
-uint32_t lcg_seed;
+prng_t prng_state_data;
+prng_t *prng_state;
/*----------------------------------------------------------------------------*\
* CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
@@ -237,14 +238,6 @@ compute_crc32_for_image (uint32_t crc32,
return crc32;
}
-pixman_bool_t
-is_little_endian (void)
-{
- volatile uint16_t endian_check_var = 0x1234;
-
- return (*(volatile uint8_t *)&endian_check_var == 0x34);
-}
-
/* perform endian conversion of pixel data
*/
void
@@ -431,13 +424,11 @@ uint8_t *
make_random_bytes (int n_bytes)
{
uint8_t *bytes = fence_malloc (n_bytes);
- int i;
if (!bytes)
return NULL;
- for (i = 0; i < n_bytes; ++i)
- bytes[i] = lcg_rand () & 0xff;
+ prng_randmemset (bytes, n_bytes, 0);
return bytes;
}
@@ -689,9 +680,9 @@ get_random_seed (void)
{
union { double d; uint32_t u32; } t;
t.d = gettime();
- lcg_srand (t.u32);
+ prng_srand (t.u32);
- return lcg_rand_u32 ();
+ return prng_rand ();
}
#ifdef HAVE_SIGACTION
@@ -785,7 +776,7 @@ initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
uint32_t mask = (1 << depth) - 1;
for (i = 0; i < 32768; ++i)
- palette->ent[i] = lcg_rand() & mask;
+ palette->ent[i] = prng_rand() & mask;
memset (palette->rgba, 0, sizeof (palette->rgba));
@@ -805,7 +796,7 @@ initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
{
uint32_t old_idx;
- rgba24 = lcg_rand();
+ rgba24 = prng_rand();
i15 = CONVERT_15 (rgba24, is_rgb);
old_idx = palette->ent[i15];
diff --git a/pixman/test/utils.h b/pixman/test/utils.h
index f7ea34c5f..78cf0d16d 100644
--- a/pixman/test/utils.h
+++ b/pixman/test/utils.h
@@ -4,6 +4,7 @@
#include <assert.h>
#include "pixman-private.h" /* For 'inline' definition */
+#include "utils-prng.h"
#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
@@ -11,49 +12,44 @@
* taken from POSIX.1-2001 example
*/
-extern uint32_t lcg_seed;
+extern prng_t prng_state_data;
+extern prng_t *prng_state;
#ifdef USE_OPENMP
-#pragma omp threadprivate(lcg_seed)
+#pragma omp threadprivate(prng_state_data)
+#pragma omp threadprivate(prng_state)
#endif
static inline uint32_t
-lcg_rand (void)
+prng_rand (void)
{
- lcg_seed = lcg_seed * 1103515245 + 12345;
- return ((uint32_t)(lcg_seed / 65536) % 32768);
+ return prng_rand_r (prng_state);
}
static inline void
-lcg_srand (uint32_t seed)
+prng_srand (uint32_t seed)
{
- lcg_seed = seed;
+ if (!prng_state)
+ {
+ /* Without setting a seed, PRNG does not work properly (is just
+ * returning zeros). So we only initialize the pointer here to
+ * make sure that 'prng_srand' is always called before any
+ * other 'prng_*' function. The wrongdoers violating this order
+ * will get a segfault. */
+ prng_state = &prng_state_data;
+ }
+ prng_srand_r (prng_state, seed);
}
static inline uint32_t
-lcg_rand_n (int max)
+prng_rand_n (int max)
{
- return lcg_rand () % max;
+ return prng_rand () % max;
}
-static inline uint32_t
-lcg_rand_N (int max)
-{
- uint32_t lo = lcg_rand ();
- uint32_t hi = lcg_rand () << 15;
- return (lo | hi) % max;
-}
-
-static inline uint32_t
-lcg_rand_u32 (void)
+static inline void
+prng_randmemset (void *buffer, size_t size, prng_randmemset_flags_t flags)
{
- /* This uses the 10/11 most significant bits from the 3 lcg results
- * (and mixes them with the low from the adjacent one).
- */
- uint32_t lo = lcg_rand() >> -(32 - 15 - 11 * 2);
- uint32_t mid = lcg_rand() << (32 - 15 - 11 * 1);
- uint32_t hi = lcg_rand() << (32 - 15 - 11 * 0);
-
- return (hi ^ mid ^ lo);
+ prng_randmemset_r (prng_state, buffer, size, flags);
}
/* CRC 32 computation
@@ -69,8 +65,12 @@ compute_crc32_for_image (uint32_t in_crc32,
/* Returns TRUE if running on a little endian system
*/
-pixman_bool_t
-is_little_endian (void);
+static force_inline pixman_bool_t
+is_little_endian (void)
+{
+ unsigned long endian_check_var = 1;
+ return *(unsigned char *)&endian_check_var == 1;
+}
/* perform endian conversion of pixel data
*/