aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fontconfig/src/fccache.c28
-rw-r--r--fontconfig/src/fccfg.c102
-rw-r--r--fontconfig/src/fccompat.c27
-rw-r--r--fontconfig/src/fcdir.c10
-rw-r--r--fontconfig/src/fcint.h11
-rw-r--r--fontconfig/src/fcmatch.c2
-rw-r--r--fontconfig/src/fcobjs.c2
-rw-r--r--fontconfig/src/fcobjs.h4
-rw-r--r--fontconfig/src/fcxml.c59
-rw-r--r--libX11/configure.ac6
-rw-r--r--libX11/modules/im/ximcp/imDefIc.c27
-rw-r--r--libX11/modules/im/ximcp/imDefLkup.c17
-rw-r--r--libX11/modules/im/ximcp/imTrans.c8
-rw-r--r--libXdmcp/Key.c10
-rw-r--r--libXdmcp/configure.ac3
-rw-r--r--libxcb/configure.ac6
-rw-r--r--libxcb/src/xcb_list.c2
-rw-r--r--mesalib/Makefile.am6
-rw-r--r--mesalib/configure.ac4
-rw-r--r--mesalib/docs/devinfo.html2
-rw-r--r--mesalib/docs/index.html6
-rw-r--r--mesalib/docs/relnotes.html1
-rw-r--r--mesalib/docs/relnotes/9.1.5.html4
-rw-r--r--mesalib/docs/relnotes/9.1.6.html168
-rw-r--r--mesalib/docs/relnotes/9.2.html4
-rw-r--r--mesalib/docs/sourcetree.html2
-rw-r--r--mesalib/docs/specs/WL_bind_wayland_display.spec8
-rw-r--r--mesalib/include/EGL/eglmesaext.h6
-rw-r--r--mesalib/include/GL/internal/dri_interface.h39
-rw-r--r--mesalib/src/Makefile.am4
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_cpu_detect.c29
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_cpu_detect.h1
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_format_srgb.h56
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_format_srgb.py57
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_math.c2
-rw-r--r--mesalib/src/glsl/ast.h58
-rw-r--r--mesalib/src/glsl/ast_array_index.cpp3
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp362
-rw-r--r--mesalib/src/glsl/ast_type.cpp19
-rw-r--r--mesalib/src/glsl/builtin_variables.cpp13
-rw-r--r--mesalib/src/glsl/glsl_parser.yy90
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp35
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h27
-rw-r--r--mesalib/src/glsl/glsl_types.cpp55
-rw-r--r--mesalib/src/glsl/glsl_types.h12
-rw-r--r--mesalib/src/glsl/ir.cpp21
-rw-r--r--mesalib/src/glsl/ir.h56
-rw-r--r--mesalib/src/glsl/ir_builder.cpp48
-rw-r--r--mesalib/src/glsl/ir_builder.h8
-rw-r--r--mesalib/src/glsl/ir_hierarchical_visitor.cpp18
-rw-r--r--mesalib/src/glsl/ir_hierarchical_visitor.h2
-rw-r--r--mesalib/src/glsl/ir_hv_accept.cpp13
-rw-r--r--mesalib/src/glsl/ir_optimization.h4
-rw-r--r--mesalib/src/glsl/ir_print_visitor.cpp12
-rw-r--r--mesalib/src/glsl/ir_print_visitor.h2
-rw-r--r--mesalib/src/glsl/ir_reader.cpp30
-rw-r--r--mesalib/src/glsl/ir_set_program_inouts.cpp202
-rw-r--r--mesalib/src/glsl/ir_visitor.h4
-rw-r--r--mesalib/src/glsl/link_varyings.cpp23
-rw-r--r--mesalib/src/glsl/link_varyings.h3
-rw-r--r--mesalib/src/glsl/linker.cpp312
-rw-r--r--mesalib/src/glsl/linker.h3
-rw-r--r--mesalib/src/glsl/lower_output_reads.cpp13
-rw-r--r--mesalib/src/glsl/lower_packed_varyings.cpp291
-rw-r--r--mesalib/src/glsl/opt_dead_builtin_varyings.cpp27
-rw-r--r--mesalib/src/glsl/opt_dead_code_local.cpp17
-rw-r--r--mesalib/src/mapi/glapi/gen/EXT_framebuffer_object.xml4
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c38
-rw-r--r--mesalib/src/mesa/drivers/dri/common/dri_util.c4
-rw-r--r--mesalib/src/mesa/drivers/dri/common/xmlconfig.c44
-rw-r--r--mesalib/src/mesa/drivers/dri/common/xmlconfig.h4
-rw-r--r--mesalib/src/mesa/main/api_validate.c70
-rw-r--r--mesalib/src/mesa/main/context.h11
-rw-r--r--mesalib/src/mesa/main/fbobject.c187
-rw-r--r--mesalib/src/mesa/main/fbobject.h6
-rw-r--r--mesalib/src/mesa/main/get.c2
-rw-r--r--mesalib/src/mesa/main/lines.c3
-rw-r--r--mesalib/src/mesa/main/mtypes.h80
-rw-r--r--mesalib/src/mesa/main/shaderapi.c48
-rw-r--r--mesalib/src/mesa/main/shaderapi.h5
-rw-r--r--mesalib/src/mesa/main/shared.c3
-rw-r--r--mesalib/src/mesa/main/texobj.c53
-rw-r--r--mesalib/src/mesa/main/texparam.c22
-rw-r--r--mesalib/src/mesa/main/texstate.c18
-rw-r--r--mesalib/src/mesa/main/varray.c20
-rw-r--r--mesalib/src/mesa/main/version.c1
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp21
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp76
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_array.c82
-rw-r--r--pixman/RELEASING2
-rw-r--r--pixman/pixman/pixman-fast-path.c241
-rw-r--r--pixman/pixman/pixman-general.c7
-rw-r--r--pixman/pixman/pixman-image.c3
-rw-r--r--pixman/pixman/pixman-implementation.c1
-rw-r--r--pixman/pixman/pixman-private.h2
-rw-r--r--pixman/test/Makefile.sources1
-rw-r--r--pixman/test/alpha-loop.c7
-rw-r--r--pixman/test/matrix-test.c53
-rw-r--r--pixman/test/scaling-bench.c69
-rw-r--r--xorg-server/.dir-locals.el1
-rw-r--r--xorg-server/configure.ac2
-rw-r--r--xorg-server/dix/window.c1
-rw-r--r--xorg-server/exa/Makefile.am2
-rw-r--r--xorg-server/glx/Makefile.am4
-rw-r--r--xorg-server/hw/kdrive/ephyr/Makefile.am2
-rw-r--r--xorg-server/hw/kdrive/fake/Makefile.am2
-rw-r--r--xorg-server/hw/kdrive/fbdev/Makefile.am2
-rw-r--r--xorg-server/hw/kdrive/linux/Makefile.am2
-rw-r--r--xorg-server/hw/kdrive/src/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/Makefile.am4
-rw-r--r--xorg-server/hw/xfree86/common/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/ddc/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/dixmods/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/exa/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/fbdevhw/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/i2c/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/int10/Makefile.am6
-rw-r--r--xorg-server/hw/xfree86/loader/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/modes/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/os-support/bsd/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/os-support/bus/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/os-support/hurd/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/os-support/misc/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/os-support/solaris/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/os-support/stub/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/parser/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/parser/write.c3
-rw-r--r--xorg-server/hw/xfree86/ramdac/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/shadowfb/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/utils/cvt/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/vbe/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/vgahw/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/x86emu/Makefile.am2
-rw-r--r--xorg-server/hw/xwin/Makefile.am2
-rw-r--r--xorg-server/hw/xwin/glx/Makefile.am2
-rw-r--r--xorg-server/include/xorg-config.h.in3
-rw-r--r--xorg-server/mi/miinitext.c2
-rw-r--r--xorg-server/miext/damage/Makefile.am2
-rw-r--r--xorg-server/miext/sync/Makefile.am2
-rw-r--r--xorg-server/test/Makefile.am4
-rw-r--r--xorg-server/test/hashtabletest.c4
-rw-r--r--xorg-server/test/xi2/Makefile.am2
-rw-r--r--xorg-server/xkeyboard-config/compat/level52
-rw-r--r--xorg-server/xkeyboard-config/rules/base.extras.xml.in6
-rw-r--r--xorg-server/xkeyboard-config/rules/base.xml.in89
-rw-r--r--xorg-server/xkeyboard-config/symbols/be2
-rw-r--r--xorg-server/xkeyboard-config/symbols/br2
-rw-r--r--xorg-server/xkeyboard-config/symbols/de14
-rw-r--r--xorg-server/xkeyboard-config/symbols/es2
-rw-r--r--xorg-server/xkeyboard-config/symbols/fr4
-rw-r--r--xorg-server/xkeyboard-config/symbols/in270
-rw-r--r--xorg-server/xkeyboard-config/symbols/latin24
-rw-r--r--xorg-server/xkeyboard-config/symbols/pt2
-rw-r--r--xorg-server/xkeyboard-config/symbols/us6
-rw-r--r--xorg-server/xkeyboard-config/tests/genLists4Comparizon.sh6
156 files changed, 3589 insertions, 634 deletions
diff --git a/fontconfig/src/fccache.c b/fontconfig/src/fccache.c
index 9f1c29827..e02d49e8f 100644
--- a/fontconfig/src/fccache.c
+++ b/fontconfig/src/fccache.c
@@ -830,34 +830,6 @@ bail1:
return NULL;
}
-
-#ifdef _WIN32
-#include <direct.h>
-#define mkdir(path,mode) _mkdir(path)
-#endif
-
-static FcBool
-FcMakeDirectory (const FcChar8 *dir)
-{
- FcChar8 *parent;
- FcBool ret;
-
- if (strlen ((char *) dir) == 0)
- return FcFalse;
-
- parent = FcStrDirname (dir);
- if (!parent)
- return FcFalse;
- if (access ((char *) parent, F_OK) == 0)
- ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0;
- else if (access ((char *) parent, F_OK) == -1)
- ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0;
- else
- ret = FcFalse;
- FcStrFree (parent);
- return ret;
-}
-
/* write serialized state to the cache file */
FcBool
FcDirCacheWrite (FcCache *cache, FcConfig *config)
diff --git a/fontconfig/src/fccfg.c b/fontconfig/src/fccfg.c
index 7ea94b846..be738d53d 100644
--- a/fontconfig/src/fccfg.c
+++ b/fontconfig/src/fccfg.c
@@ -674,12 +674,21 @@ FcConfigAddRule (FcConfig *config,
num = 0;
for (r = rule; r; r = r->next)
{
- if (r->type == FcRuleTest)
+ switch (r->type)
{
+ case FcRuleTest:
if (r->u.test &&
r->u.test->kind == FcMatchDefault)
r->u.test->kind = kind;
- num++;
+ if (r->u.test->object > FC_MAX_BASE_OBJECT)
+ num++;
+ break;
+ case FcRuleEdit:
+ if (r->u.edit->object > FC_MAX_BASE_OBJECT)
+ num++;
+ break;
+ default:
+ break;
}
}
if (config->maxObjects < num)
@@ -1486,11 +1495,15 @@ FcConfigSubstituteWithPat (FcConfig *config,
FcValue v;
FcSubst *s;
FcRule *r;
- FcValueList *l, *value = NULL;
+ FcValueList *l, **value = NULL;
FcPattern *m;
FcStrSet *strs;
- FcPatternElt *elt = NULL;
FcObject object = FC_INVALID_OBJECT;
+ FcPatternElt **elt = NULL;
+ int i, nobjs;
+ FcBool retval = FcTrue;
+
+#define FC_OBJ_ID(_n_) ((_n_) > FC_MAX_BASE_OBJECT ? ((_n_) - FC_EXT_OBJ_INDEX) : (_n_))
if (!config)
{
@@ -1535,6 +1548,20 @@ FcConfigSubstituteWithPat (FcConfig *config,
return FcFalse;
}
+ nobjs = FC_MAX_BASE_OBJECT + config->maxObjects + 2;
+ value = (FcValueList **) malloc (SIZEOF_VOID_P * nobjs);
+ if (!value)
+ {
+ retval = FcFalse;
+ goto bail1;
+ }
+ elt = (FcPatternElt **) malloc (SIZEOF_VOID_P * nobjs);
+ if (!elt)
+ {
+ retval = FcFalse;
+ goto bail1;
+ }
+
if (FcDebug () & FC_DBG_EDIT)
{
printf ("FcConfigSubstitute ");
@@ -1543,6 +1570,11 @@ FcConfigSubstituteWithPat (FcConfig *config,
for (; s; s = s->next)
{
r = s->rule;
+ for (i = 0; i < nobjs; i++)
+ {
+ elt[i] = NULL;
+ value[i] = NULL;
+ }
for (; r; r = r->next)
{
switch (r->type) {
@@ -1550,6 +1582,7 @@ FcConfigSubstituteWithPat (FcConfig *config,
/* shouldn't be reached */
break;
case FcRuleTest:
+ object = FC_OBJ_ID (r->u.test->object);
/*
* Check the tests to see if
* they all match the pattern
@@ -1564,18 +1597,16 @@ FcConfigSubstituteWithPat (FcConfig *config,
else
m = p;
if (m)
- elt = FcPatternObjectFindElt (m, r->u.test->object);
- else
- elt = NULL;
+ elt[object] = FcPatternObjectFindElt (m, r->u.test->object);
/*
* If there's no such field in the font,
* then FcQualAll matches while FcQualAny does not
*/
- if (!elt)
+ if (!elt[object])
{
if (r->u.test->qual == FcQualAll)
{
- value = NULL;
+ value[object] = NULL;
continue;
}
else
@@ -1589,18 +1620,18 @@ FcConfigSubstituteWithPat (FcConfig *config,
* Check to see if there is a match, mark the location
* to apply match-relative edits
*/
- value = FcConfigMatchValueList (m, p_pat, kind, r->u.test, elt->values);
- if (!value ||
- (r->u.test->qual == FcQualFirst && value != elt->values) ||
- (r->u.test->qual == FcQualNotFirst && value == elt->values))
+ value[object] = FcConfigMatchValueList (m, p_pat, kind, r->u.test, elt[object]->values);
+ if (!value[object] ||
+ (r->u.test->qual == FcQualFirst && value[object] != elt[object]->values) ||
+ (r->u.test->qual == FcQualNotFirst && value[object] == elt[object]->values))
{
if (FcDebug () & FC_DBG_EDIT)
printf ("No match\n");
goto bail;
}
- object = r->u.test->object;
break;
case FcRuleEdit:
+ object = FC_OBJ_ID (r->u.edit->object);
if (FcDebug () & FC_DBG_EDIT)
{
printf ("Substitute ");
@@ -1611,13 +1642,6 @@ FcConfigSubstituteWithPat (FcConfig *config,
* Evaluate the list of expressions
*/
l = FcConfigValues (p, p_pat,kind, r->u.edit->expr, r->u.edit->binding);
- /*
- * Locate any test associated with this field, skipping
- * tests associated with the pattern when substituting in
- * the font
- */
- if (object != r->u.edit->object)
- value = NULL;
switch (FC_OP_GET_OP (r->u.edit->op)) {
case FcOpAssign:
@@ -1625,25 +1649,25 @@ FcConfigSubstituteWithPat (FcConfig *config,
* If there was a test, then replace the matched
* value with the new list of values
*/
- if (value)
+ if (value[object])
{
- FcValueList *thisValue = value;
- FcValueList *nextValue = thisValue;
+ FcValueList *thisValue = value[object];
+ FcValueList *nextValue = l;
/*
* Append the new list of values after the current value
*/
- FcConfigAdd (&elt->values, thisValue, FcTrue, l, r->u.edit->object);
+ FcConfigAdd (&elt[object]->values, thisValue, FcTrue, l, r->u.edit->object);
/*
* Delete the marked value
*/
if (thisValue)
- FcConfigDel (&elt->values, thisValue);
+ FcConfigDel (&elt[object]->values, thisValue);
/*
* Adjust a pointer into the value list to ensure
* future edits occur at the same place
*/
- value = nextValue;
+ value[object] = nextValue;
break;
}
/* fall through ... */
@@ -1658,12 +1682,12 @@ FcConfigSubstituteWithPat (FcConfig *config,
* Adjust a pointer into the value list as they no
* longer point to anything valid
*/
- value = NULL;
+ value[object] = NULL;
break;
case FcOpPrepend:
- if (value)
+ if (value[object])
{
- FcConfigAdd (&elt->values, value, FcFalse, l, r->u.edit->object);
+ FcConfigAdd (&elt[object]->values, value[object], FcFalse, l, r->u.edit->object);
break;
}
/* fall through ... */
@@ -1671,9 +1695,9 @@ FcConfigSubstituteWithPat (FcConfig *config,
FcConfigPatternAdd (p, r->u.edit->object, l, FcFalse);
break;
case FcOpAppend:
- if (value)
+ if (value[object])
{
- FcConfigAdd (&elt->values, value, FcTrue, l, r->u.edit->object);
+ FcConfigAdd (&elt[object]->values, value[object], FcTrue, l, r->u.edit->object);
break;
}
/* fall through ... */
@@ -1681,9 +1705,9 @@ FcConfigSubstituteWithPat (FcConfig *config,
FcConfigPatternAdd (p, r->u.edit->object, l, FcTrue);
break;
case FcOpDelete:
- if (value)
+ if (value[object])
{
- FcConfigDel (&elt->values, value);
+ FcConfigDel (&elt[object]->values, value[object]);
break;
}
/* fall through ... */
@@ -1715,7 +1739,15 @@ FcConfigSubstituteWithPat (FcConfig *config,
printf ("FcConfigSubstitute done");
FcPatternPrint (p);
}
- return FcTrue;
+bail1:
+ if (elt)
+ free (elt);
+ if (value)
+ free (value);
+
+#undef FC_OBJ_ID
+
+ return retval;
}
FcBool
diff --git a/fontconfig/src/fccompat.c b/fontconfig/src/fccompat.c
index a2171607c..d4f88c83f 100644
--- a/fontconfig/src/fccompat.c
+++ b/fontconfig/src/fccompat.c
@@ -219,3 +219,30 @@ FcRandom(void)
return result;
}
+
+#ifdef _WIN32
+#include <direct.h>
+#define mkdir(path,mode) _mkdir(path)
+#endif
+
+FcBool
+FcMakeDirectory (const FcChar8 *dir)
+{
+ FcChar8 *parent;
+ FcBool ret;
+
+ if (strlen ((char *) dir) == 0)
+ return FcFalse;
+
+ parent = FcStrDirname (dir);
+ if (!parent)
+ return FcFalse;
+ if (access ((char *) parent, F_OK) == 0)
+ ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0;
+ else if (access ((char *) parent, F_OK) == -1)
+ ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0;
+ else
+ ret = FcFalse;
+ FcStrFree (parent);
+ return ret;
+}
diff --git a/fontconfig/src/fcdir.c b/fontconfig/src/fcdir.c
index dc580bb6f..b040a285a 100644
--- a/fontconfig/src/fcdir.c
+++ b/fontconfig/src/fcdir.c
@@ -49,6 +49,16 @@ FcFileIsLink (const FcChar8 *file)
#endif
}
+FcBool
+FcFileIsFile (const FcChar8 *file)
+{
+ struct stat statb;
+
+ if (FcStat (file, &statb) != 0)
+ return FcFalse;
+ return S_ISREG (statb.st_mode);
+}
+
static FcBool
FcFileScanFontConfig (FcFontSet *set,
FcBlanks *blanks,
diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h
index fe523fb7c..ec0c67470 100644
--- a/fontconfig/src/fcint.h
+++ b/fontconfig/src/fcint.h
@@ -174,6 +174,11 @@ typedef struct _FcValueList {
typedef int FcObject;
+/* The 1000 is to leave some room for future added internal objects, such
+ * that caches from newer fontconfig can still be used with older fontconfig
+ * without getting confused. */
+#define FC_EXT_OBJ_INDEX 1000
+
typedef struct _FcPatternElt *FcPatternEltPtr;
/*
@@ -742,6 +747,9 @@ FcMakeTempfile (char *template);
FcPrivate int32_t
FcRandom (void);
+FcPrivate FcBool
+FcMakeDirectory (const FcChar8 *dir);
+
/* fcdbg.c */
FcPrivate void
@@ -800,6 +808,9 @@ FcPrivate FcBool
FcFileIsLink (const FcChar8 *file);
FcPrivate FcBool
+FcFileIsFile (const FcChar8 *file);
+
+FcPrivate FcBool
FcFileScanConfig (FcFontSet *set,
FcStrSet *dirs,
FcBlanks *blanks,
diff --git a/fontconfig/src/fcmatch.c b/fontconfig/src/fcmatch.c
index 10976d6e8..dec92b9cf 100644
--- a/fontconfig/src/fcmatch.c
+++ b/fontconfig/src/fcmatch.c
@@ -245,6 +245,8 @@ typedef enum _FcMatcherPriorityDummy {
typedef enum _FcMatcherPriority {
PRI1(HASH),
PRI1(FILE),
+ PRI1(FONTFORMAT),
+ PRI1(SCALABLE),
PRI1(FOUNDRY),
PRI1(CHARSET),
PRI_FAMILY_STRONG,
diff --git a/fontconfig/src/fcobjs.c b/fontconfig/src/fcobjs.c
index 1d3af73be..bad9824d4 100644
--- a/fontconfig/src/fcobjs.c
+++ b/fontconfig/src/fcobjs.c
@@ -37,7 +37,7 @@ FcObjectTypeLookup (register const char *str, register unsigned int len);
/* The 1000 is to leave some room for future added internal objects, such
* that caches from newer fontconfig can still be used with older fontconfig
* without getting confused. */
-static fc_atomic_int_t next_id = FC_MAX_BASE_OBJECT + 1000;
+static fc_atomic_int_t next_id = FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX;
struct FcObjectOtherTypeInfo {
struct FcObjectOtherTypeInfo *next;
FcObjectType object;
diff --git a/fontconfig/src/fcobjs.h b/fontconfig/src/fcobjs.h
index 682fe6ad3..87c7319e3 100644
--- a/fontconfig/src/fcobjs.h
+++ b/fontconfig/src/fcobjs.h
@@ -23,7 +23,7 @@ FC_OBJECT (FILE, FcTypeString, FcCompareFilename)
FC_OBJECT (INDEX, FcTypeInteger, NULL)
FC_OBJECT (RASTERIZER, FcTypeString, FcCompareString)
FC_OBJECT (OUTLINE, FcTypeBool, FcCompareBool)
-FC_OBJECT (SCALABLE, FcTypeBool, NULL)
+FC_OBJECT (SCALABLE, FcTypeBool, FcCompareBool)
FC_OBJECT (DPI, FcTypeDouble, NULL)
FC_OBJECT (RGBA, FcTypeInteger, NULL)
FC_OBJECT (SCALE, FcTypeDouble, NULL)
@@ -35,7 +35,7 @@ FC_OBJECT (CHARSET, FcTypeCharSet, FcCompareCharSet)
FC_OBJECT (LANG, FcTypeLangSet, FcCompareLang)
FC_OBJECT (FONTVERSION, FcTypeInteger, FcCompareNumber)
FC_OBJECT (CAPABILITY, FcTypeString, NULL)
-FC_OBJECT (FONTFORMAT, FcTypeString, NULL)
+FC_OBJECT (FONTFORMAT, FcTypeString, FcCompareString)
FC_OBJECT (EMBOLDEN, FcTypeBool, NULL)
FC_OBJECT (EMBEDDED_BITMAP, FcTypeBool, NULL)
FC_OBJECT (DECORATIVE, FcTypeBool, FcCompareBool)
diff --git a/fontconfig/src/fcxml.c b/fontconfig/src/fcxml.c
index 6a2af85e3..2cdf0ad0a 100644
--- a/fontconfig/src/fcxml.c
+++ b/fontconfig/src/fcxml.c
@@ -2182,6 +2182,8 @@ FcParseInclude (FcConfigParse *parse)
FcBool ignore_missing = FcFalse;
FcBool deprecated = FcFalse;
FcChar8 *prefix = NULL, *p;
+ static FcChar8 *userdir = NULL;
+ static FcChar8 *userconf = NULL;
s = FcStrBufDoneStatic (&parse->pstack->str);
if (!s)
@@ -2214,23 +2216,78 @@ FcParseInclude (FcConfigParse *parse)
memcpy (&prefix[plen + 1], s, dlen);
prefix[plen + 1 + dlen] = 0;
s = prefix;
+ if (FcFileIsDir (s))
+ {
+ userdir:
+ if (!userdir)
+ userdir = FcStrdup (s);
+ }
+ else if (FcFileIsFile (s))
+ {
+ userconf:
+ if (!userconf)
+ userconf = FcStrdup (s);
+ }
+ else
+ {
+ /* No config dir nor file on the XDG directory spec compliant place
+ * so need to guess what it is supposed to be.
+ */
+ FcChar8 *parent = FcStrDirname (s);
+
+ if (!FcFileIsDir (parent))
+ FcMakeDirectory (parent);
+ FcStrFree (parent);
+ if (FcStrStr (s, (const FcChar8 *)"conf.d") != NULL)
+ goto userdir;
+ else
+ goto userconf;
+ }
}
if (!FcConfigParseAndLoad (parse->config, s, !ignore_missing))
parse->error = FcTrue;
+#ifndef _WIN32
else
{
FcChar8 *filename;
+ static FcBool warn_conf = FcFalse, warn_confd = FcFalse;
filename = FcConfigFilename(s);
if (deprecated == FcTrue &&
filename != NULL &&
!FcFileIsLink (filename))
{
- FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated.", s);
+ if (FcFileIsDir (filename))
+ {
+ if (FcFileIsDir (userdir) ||
+ rename ((const char *)filename, (const char *)userdir) != 0 ||
+ symlink ((const char *)userdir, (const char *)filename) != 0)
+ {
+ if (!warn_confd)
+ {
+ FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userdir);
+ warn_confd = FcTrue;
+ }
+ }
+ }
+ else
+ {
+ if (FcFileIsFile (userconf) ||
+ rename ((const char *)filename, (const char *)userconf) != 0 ||
+ symlink ((const char *)userconf, (const char *)filename) != 0)
+ {
+ if (!warn_conf)
+ {
+ FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userconf);
+ warn_conf = FcTrue;
+ }
+ }
+ }
}
if(filename)
FcStrFree(filename);
}
+#endif
FcStrBufDestroy (&parse->pstack->str);
bail:
diff --git a/libX11/configure.ac b/libX11/configure.ac
index ff04f8a3e..d3becda9f 100644
--- a/libX11/configure.ac
+++ b/libX11/configure.ac
@@ -438,9 +438,9 @@ 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.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 \
+ ja.SJIS km_KH.UTF-8 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 sr_CS.UTF-8 \
tatar-cyr th_TH th_TH.UTF-8 tscii-0 vi_VN.tcvn vi_VN.viscii \
zh_CN zh_CN.gb18030 zh_CN.gbk zh_CN.UTF-8 zh_HK.big5 \
zh_HK.big5hkscs zh_HK.UTF-8 zh_TW zh_TW.big5 zh_TW.UTF-8"
diff --git a/libX11/modules/im/ximcp/imDefIc.c b/libX11/modules/im/ximcp/imDefIc.c
index 3b5fa4147..f7e484789 100644
--- a/libX11/modules/im/ximcp/imDefIc.c
+++ b/libX11/modules/im/ximcp/imDefIc.c
@@ -927,6 +927,30 @@ _XimProtoDestroyIC(
return;
}
+/*
+ * Some functions require the request queue from the server to be flushed
+ * so that the ordering of client initiated status changes and those requested
+ * by the server is well defined.
+ * _XimSync() would be the function of choice here as it should get a
+ * XIM_SYNC_REPLY back from the server.
+ * This however isn't implemented in the piece of junk that is used by most
+ * input servers as the server side protocol if to XIM.
+ * Since this code is not shipped as a library together with the client side
+ * XIM code but is duplicated by every input server around the world there
+ * is no easy fix to this but this ugly hack below.
+ * Obtaining an IC value from the server sends a request and empties out the
+ * event/server request queue until the answer to this request is found.
+ * Thus it is guaranteed that any pending server side request gets processed.
+ * This is what the hack below is doing.
+ */
+
+static void
+BrokenSyncWithServer(XIC xic)
+{
+ CARD32 dummy;
+ XGetICValues(xic, XNFilterEvents, &dummy, NULL);
+}
+
static void
_XimProtoSetFocus(
XIC xic)
@@ -957,6 +981,7 @@ _XimProtoSetFocus(
}
}
#endif /* XIM_CONNECTABLE */
+ BrokenSyncWithServer(xic);
buf_s[0] = im->private.proto.imid; /* imid */
buf_s[1] = ic->private.proto.icid; /* icid */
@@ -1003,6 +1028,8 @@ _XimProtoUnsetFocus(
}
#endif /* XIM_CONNECTABLE */
+ BrokenSyncWithServer(xic);
+
buf_s[0] = im->private.proto.imid; /* imid */
buf_s[1] = ic->private.proto.icid; /* icid */
diff --git a/libX11/modules/im/ximcp/imDefLkup.c b/libX11/modules/im/ximcp/imDefLkup.c
index 0a9553a41..b4315894f 100644
--- a/libX11/modules/im/ximcp/imDefLkup.c
+++ b/libX11/modules/im/ximcp/imDefLkup.c
@@ -269,6 +269,8 @@ _XimForwardEventCore(
int ret_code;
INT16 len;
+ bzero(buf32, sizeof(buf32)); /* valgrind noticed uninitialized memory use! */
+
if (!(len = _XimSetEventToWire(ev, (xEvent *)&buf_s[4])))
return False; /* X event */
@@ -704,7 +706,11 @@ _XimCommitRecv(
(void)_XimRespSyncReply(ic, flag);
- MARK_FABRICATED(im);
+ if (ic->private.proto.registed_filter_event
+ & (KEYPRESS_MASK | KEYRELEASE_MASK))
+ MARK_FABRICATED(im);
+
+ bzero(&ev, sizeof(ev)); /* uninitialized : found when running kterm under valgrind */
ev.type = KeyPress;
ev.send_event = False;
@@ -713,6 +719,15 @@ _XimCommitRecv(
ev.keycode = 0;
ev.state = 0;
+ ev.time = 0L;
+ ev.serial = LastKnownRequestProcessed(im->core.display);
+ /* FIXME :
+ I wish there were COMMENTs (!) about the data passed around.
+ */
+#if 0
+ fprintf(stderr,"%s,%d: putback k press FIXED ev.time=0 ev.serial=%lu\n", __FILE__, __LINE__, ev.serial);
+#endif
+
XPutBackEvent(im->core.display, (XEvent *)&ev);
return True;
diff --git a/libX11/modules/im/ximcp/imTrans.c b/libX11/modules/im/ximcp/imTrans.c
index 4bdecb2ef..a8cd95e8f 100644
--- a/libX11/modules/im/ximcp/imTrans.c
+++ b/libX11/modules/im/ximcp/imTrans.c
@@ -222,12 +222,20 @@ _XimTransInternalConnection(
if (spec->is_putback)
return;
+
+ bzero(&ev, sizeof(ev)); /* FIXME: other fields may be accessed, too. */
kev = (XKeyEvent *)&ev;
kev->type = KeyPress;
kev->send_event = False;
kev->display = im->core.display;
kev->window = spec->window;
kev->keycode = 0;
+ kev->time = 0L;
+ kev->serial = LastKnownRequestProcessed(im->core.display);
+#if 0
+ fprintf(stderr,"%s,%d: putback FIXED kev->time=0 kev->serial=%lu\n", __FILE__, __LINE__, kev->serial);
+#endif
+
XPutBackEvent(im->core.display, &ev);
XFlush(im->core.display);
spec->is_putback = True;
diff --git a/libXdmcp/Key.c b/libXdmcp/Key.c
index aa4add653..a09b316f4 100644
--- a/libXdmcp/Key.c
+++ b/libXdmcp/Key.c
@@ -32,6 +32,11 @@ in this Software without prior written authorization from The Open Group.
#include <X11/Xmd.h>
#include <X11/Xdmcp.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/stdlib.h> /* for arc4random_buf() */
+#endif
+
+#ifndef HAVE_ARC4RANDOM_BUF
static void
getbits (long data, unsigned char *dst)
{
@@ -40,6 +45,7 @@ getbits (long data, unsigned char *dst)
dst[2] = (data >> 16) & 0xff;
dst[3] = (data >> 24) & 0xff;
}
+#endif
#define Time_t time_t
@@ -59,6 +65,7 @@ getbits (long data, unsigned char *dst)
void
XdmcpGenerateKey (XdmAuthKeyPtr key)
{
+#ifndef HAVE_ARC4RANDOM_BUF
long lowbits, highbits;
srandom ((int)getpid() ^ time((Time_t *)0));
@@ -66,6 +73,9 @@ XdmcpGenerateKey (XdmAuthKeyPtr key)
highbits = random ();
getbits (lowbits, key->data);
getbits (highbits, key->data + 4);
+#else
+ arc4random_buf(key->data, 8);
+#endif
}
int
diff --git a/libXdmcp/configure.ac b/libXdmcp/configure.ac
index 08c046ae0..d8ddfae93 100644
--- a/libXdmcp/configure.ac
+++ b/libXdmcp/configure.ac
@@ -53,7 +53,8 @@ AC_PROG_LN_S
AC_SEARCH_LIBS([recvfrom],[socket])
# Checks for library functions.
-AC_CHECK_FUNCS([srand48 lrand48])
+AC_CHECK_LIB([bsd], [arc4random_buf])
+AC_CHECK_FUNCS([srand48 lrand48 arc4random_buf])
# Obtain compiler/linker options for depedencies
PKG_CHECK_MODULES(XDMCP, xproto)
diff --git a/libxcb/configure.ac b/libxcb/configure.ac
index 736438305..482f85b2b 100644
--- a/libxcb/configure.ac
+++ b/libxcb/configure.ac
@@ -128,12 +128,12 @@ xcbincludedir='${includedir}/xcb'
AC_SUBST(xcbincludedir)
if test "x$GCC" = xyes ; then
- CWARNFLAGS="-Wall -pedantic -Wpointer-arith \
+ CWARNFLAGS="-Wall -pedantic -Wpointer-arith -Wold-style-definition \
-Wstrict-prototypes -Wmissing-declarations -Wnested-externs"
else
AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
if test "x$SUNCC" = "xyes"; then
- CWARNFLAGS="-v"
+ CWARNFLAGS="-v -fd"
fi
fi
AC_SUBST(CWARNFLAGS)
@@ -192,7 +192,7 @@ XCB_EXTENSION(XFixes, "yes")
XCB_EXTENSION(XFree86-DRI, "yes")
XCB_EXTENSION(Xinerama, "yes")
XCB_EXTENSION(XInput, "no")
-XCB_EXTENSION(XKB, "no")
+XCB_EXTENSION(XKB, "yes")
XCB_EXTENSION(Xprint, "yes")
XCB_EXTENSION(SELinux, "no")
XCB_EXTENSION(XTest, "yes")
diff --git a/libxcb/src/xcb_list.c b/libxcb/src/xcb_list.c
index 6f5c61190..129540bc4 100644
--- a/libxcb/src/xcb_list.c
+++ b/libxcb/src/xcb_list.c
@@ -47,7 +47,7 @@ struct _xcb_map {
/* Private interface */
-_xcb_map *_xcb_map_new()
+_xcb_map *_xcb_map_new(void)
{
_xcb_map *list;
list = malloc(sizeof(_xcb_map));
diff --git a/mesalib/Makefile.am b/mesalib/Makefile.am
index ce391c409..343badef4 100644
--- a/mesalib/Makefile.am
+++ b/mesalib/Makefile.am
@@ -52,12 +52,6 @@ EXTRA_FILES = \
src/glsl/glcpp/glcpp-lex.c \
src/glsl/glcpp/glcpp-parse.c \
src/glsl/glcpp/glcpp-parse.h \
- src/mesa/main/api_exec_es1.c \
- src/mesa/main/api_exec_es1_dispatch.h \
- src/mesa/main/api_exec_es1_remap_helper.h \
- src/mesa/main/api_exec_es2.c \
- src/mesa/main/api_exec_es2_dispatch.h \
- src/mesa/main/api_exec_es2_remap_helper.h \
src/mesa/program/lex.yy.c \
src/mesa/program/program_parse.tab.c \
src/mesa/program/program_parse.tab.h \
diff --git a/mesalib/configure.ac b/mesalib/configure.ac
index 62d06e035..0dcd2a51f 100644
--- a/mesalib/configure.ac
+++ b/mesalib/configure.ac
@@ -1617,6 +1617,10 @@ if test "x$enable_gallium_llvm" = xyes; then
if $LLVM_CONFIG --components | grep -qw 'irreader'; then
LLVM_COMPONENTS="${LLVM_COMPONENTS} irreader"
fi
+ # LLVM 3.4 requires Option
+ if $LLVM_CONFIG --components | grep -qw 'option'; then
+ LLVM_COMPONENTS="${LLVM_COMPONENTS} option"
+ fi
fi
DEFINES="${DEFINES} -DHAVE_LLVM=0x0$LLVM_VERSION_INT"
MESA_LLVM=1
diff --git a/mesalib/docs/devinfo.html b/mesalib/docs/devinfo.html
index bf7725961..4c1099c5e 100644
--- a/mesalib/docs/devinfo.html
+++ b/mesalib/docs/devinfo.html
@@ -36,7 +36,7 @@ To add a new GL extension to Mesa you have to do at least the following.
</pre>
</li>
<li>
- In the src/mesa/glapi/ directory, add the new extension functions and
+ In the src/mapi/glapi/gen/ directory, add the new extension functions and
enums to the gl_API.xml file.
Then, a bunch of source files must be regenerated by executing the
corresponding Python scripts.
diff --git a/mesalib/docs/index.html b/mesalib/docs/index.html
index f0c51703f..30f58ab42 100644
--- a/mesalib/docs/index.html
+++ b/mesalib/docs/index.html
@@ -16,6 +16,12 @@
<h1>News</h1>
+<h2>August 1, 2013</h2>
+<p>
+<a href="relnotes/9.1.6.html">Mesa 9.1.6</a> is released.
+This is a bug fix release.
+</p>
+
<h2>July 17, 2013</h2>
<p>
<a href="relnotes/9.1.5.html">Mesa 9.1.5</a> is released.
diff --git a/mesalib/docs/relnotes.html b/mesalib/docs/relnotes.html
index 3d391c061..e33835abc 100644
--- a/mesalib/docs/relnotes.html
+++ b/mesalib/docs/relnotes.html
@@ -22,6 +22,7 @@ The release notes summarize what's new or changed in each Mesa release.
<ul>
<li><a href="relnotes/9.2.html">9.2 release notes</a>
+<li><a href="relnotes/9.1.6.html">9.1.6 release notes</a>
<li><a href="relnotes/9.1.5.html">9.1.5 release notes</a>
<li><a href="relnotes/9.1.4.html">9.1.4 release notes</a>
<li><a href="relnotes/9.1.3.html">9.1.3 release notes</a>
diff --git a/mesalib/docs/relnotes/9.1.5.html b/mesalib/docs/relnotes/9.1.5.html
index fcc47c4f4..05f35e825 100644
--- a/mesalib/docs/relnotes/9.1.5.html
+++ b/mesalib/docs/relnotes/9.1.5.html
@@ -30,7 +30,9 @@ because GL_ARB_compatibility is not supported.
<h2>MD5 checksums</h2>
<pre>
-TBD
+4ed2af5943141a85a21869053a2fc2eb MesaLib-9.1.5.tar.bz2
+47181066acf3231d74e027b2033f9455 MesaLib-9.1.5.tar.gz
+4c9c6615bd99215325250f87ed34058f MesaLib-9.1.5.zip
</pre>
<h2>New features</h2>
diff --git a/mesalib/docs/relnotes/9.1.6.html b/mesalib/docs/relnotes/9.1.6.html
new file mode 100644
index 000000000..c27b0a619
--- /dev/null
+++ b/mesalib/docs/relnotes/9.1.6.html
@@ -0,0 +1,168 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <title>Mesa Release Notes</title>
+ <link rel="stylesheet" type="text/css" href="../mesa.css">
+</head>
+<body>
+
+<div class="header">
+ <h1>The Mesa 3D Graphics Library</h1>
+</div>
+
+<iframe src="../contents.html"></iframe>
+<div class="content">
+
+<h1>Mesa 9.1.6 Release Notes / August 1, 2013</h1>
+
+<p>
+Mesa 9.1.6 is a bug fix release which fixes bugs found since the 9.1.5 release.
+</p>
+<p>
+Mesa 9.1 implements the OpenGL 3.1 API, but the version reported by
+glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
+glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 3.1. OpenGL
+3.1 is <strong>only</strong> available if requested at context creation
+because GL_ARB_compatibility is not supported.
+</p>
+
+<h2>MD5 checksums</h2>
+<pre>
+443a2a352667294b53d56cb1a74114e9 MesaLib-9.1.6.tar.bz2
+08d3069cccd6821e5f33e0840bca0718 MesaLib-9.1.6.tar.gz
+90aa7a6d9878cdbfcb055312f356d6b9 MesaLib-9.1.6.zip
+</pre>
+
+<h2>New features</h2>
+<p>None.</p>
+
+<h2>Bug fixes</h2>
+
+<p>This list is likely incomplete.</p>
+
+<ul>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=47824">Bug 47824</a> - osmesa using --enable-shared-glapi depends on libgl</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=62362">Bug 62362</a> - Crash when using Wayland EGL platform</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=63435">Bug 63435</a> - [Regression since 9.0] Flickering in EGL OpenGL full-screen window with swap interval 1</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=64087">Bug 64087</a> - Webgl conformance shader-with-non-reserved-words crash when mesa is compiled without --enable-debug</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=64330">Bug 64330</a> - WebGL snake demo crash in loop_analysis.cpp:506: bool is_loop_terminator(ir_if*): assertion „inst != __null“ failed.</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=65236">Bug 65236</a> - [i965] Rendering artifacts in VDrift/GL2</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=66558">Bug 66558</a> - RS690: 3D artifacts when playing SuperTuxKart</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=66847">Bug 66847</a> - compilation broken with llvm 3.3</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=66850">Bug 66850</a> - glGenerateMipmap crashes when using GL_TEXTURE_2D_ARRAY with compressed internal format</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=66921">Bug 66921</a> - [r300g] Heroes of Newerth: HiZ related corruption</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=67283">Bug 67283</a> - VDPAU doesn't work on hybrid laptop through DRI_PRIME</li>
+
+</ul>
+
+<h2>Changes</h2>
+<p>The full set of changes can be viewed by using the following GIT command:</p>
+
+<pre>
+ git log mesa-9.1.5..mesa-9.1.6
+</pre>
+
+<p>Andreas Boll (1):</p>
+<ul>
+ <li>configure.ac: Require llvm-3.2 for r600g/radeonsi llvm backends</li>
+</ul>
+
+<p>Brian Paul (4):</p>
+<ul>
+ <li>mesa: handle 2D texture arrays in get_tex_rgba_compressed()</li>
+ <li>meta: handle 2D texture arrays in decompress_texture_image()</li>
+ <li>mesa: implement mipmap generation for compressed 2D array textures</li>
+ <li>mesa: improve free() cleanup in generate_mipmap_compressed()</li>
+</ul>
+
+<p>Carl Worth (7):</p>
+<ul>
+ <li>docs: Add 9.1.5 release md5sums</li>
+ <li>Merge 'origin/9.1' into stable</li>
+ <li>cherry-ignore: Drop 13 patches from the pick list</li>
+ <li>get-pick-list.sh: Include commits mentionining "CC: mesa-stable..." in pick list</li>
+ <li>get-pick-list: Allow for non-whitespace between "CC:" and "mesa-stable"</li>
+ <li>get-pick-list: Ignore commits which CC mesa-stable unless they say "9.1"</li>
+ <li>Bump version to 9.1.6</li>
+</ul>
+
+<p>Chris Forbes (5):</p>
+<ul>
+ <li>i965/Gen4: Zero extra coordinates for ir_tex</li>
+ <li>i965/vs: Fix flaky texture swizzling</li>
+ <li>i965/vs: set up sampler state pointer for Gen4/5.</li>
+ <li>i965/vs: Put lod parameter in the correct place for Gen4</li>
+ <li>i965/vs: Gen4/5: enable front colors if back colors are written</li>
+</ul>
+
+<p>Christoph Bumiller (1):</p>
+<ul>
+ <li>nv50,nvc0: s/uint16/uint32 for constant buffer offset</li>
+</ul>
+
+<p>Dave Airlie (1):</p>
+<ul>
+ <li>gallium/vl: add prime support</li>
+</ul>
+
+<p>Eric Anholt (1):</p>
+<ul>
+ <li>egl: Restore "bogus" DRI2 invalidate event code.</li>
+</ul>
+
+<p>Jeremy Huddleston Sequoia (1):</p>
+<ul>
+ <li>Apple: glFlush() is not needed with CGLFlushDrawable()</li>
+</ul>
+
+<p>Kenneth Graunke (1):</p>
+<ul>
+ <li>glsl: Classify "layout" like other identifiers.</li>
+</ul>
+
+<p>Kristian Høgsberg (1):</p>
+<ul>
+ <li>egl-wayland: Fix left-over wl_display_roundtrip() usage</li>
+</ul>
+
+<p>Maarten Lankhorst (2):</p>
+<ul>
+ <li>osmesa: link against static libglapi library too to get the gl exports</li>
+ <li>nvc0: force use of correct firmware file</li>
+</ul>
+
+<p>Marek Olšák (4):</p>
+<ul>
+ <li>r300g/swtcl: fix geometry corruption by uploading indices to a buffer</li>
+ <li>r300g/swtcl: fix a lockup in MSAA resolve</li>
+ <li>Revert "r300g: allow HiZ with a 16-bit zbuffer"</li>
+ <li>r600g: increase array size for shader inputs and outputs</li>
+</ul>
+
+<p>Matt Turner (2):</p>
+<ul>
+ <li>i965: NULL check prog on shader compilation failure.</li>
+ <li>i965/vs: Print error if vertex shader fails to compile.</li>
+</ul>
+
+<p>Paul Berry (1):</p>
+<ul>
+ <li>glsl: Handle empty if statement encountered during loop analysis.</li>
+</ul>
+
+</div>
+</body>
+</html>
diff --git a/mesalib/docs/relnotes/9.2.html b/mesalib/docs/relnotes/9.2.html
index 4e419f166..1f93b8963 100644
--- a/mesalib/docs/relnotes/9.2.html
+++ b/mesalib/docs/relnotes/9.2.html
@@ -53,6 +53,7 @@ Note: some of the new features are only available with certain drivers.
<li>Added new freedreno gallium driver</li>
<li>OSMesa interface for gallium llvmpipe/softpipe drivers</li>
<li>Gallium Heads-Up Display (HUD) feature for performance monitoring</li>
+<li>Added support for UVD (2.2 and 3.0) video decoding on r600g and radeonsi through VDPAU (requires Kernel 3.10 or later)</li>
</ul>
@@ -71,7 +72,8 @@ Note: some of the new features are only available with certain drivers.
the (unsupported) GDI driver.</li>
<li>GL_EXT_separate_shader_objects has been removed from all Gallium drivers,
because it disallows a critical GLSL shader optimization.
- GL_ARB_separate_shader_objects doesn't have this issue.
+ GL_ARB_separate_shader_objects doesn't have this issue.</li>
+<li>i965 Gen6+ requires Kernel 3.6 or later. (92d2f5a)</li>
</ul>
</div>
diff --git a/mesalib/docs/sourcetree.html b/mesalib/docs/sourcetree.html
index 530c333c4..a6868d398 100644
--- a/mesalib/docs/sourcetree.html
+++ b/mesalib/docs/sourcetree.html
@@ -59,7 +59,6 @@ each directory.
<li><b>osmesa</b> - off-screen software driver
<li>XXX more
</ul>
- <li><b>es</b> - OpenGL ES overlay, parallelly buildable with the core Mesa
<li><b>math</b> - vertex array translation and transformation code
(not used with Gallium)
<li><b>program</b> - Vertex/fragment shader and GLSL compiler code
@@ -135,7 +134,6 @@ each directory.
<li><b>clover</b> - OpenCL state tracker
<li><b>dri</b> - Meta state tracker for DRI drivers
<li><b>egl</b> - Meta state tracker for EGL drivers
- <li><b>es</b> - OpenGL ES 1.x and 2.x state trackers
<li><b>glx</b> - Meta state tracker for GLX
<li><b>vdpau</b> - VDPAU state tracker
<li><b>vega</b> - OpenVG 1.x state tracker
diff --git a/mesalib/docs/specs/WL_bind_wayland_display.spec b/mesalib/docs/specs/WL_bind_wayland_display.spec
index 02bd6ea21..8f0083c24 100644
--- a/mesalib/docs/specs/WL_bind_wayland_display.spec
+++ b/mesalib/docs/specs/WL_bind_wayland_display.spec
@@ -17,7 +17,7 @@ Status
Version
- Version 1, March 1, 2011
+ Version 5, July 16, 2013
Number
@@ -57,7 +57,7 @@ New Procedures and Functions
struct wl_display *display);
EGLBoolean eglQueryWaylandBufferWL(EGLDisplay dpy,
- struct wl_buffer *buffer,
+ struct wl_resource *buffer,
EGLint attribute, EGLint *value);
New Tokens
@@ -173,3 +173,7 @@ Revision History
Use EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB, and EGL_TEXTURE_RGBA,
and just define the new YUV texture formats. Add support for
EGL_WIDTH and EGL_HEIGHT in the query attributes (Kristian Høgsberg)
+ Version 5, July 16, 2013
+ Change eglQueryWaylandBufferWL to take a resource pointer to the
+ buffer instead of a pointer to a struct wl_buffer, as the latter has
+ been deprecated. (Ander Conselvan de Oliveira)
diff --git a/mesalib/include/EGL/eglmesaext.h b/mesalib/include/EGL/eglmesaext.h
index d476d18a2..e0eae281f 100644
--- a/mesalib/include/EGL/eglmesaext.h
+++ b/mesalib/include/EGL/eglmesaext.h
@@ -120,15 +120,15 @@ typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDRMDISPLAYMESA) (int fd);
#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
struct wl_display;
-struct wl_buffer;
+struct wl_resource;
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_buffer *buffer, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
#endif
typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, struct wl_buffer *buffer, EGLint attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
#endif
diff --git a/mesalib/include/GL/internal/dri_interface.h b/mesalib/include/GL/internal/dri_interface.h
index 5c99d5596..be31bb874 100644
--- a/mesalib/include/GL/internal/dri_interface.h
+++ b/mesalib/include/GL/internal/dri_interface.h
@@ -940,7 +940,7 @@ struct __DRIdri2ExtensionRec {
* extensions.
*/
#define __DRI_IMAGE "DRI_IMAGE"
-#define __DRI_IMAGE_VERSION 7
+#define __DRI_IMAGE_VERSION 8
/**
* These formats correspond to the similarly named MESA_FORMAT_*
@@ -1027,6 +1027,25 @@ struct __DRIdri2ExtensionRec {
* 7+. Each query will return a
* new fd. */
+enum __DRIYUVColorSpace {
+ __DRI_YUV_COLOR_SPACE_UNDEFINED = 0,
+ __DRI_YUV_COLOR_SPACE_ITU_REC601 = 0x327F,
+ __DRI_YUV_COLOR_SPACE_ITU_REC709 = 0x3280,
+ __DRI_YUV_COLOR_SPACE_ITU_REC2020 = 0x3281
+};
+
+enum __DRISampleRange {
+ __DRI_YUV_RANGE_UNDEFINED = 0,
+ __DRI_YUV_FULL_RANGE = 0x3282,
+ __DRI_YUV_NARROW_RANGE = 0x3283
+};
+
+enum __DRIChromaSiting {
+ __DRI_YUV_CHROMA_SITING_UNDEFINED = 0,
+ __DRI_YUV_CHROMA_SITING_0 = 0x3284,
+ __DRI_YUV_CHROMA_SITING_0_5 = 0x3285
+};
+
/**
* \name Reasons that __DRIimageExtensionRec::createImageFromTexture might fail
*/
@@ -1132,6 +1151,24 @@ struct __DRIimageExtensionRec {
int *fds, int num_fds,
int *strides, int *offsets,
void *loaderPrivate);
+
+ /**
+ * Like createImageFromFds, but takes additional attributes.
+ *
+ * For EGL_EXT_image_dma_buf_import.
+ *
+ * \since 8
+ */
+ __DRIimage *(*createImageFromDmaBufs)(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ int *fds, int num_fds,
+ int *strides, int *offsets,
+ enum __DRIYUVColorSpace color_space,
+ enum __DRISampleRange sample_range,
+ enum __DRIChromaSiting horiz_siting,
+ enum __DRIChromaSiting vert_siting,
+ unsigned *error,
+ void *loaderPrivate);
};
diff --git a/mesalib/src/Makefile.am b/mesalib/src/Makefile.am
index b3dc44d6f..76280a0c0 100644
--- a/mesalib/src/Makefile.am
+++ b/mesalib/src/Makefile.am
@@ -29,6 +29,10 @@ if HAVE_DRI_GLX
SUBDIRS += glx
endif
+if HAVE_EGL_PLATFORM_WAYLAND
+SUBDIRS += egl/wayland
+endif
+
if HAVE_GBM
SUBDIRS += gbm
endif
diff --git a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c
index 588fc7c72..87ad78095 100644
--- a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c
+++ b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.c
@@ -230,8 +230,28 @@ static INLINE uint64_t xgetbv(void)
#else
return 0;
#endif
+}
+
+#if defined(PIPE_ARCH_X86)
+static INLINE boolean sse2_has_daz(void)
+{
+ struct {
+ uint32_t pad1[7];
+ uint32_t mxcsr_mask;
+ uint32_t pad2[128-8];
+ } PIPE_ALIGN_VAR(16) fxarea;
+
+ fxarea.mxcsr_mask = 0;
+#if (defined(PIPE_CC_GCC) || defined(PIPE_CC_SUNPRO))
+ __asm __volatile ("fxsave %0" : "+m" (fxarea));
+#elif (defined(PIPE_CC_MSVC) || defined(PIPE_CC_ICL))
+ _fxsave(&fxarea);
+#endif
+ return !!(fxarea.mxcsr_mask & (1 << 6));
}
+#endif
+
#endif /* X86 or X86_64 */
void
@@ -310,6 +330,12 @@ util_cpu_detect(void)
((xgetbv() & 6) == 6); // XMM & YMM
util_cpu_caps.has_f16c = (regs2[2] >> 29) & 1;
util_cpu_caps.has_mmx2 = util_cpu_caps.has_sse; /* SSE cpus supports mmxext too */
+#if defined(PIPE_ARCH_X86_64)
+ util_cpu_caps.has_daz = 1;
+#else
+ util_cpu_caps.has_daz = util_cpu_caps.has_sse3 ||
+ (util_cpu_caps.has_sse2 && sse2_has_daz());
+#endif
cacheline = ((regs2[1] >> 8) & 0xFF) * 8;
if (cacheline > 0)
@@ -368,9 +394,12 @@ util_cpu_detect(void)
debug_printf("util_cpu_caps.has_sse4_1 = %u\n", util_cpu_caps.has_sse4_1);
debug_printf("util_cpu_caps.has_sse4_2 = %u\n", util_cpu_caps.has_sse4_2);
debug_printf("util_cpu_caps.has_avx = %u\n", util_cpu_caps.has_avx);
+ debug_printf("util_cpu_caps.has_f16c = %u\n", util_cpu_caps.has_f16c);
+ debug_printf("util_cpu_caps.has_popcnt = %u\n", util_cpu_caps.has_popcnt);
debug_printf("util_cpu_caps.has_3dnow = %u\n", util_cpu_caps.has_3dnow);
debug_printf("util_cpu_caps.has_3dnow_ext = %u\n", util_cpu_caps.has_3dnow_ext);
debug_printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec);
+ debug_printf("util_cpu_caps.has_daz = %u\n", util_cpu_caps.has_daz);
}
#endif
diff --git a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h
index f9cd6475e..cc3e0ce03 100644
--- a/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h
+++ b/mesalib/src/gallium/auxiliary/util/u_cpu_detect.h
@@ -68,6 +68,7 @@ struct util_cpu_caps {
unsigned has_3dnow:1;
unsigned has_3dnow_ext:1;
unsigned has_altivec:1;
+ unsigned has_daz:1;
};
extern struct util_cpu_caps
diff --git a/mesalib/src/gallium/auxiliary/util/u_format_srgb.h b/mesalib/src/gallium/auxiliary/util/u_format_srgb.h
index 82ed9575d..740a91974 100644
--- a/mesalib/src/gallium/auxiliary/util/u_format_srgb.h
+++ b/mesalib/src/gallium/auxiliary/util/u_format_srgb.h
@@ -39,6 +39,7 @@
#include "pipe/p_compiler.h"
+#include "u_pack_color.h"
#include "u_math.h"
@@ -51,23 +52,58 @@ util_format_srgb_to_linear_8unorm_table[256];
extern const uint8_t
util_format_linear_to_srgb_8unorm_table[256];
+extern const unsigned
+util_format_linear_to_srgb_helper_table[104];
+
/**
* Convert a unclamped linear float to srgb value in the [0,255].
- * XXX this hasn't been tested (render to srgb surface).
- * XXX this needs optimization.
*/
static INLINE uint8_t
util_format_linear_float_to_srgb_8unorm(float x)
{
- if (x >= 1.0f)
- return 255;
- else if (x >= 0.0031308f)
- return float_to_ubyte(1.055f * powf(x, 0.41666f) - 0.055f);
- else if (x > 0.0f)
- return float_to_ubyte(12.92f * x);
- else
- return 0;
+ /* this would be exact but (probably much) slower */
+ if (0) {
+ if (x >= 1.0f)
+ return 255;
+ else if (x >= 0.0031308f)
+ return float_to_ubyte(1.055f * powf(x, 0.41666666f) - 0.055f);
+ else if (x > 0.0f)
+ return float_to_ubyte(12.92f * x);
+ else
+ return 0;
+ }
+ else {
+ /*
+ * This is taken from https://gist.github.com/rygorous/2203834
+ * Use LUT and do linear interpolation.
+ */
+ union fi almostone, minval, f;
+ unsigned tab, bias, scale, t;
+
+ almostone.ui = 0x3f7fffff;
+ minval.ui = (127-13) << 23;
+
+ /*
+ * Clamp to [2^(-13), 1-eps]; these two values map to 0 and 1, respectively.
+ * The tests are carefully written so that NaNs map to 0, same as in the
+ * reference implementation.
+ */
+ if (!(x > minval.f))
+ x = minval.f;
+ if (x > almostone.f)
+ x = almostone.f;
+
+ /* Do the table lookup and unpack bias, scale */
+ f.f = x;
+ tab = util_format_linear_to_srgb_helper_table[(f.ui - minval.ui) >> 20];
+ bias = (tab >> 16) << 9;
+ scale = tab & 0xffff;
+
+ /* Grab next-highest mantissa bits and perform linear interpolation */
+ t = (f.ui >> 12) & 0xff;
+ return (uint8_t) ((bias + scale*t) >> 16);
+ }
}
diff --git a/mesalib/src/gallium/auxiliary/util/u_format_srgb.py b/mesalib/src/gallium/auxiliary/util/u_format_srgb.py
index cd63ae789..c6c02f053 100644
--- a/mesalib/src/gallium/auxiliary/util/u_format_srgb.py
+++ b/mesalib/src/gallium/auxiliary/util/u_format_srgb.py
@@ -40,6 +40,7 @@ CopyRight = '''
import math
+import struct
def srgb_to_linear(x):
@@ -51,10 +52,11 @@ def srgb_to_linear(x):
def linear_to_srgb(x):
if x >= 0.0031308:
- return 1.055 * math.pow(x, 0.41666) - 0.055
+ return 1.055 * math.pow(x, 0.41666666) - 0.055
else:
return 12.92 * x
+
def generate_srgb_tables():
print 'const float'
print 'util_format_srgb_8unorm_to_linear_float_table[256] = {'
@@ -84,6 +86,59 @@ def generate_srgb_tables():
print '};'
print
+# calculate the table interpolation values used in float linear to unorm8 srgb
+ numexp = 13
+ mantissa_msb = 3
+# stepshift is just used to only use every x-th float to make things faster,
+# 5 is largest value which still gives exact same table as 0
+ stepshift = 5
+ nbuckets = numexp << mantissa_msb
+ bucketsize = (1 << (23 - mantissa_msb)) >> stepshift
+ mantshift = 12
+ valtable = []
+ sum_aa = float(bucketsize)
+ sum_ab = 0.0
+ sum_bb = 0.0
+ for i in range(0, bucketsize):
+ j = (i << stepshift) >> mantshift
+ sum_ab += j
+ sum_bb += j*j
+ inv_det = 1.0 / (sum_aa * sum_bb - sum_ab * sum_ab)
+
+ for bucket in range(0, nbuckets):
+ start = ((127 - numexp) << 23) + bucket*(bucketsize << stepshift)
+ sum_a = 0.0
+ sum_b = 0.0
+
+ for i in range(0, bucketsize):
+ j = (i << stepshift) >> mantshift
+ fint = start + (i << stepshift)
+ ffloat = struct.unpack('f', struct.pack('I', fint))[0]
+ val = linear_to_srgb(ffloat) * 255.0 + 0.5
+ sum_a += val
+ sum_b += j*val
+
+ solved_a = inv_det * (sum_bb*sum_a - sum_ab*sum_b)
+ solved_b = inv_det * (sum_aa*sum_b - sum_ab*sum_a)
+
+ scaled_a = solved_a * 65536.0 / 512.0
+ scaled_b = solved_b * 65536.0
+
+ int_a = int(scaled_a + 0.5)
+ int_b = int(scaled_b + 0.5)
+
+ valtable.append((int_a << 16) + int_b)
+
+ print 'const unsigned'
+ print 'util_format_linear_to_srgb_helper_table[104] = {'
+
+ for j in range(0, nbuckets, 4):
+ print ' ',
+ for i in range(j, j + 4):
+ print '0x%08x,' % (valtable[i],),
+ print
+ print '};'
+ print
def main():
print '/* This file is autogenerated by u_format_srgb.py. Do not edit directly. */'
diff --git a/mesalib/src/gallium/auxiliary/util/u_math.c b/mesalib/src/gallium/auxiliary/util/u_math.c
index f3fe392ba..6981ee939 100644
--- a/mesalib/src/gallium/auxiliary/util/u_math.c
+++ b/mesalib/src/gallium/auxiliary/util/u_math.c
@@ -111,7 +111,7 @@ util_fpstate_set_denorms_to_zero(unsigned current_mxcsr)
if (util_cpu_caps.has_sse) {
/* Enable flush to zero mode */
current_mxcsr |= _MM_FLUSH_ZERO_MASK;
- if (util_cpu_caps.has_sse3) {
+ if (util_cpu_caps.has_daz) {
/* Enable denormals are zero mode */
current_mxcsr |= _MM_DENORMALS_ZERO_MASK;
}
diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h
index d98f1a39b..9b194dbd0 100644
--- a/mesalib/src/glsl/ast.h
+++ b/mesalib/src/glsl/ast.h
@@ -435,6 +435,12 @@ struct ast_type_qualifier {
unsigned column_major:1;
unsigned row_major:1;
/** \} */
+
+ /** \name Layout qualifiers for GLSL 1.50 geometry shaders */
+ /** \{ */
+ unsigned prim_type:1;
+ unsigned max_vertices:1;
+ /** \} */
}
/** \brief Set of flags, accessed by name. */
q;
@@ -461,6 +467,12 @@ struct ast_type_qualifier {
*/
int index;
+ /** Maximum output vertices in GLSL 1.50 geometry shaders. */
+ int max_vertices;
+
+ /** Input or output primitive type in GLSL 1.50 geometry shaders */
+ GLenum prim_type;
+
/**
* Binding specified via GL_ARB_shading_language_420pack's "binding" keyword.
*
@@ -895,12 +907,14 @@ public:
class ast_interface_block : public ast_node {
public:
ast_interface_block(ast_type_qualifier layout,
- const char *instance_name,
- ast_expression *array_size)
+ const char *instance_name,
+ bool is_array,
+ ast_expression *array_size)
: layout(layout), block_name(NULL), instance_name(instance_name),
- array_size(array_size)
+ is_array(is_array), array_size(array_size)
{
- /* empty */
+ if (!is_array)
+ assert(array_size == NULL);
}
virtual ir_rvalue *hir(exec_list *instructions,
@@ -921,16 +935,44 @@ public:
exec_list declarations;
/**
- * Declared array size of the block instance
- *
- * If the block is not declared as an array, this field will be \c NULL.
+ * True if the block is declared as an array
*
* \note
* A block can only be an array if it also has an instance name. If this
- * field is not \c NULL, ::instance_name must also not be \c NULL.
+ * field is true, ::instance_name must also not be \c NULL.
+ */
+ bool is_array;
+
+ /**
+ * Declared array size of the block instance
+ *
+ * If the block is not declared as an array or if the block instance array
+ * is unsized, this field will be \c NULL.
*/
ast_expression *array_size;
};
+
+
+/**
+ * AST node representing a declaration of the input layout for geometry
+ * shaders.
+ */
+class ast_gs_input_layout : public ast_node
+{
+public:
+ ast_gs_input_layout(const struct YYLTYPE &locp, GLenum prim_type)
+ : prim_type(prim_type)
+ {
+ set_location(locp);
+ }
+
+ virtual ir_rvalue *hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state);
+
+private:
+ const GLenum prim_type;
+};
+
/*@}*/
extern void
diff --git a/mesalib/src/glsl/ast_array_index.cpp b/mesalib/src/glsl/ast_array_index.cpp
index 4baeb6f9d..51f6b10f3 100644
--- a/mesalib/src/glsl/ast_array_index.cpp
+++ b/mesalib/src/glsl/ast_array_index.cpp
@@ -117,7 +117,8 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
} else if (const_index == NULL && array->type->is_array()) {
if (array->type->array_size() == 0) {
_mesa_glsl_error(&loc, state, "unsized array index must be constant");
- } else if (array->type->fields.array->is_interface()) {
+ } else if (array->type->fields.array->is_interface()
+ && array->variable_referenced()->mode == ir_var_uniform) {
/* Page 46 in section 4.3.7 of the OpenGL ES 3.00 spec says:
*
* "All indexes used to index a uniform block array must be
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index 598da92f8..04b16c8aa 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -72,6 +72,8 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
state->toplevel_ir = instructions;
+ state->gs_input_prim_type_specified = false;
+
/* Section 4.2 of the GLSL 1.20 specification states:
* "The built-in functions are scoped in a scope outside the global scope
* users declare global variables in. That is, a shader's global scope,
@@ -1771,12 +1773,6 @@ process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
}
}
}
- } else if (state->es_shader) {
- /* Section 10.17 of the GLSL ES 1.00 specification states that unsized
- * array declarations have been removed from the language.
- */
- _mesa_glsl_error(loc, state, "unsized array declarations are not "
- "allowed in GLSL ES 1.00");
}
const glsl_type *array_type = glsl_type::get_array_instance(base, length);
@@ -1936,6 +1932,8 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
bool ubo_qualifiers_valid,
bool is_parameter)
{
+ STATIC_ASSERT(sizeof(qual->flags.q) <= sizeof(qual->flags.i));
+
if (qual->flags.q.invariant) {
if (var->used) {
_mesa_glsl_error(loc, state,
@@ -1963,6 +1961,21 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
_mesa_glsl_shader_target_name(state->target));
}
+ /* Section 6.1.1 (Function Calling Conventions) of the GLSL 1.10 spec says:
+ *
+ * "However, the const qualifier cannot be used with out or inout."
+ *
+ * The same section of the GLSL 4.40 spec further clarifies this saying:
+ *
+ * "The const qualifier cannot be used with out or inout, or a
+ * compile-time error results."
+ */
+ if (is_parameter && qual->flags.q.constant && qual->flags.q.out) {
+ _mesa_glsl_error(loc, state,
+ "`const' may not be applied to `out' or `inout' "
+ "function parameters");
+ }
+
/* If there is no qualifier that changes the mode of the variable, leave
* the setting alone.
*/
@@ -2055,13 +2068,24 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
else
var->interpolation = INTERP_QUALIFIER_NONE;
- if (var->interpolation != INTERP_QUALIFIER_NONE &&
- !(state->target == vertex_shader && var->mode == ir_var_shader_out) &&
- !(state->target == fragment_shader && var->mode == ir_var_shader_in)) {
- _mesa_glsl_error(loc, state,
- "interpolation qualifier `%s' can only be applied to "
- "vertex shader outputs and fragment shader inputs",
- var->interpolation_string());
+ if (var->interpolation != INTERP_QUALIFIER_NONE) {
+ ir_variable_mode mode = (ir_variable_mode) var->mode;
+
+ if (mode != ir_var_shader_in && mode != ir_var_shader_out) {
+ _mesa_glsl_error(loc, state,
+ "interpolation qualifier `%s' can only be applied to "
+ "shader inputs or outputs.",
+ var->interpolation_string());
+
+ }
+
+ if ((state->target == vertex_shader && mode == ir_var_shader_in) ||
+ (state->target == fragment_shader && mode == ir_var_shader_out)) {
+ _mesa_glsl_error(loc, state,
+ "interpolation qualifier `%s' cannot be applied to "
+ "vertex shader inputs or fragment shader outputs",
+ var->interpolation_string());
+ }
}
var->pixel_center_integer = qual->flags.q.pixel_center_integer;
@@ -2317,7 +2341,8 @@ get_variable_being_redeclared(ir_variable *var, ast_declaration *decl,
earlier->type = var->type;
delete var;
var = NULL;
- } else if (state->ARB_fragment_coord_conventions_enable
+ } else if ((state->ARB_fragment_coord_conventions_enable ||
+ state->is_version(150, 0))
&& strcmp(var->name, "gl_FragCoord") == 0
&& earlier->type == var->type
&& earlier->mode == var->mode) {
@@ -2519,6 +2544,81 @@ process_initializer(ir_variable *var, ast_declaration *decl,
return result;
}
+
+/**
+ * Do additional processing necessary for geometry shader input declarations
+ * (this covers both interface blocks arrays and bare input variables).
+ */
+static void
+handle_geometry_shader_input_decl(struct _mesa_glsl_parse_state *state,
+ YYLTYPE loc, ir_variable *var)
+{
+ unsigned num_vertices = 0;
+ if (state->gs_input_prim_type_specified) {
+ num_vertices = vertices_per_prim(state->gs_input_prim_type);
+ }
+
+ /* Geometry shader input variables must be arrays. Caller should have
+ * reported an error for this.
+ */
+ if (!var->type->is_array()) {
+ assert(state->error);
+
+ /* To avoid cascading failures, short circuit the checks below. */
+ return;
+ }
+
+ if (var->type->length == 0) {
+ /* Section 4.3.8.1 (Input Layout Qualifiers) of the GLSL 1.50 spec says:
+ *
+ * All geometry shader input unsized array declarations will be
+ * sized by an earlier input layout qualifier, when present, as per
+ * the following table.
+ *
+ * Followed by a table mapping each allowed input layout qualifier to
+ * the corresponding input length.
+ */
+ if (num_vertices != 0)
+ var->type = glsl_type::get_array_instance(var->type->fields.array,
+ num_vertices);
+ } else {
+ /* Section 4.3.8.1 (Input Layout Qualifiers) of the GLSL 1.50 spec
+ * includes the following examples of compile-time errors:
+ *
+ * // code sequence within one shader...
+ * in vec4 Color1[]; // size unknown
+ * ...Color1.length()...// illegal, length() unknown
+ * in vec4 Color2[2]; // size is 2
+ * ...Color1.length()...// illegal, Color1 still has no size
+ * in vec4 Color3[3]; // illegal, input sizes are inconsistent
+ * layout(lines) in; // legal, input size is 2, matching
+ * in vec4 Color4[3]; // illegal, contradicts layout
+ * ...
+ *
+ * To detect the case illustrated by Color3, we verify that the size of
+ * an explicitly-sized array matches the size of any previously declared
+ * explicitly-sized array. To detect the case illustrated by Color4, we
+ * verify that the size of an explicitly-sized array is consistent with
+ * any previously declared input layout.
+ */
+ if (num_vertices != 0 && var->type->length != num_vertices) {
+ _mesa_glsl_error(&loc, state,
+ "geometry shader input size contradicts previously"
+ " declared layout (size is %u, but layout requires a"
+ " size of %u)", var->type->length, num_vertices);
+ } else if (state->gs_input_size != 0 &&
+ var->type->length != state->gs_input_size) {
+ _mesa_glsl_error(&loc, state,
+ "geometry shader input sizes are "
+ "inconsistent (size is %u, but a previous "
+ "declaration has size %u)",
+ var->type->length, state->gs_input_size);
+ } else {
+ state->gs_input_size = var->type->length;
+ }
+ }
+}
+
ir_rvalue *
ast_declarator_list::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
@@ -2605,6 +2705,11 @@ ast_declarator_list::hir(exec_list *instructions,
* name of a known structure type. This is both invalid and weird.
* Emit an error.
*
+ * - The program text contained something like 'mediump float;'
+ * when the programmer probably meant 'precision mediump
+ * float;' Emit a warning with a description of what they
+ * probably meant to do.
+ *
* Note that if decl_type is NULL and there is a structure involved,
* there must have been some sort of error with the structure. In this
* case we assume that an error was already generated on this line of
@@ -2613,20 +2718,33 @@ ast_declarator_list::hir(exec_list *instructions,
*/
assert(this->type->specifier->structure == NULL || decl_type != NULL
|| state->error);
- if (this->type->specifier->structure == NULL) {
- if (decl_type != NULL) {
- _mesa_glsl_warning(&loc, state, "empty declaration");
- } else {
- _mesa_glsl_error(&loc, state,
- "invalid type `%s' in empty declaration",
- type_name);
- }
- }
- if (this->type->qualifier.precision != ast_precision_none &&
- this->type->specifier->structure != NULL) {
- _mesa_glsl_error(&loc, state, "precision qualifiers can't be applied "
- "to structures");
+ if (decl_type == NULL) {
+ _mesa_glsl_error(&loc, state,
+ "invalid type `%s' in empty declaration",
+ type_name);
+ } else if (this->type->qualifier.precision != ast_precision_none) {
+ if (this->type->specifier->structure != NULL) {
+ _mesa_glsl_error(&loc, state,
+ "precision qualifiers can't be applied "
+ "to structures");
+ } else {
+ static const char *const precision_names[] = {
+ "highp",
+ "highp",
+ "mediump",
+ "lowp"
+ };
+
+ _mesa_glsl_warning(&loc, state,
+ "empty declaration with precision qualifier, "
+ "to set the default precision, use "
+ "`precision %s %s;'",
+ precision_names[this->type->qualifier.precision],
+ type_name);
+ }
+ } else {
+ _mesa_glsl_warning(&loc, state, "empty declaration");
}
}
@@ -2662,6 +2780,26 @@ ast_declarator_list::hir(exec_list *instructions,
var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto);
+ /* The 'varying in' and 'varying out' qualifiers can only be used with
+ * ARB_geometry_shader4 and EXT_geometry_shader4, which we don't support
+ * yet.
+ */
+ if (this->type->qualifier.flags.q.varying) {
+ if (this->type->qualifier.flags.q.in) {
+ _mesa_glsl_error(& loc, state,
+ "`varying in' qualifier in declaration of "
+ "`%s' only valid for geometry shaders using "
+ "ARB_geometry_shader4 or EXT_geometry_shader4",
+ decl->identifier);
+ } else if (this->type->qualifier.flags.q.out) {
+ _mesa_glsl_error(& loc, state,
+ "`varying out' qualifier in declaration of "
+ "`%s' only valid for geometry shaders using "
+ "ARB_geometry_shader4 or EXT_geometry_shader4",
+ decl->identifier);
+ }
+ }
+
/* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
*
* "Global variables can only use the qualifiers const,
@@ -2796,7 +2934,22 @@ ast_declarator_list::hir(exec_list *instructions,
"cannot have array type")) {
error_emitted = true;
}
- }
+ } else if (state->target == geometry_shader) {
+ /* From section 4.3.4 (Inputs) of the GLSL 1.50 spec:
+ *
+ * Geometry shader input variables get the per-vertex values
+ * written out by vertex shader output variables of the same
+ * names. Since a geometry shader operates on a set of
+ * vertices, each input varying variable (or input block, see
+ * interface blocks below) needs to be declared as an array.
+ */
+ if (!var->type->is_array()) {
+ _mesa_glsl_error(&loc, state,
+ "geometry shader inputs must be arrays");
+ }
+
+ handle_geometry_shader_input_decl(state, loc, var);
+ }
}
/* Integer fragment inputs must be qualified with 'flat'. In GLSL ES,
@@ -2906,7 +3059,7 @@ ast_declarator_list::hir(exec_list *instructions,
}
break;
default:
- assert(0);
+ break;
}
}
@@ -3015,6 +3168,33 @@ ast_declarator_list::hir(exec_list *instructions,
decl->identifier);
}
+ if (state->es_shader) {
+ const glsl_type *const t = (earlier == NULL)
+ ? var->type : earlier->type;
+
+ if (t->is_array() && t->length == 0)
+ /* Section 10.17 of the GLSL ES 1.00 specification states that
+ * unsized array declarations have been removed from the language.
+ * Arrays that are sized using an initializer are still explicitly
+ * sized. However, GLSL ES 1.00 does not allow array
+ * initializers. That is only allowed in GLSL ES 3.00.
+ *
+ * Section 4.1.9 (Arrays) of the GLSL ES 3.00 spec says:
+ *
+ * "An array type can also be formed without specifying a size
+ * if the definition includes an initializer:
+ *
+ * float x[] = float[2] (1.0, 2.0); // declares an array of size 2
+ * float y[] = float[] (1.0, 2.0, 3.0); // declares an array of size 3
+ *
+ * float a[5];
+ * float b[] = a;"
+ */
+ _mesa_glsl_error(& loc, state,
+ "unsized array declarations are not allowed in "
+ "GLSL ES");
+ }
+
/* If the declaration is not a redeclaration, there are a few additional
* semantic checks that must be applied. In addition, variable that was
* created for the declaration should be added to the IR stream.
@@ -3323,6 +3503,18 @@ ast_function::hir(exec_list *instructions,
"function `%s' return type has qualifiers", name);
}
+ /* Section 6.1 (Function Definitions) of the GLSL 1.20 spec says:
+ *
+ * "Arrays are allowed as arguments and as the return type. In both
+ * cases, the array must be explicitly sized."
+ */
+ if (return_type->is_array() && return_type->length == 0) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(& loc, state,
+ "function `%s' return type array must be explicitly "
+ "sized", name);
+ }
+
/* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
*
* "[Sampler types] can only be declared as function parameters
@@ -4362,6 +4554,19 @@ ast_interface_block::hir(exec_list *instructions,
*/
assert(declared_variables.is_empty());
+ /* From section 4.3.4 (Inputs) of the GLSL 1.50 spec:
+ *
+ * Geometry shader input variables get the per-vertex values written
+ * out by vertex shader output variables of the same names. Since a
+ * geometry shader operates on a set of vertices, each input varying
+ * variable (or input block, see interface blocks below) needs to be
+ * declared as an array.
+ */
+ if (state->target == geometry_shader && !this->is_array &&
+ var_mode == ir_var_shader_in) {
+ _mesa_glsl_error(&loc, state, "geometry shader inputs must be arrays");
+ }
+
/* Page 39 (page 45 of the PDF) of section 4.3.7 in the GLSL ES 3.00 spec
* says:
*
@@ -4372,7 +4577,34 @@ ast_interface_block::hir(exec_list *instructions,
if (this->instance_name) {
ir_variable *var;
- if (this->array_size != NULL) {
+ if (this->is_array) {
+ /* Section 4.3.7 (Interface Blocks) of the GLSL 1.50 spec says:
+ *
+ * For uniform blocks declared an array, each individual array
+ * element corresponds to a separate buffer object backing one
+ * instance of the block. As the array size indicates the number
+ * of buffer objects needed, uniform block array declarations
+ * must specify an array size.
+ *
+ * And a few paragraphs later:
+ *
+ * Geometry shader input blocks must be declared as arrays and
+ * follow the array declaration and linking rules for all
+ * geometry shader inputs. All other input and output block
+ * arrays must specify an array size.
+ *
+ * The upshot of this is that the only circumstance where an
+ * interface array size *doesn't* need to be specified is on a
+ * geometry shader input.
+ */
+ if (this->array_size == NULL &&
+ (state->target != geometry_shader || !this->layout.flags.q.in)) {
+ _mesa_glsl_error(&loc, state,
+ "only geometry shader inputs may be unsized "
+ "instance block arrays");
+
+ }
+
const glsl_type *block_array_type =
process_array_type(&loc, block_type, this->array_size, state);
@@ -4386,13 +4618,15 @@ ast_interface_block::hir(exec_list *instructions,
}
var->interface_type = block_type;
+ if (state->target == geometry_shader && var_mode == ir_var_shader_in)
+ handle_geometry_shader_input_decl(state, loc, var);
state->symbols->add_variable(var);
instructions->push_tail(var);
} else {
/* In order to have an array size, the block must also be declared with
* an instane name.
*/
- assert(this->array_size == NULL);
+ assert(!this->is_array);
for (unsigned i = 0; i < num_variables; i++) {
ir_variable *var =
@@ -4416,6 +4650,72 @@ ast_interface_block::hir(exec_list *instructions,
return NULL;
}
+
+ir_rvalue *
+ast_gs_input_layout::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ YYLTYPE loc = this->get_location();
+
+ /* If any geometry input layout declaration preceded this one, make sure it
+ * was consistent with this one.
+ */
+ if (state->gs_input_prim_type_specified &&
+ state->gs_input_prim_type != this->prim_type) {
+ _mesa_glsl_error(&loc, state,
+ "geometry shader input layout does not match"
+ " previous declaration");
+ return NULL;
+ }
+
+ /* If any shader inputs occurred before this declaration and specified an
+ * array size, make sure the size they specified is consistent with the
+ * primitive type.
+ */
+ unsigned num_vertices = vertices_per_prim(this->prim_type);
+ if (state->gs_input_size != 0 && state->gs_input_size != num_vertices) {
+ _mesa_glsl_error(&loc, state,
+ "this geometry shader input layout implies %u vertices"
+ " per primitive, but a previous input is declared"
+ " with size %u", num_vertices, state->gs_input_size);
+ return NULL;
+ }
+
+ state->gs_input_prim_type_specified = true;
+ state->gs_input_prim_type = this->prim_type;
+
+ /* If any shader inputs occurred before this declaration and did not
+ * specify an array size, their size is determined now.
+ */
+ foreach_list (node, instructions) {
+ ir_variable *var = ((ir_instruction *) node)->as_variable();
+ if (var == NULL || var->mode != ir_var_shader_in)
+ continue;
+
+ /* Note: gl_PrimitiveIDIn has mode ir_var_shader_in, but it's not an
+ * array; skip it.
+ */
+ if (!var->type->is_array())
+ continue;
+
+ if (var->type->length == 0) {
+ if (var->max_array_access >= num_vertices) {
+ _mesa_glsl_error(&loc, state,
+ "this geometry shader input layout implies %u"
+ " vertices, but an access to element %u of input"
+ " `%s' already exists", num_vertices,
+ var->max_array_access, var->name);
+ } else {
+ var->type = glsl_type::get_array_instance(var->type->fields.array,
+ num_vertices);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
static void
detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
exec_list *instructions)
diff --git a/mesalib/src/glsl/ast_type.cpp b/mesalib/src/glsl/ast_type.cpp
index 38c3f8eb0..ce6b6a771 100644
--- a/mesalib/src/glsl/ast_type.cpp
+++ b/mesalib/src/glsl/ast_type.cpp
@@ -133,6 +133,25 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
return false;
}
+ if (q.flags.q.prim_type) {
+ if (this->flags.q.prim_type && this->prim_type != q.prim_type) {
+ _mesa_glsl_error(loc, state,
+ "conflicting primitive type qualifiers used");
+ return false;
+ }
+ this->prim_type = q.prim_type;
+ }
+
+ if (q.flags.q.max_vertices) {
+ if (this->flags.q.max_vertices && this->max_vertices != q.max_vertices) {
+ _mesa_glsl_error(loc, state,
+ "geometry shader set conflicting max_vertices "
+ "(%d and %d)", this->max_vertices, q.max_vertices);
+ return false;
+ }
+ this->max_vertices = q.max_vertices;
+ }
+
if ((q.flags.i & ubo_mat_mask.flags.i) != 0)
this->flags.i &= ~ubo_mat_mask.flags.i;
if ((q.flags.i & ubo_layout_mask.flags.i) != 0)
diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp
index 1e88b6a73..6a808c072 100644
--- a/mesalib/src/glsl/builtin_variables.cpp
+++ b/mesalib/src/glsl/builtin_variables.cpp
@@ -686,8 +686,11 @@ builtin_variable_generator::generate_gs_special_vars()
* the specific case of gl_PrimitiveIDIn. So we don't need to treat
* gl_PrimitiveIDIn as an {ARB,EXT}_geometry_shader4-only variable.
*/
- add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveIDIn");
- add_output(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID");
+ ir_variable *var;
+ var = add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveIDIn");
+ var->interpolation = INTERP_QUALIFIER_FLAT;
+ var = add_output(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID");
+ var->interpolation = INTERP_QUALIFIER_FLAT;
}
@@ -702,6 +705,12 @@ builtin_variable_generator::generate_fs_special_vars()
if (state->is_version(120, 100))
add_input(VARYING_SLOT_PNTC, vec2_t, "gl_PointCoord");
+ if (state->is_version(150, 0)) {
+ ir_variable *var =
+ add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID");
+ var->interpolation = INTERP_QUALIFIER_FLAT;
+ }
+
/* gl_FragColor and gl_FragData were deprecated starting in desktop GLSL
* 1.30, and were relegated to the compatibility profile in GLSL 4.20.
* They were removed from GLSL ES 3.00.
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index fcc5620cd..e3a57ea02 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -254,6 +254,7 @@ _mesa_glsl_lex(YYSTYPE *val, YYLTYPE *loc, _mesa_glsl_parse_state *state)
%type <node> for_init_statement
%type <for_rest_statement> for_rest_statement
%type <n> integer_constant
+%type <node> layout_defaults
%right THEN ELSE
%%
@@ -1157,7 +1158,8 @@ layout_qualifier_id:
memset(& $$, 0, sizeof($$));
/* Layout qualifiers for ARB_fragment_coord_conventions. */
- if (!$$.flags.i && state->ARB_fragment_coord_conventions_enable) {
+ if (!$$.flags.i && (state->ARB_fragment_coord_conventions_enable ||
+ state->is_version(150, 0))) {
if (strcmp($1, "origin_upper_left") == 0) {
$$.flags.q.origin_upper_left = 1;
} else if (strcmp($1, "pixel_center_integer") == 0) {
@@ -1222,6 +1224,34 @@ layout_qualifier_id:
}
}
+ /* Layout qualifiers for GLSL 1.50 geometry shaders. */
+ if (!$$.flags.i) {
+ struct {
+ const char *s;
+ GLenum e;
+ } map[] = {
+ { "points", GL_POINTS },
+ { "lines", GL_LINES },
+ { "lines_adjacency", GL_LINES_ADJACENCY },
+ { "line_strip", GL_LINE_STRIP },
+ { "triangles", GL_TRIANGLES },
+ { "triangles_adjacency", GL_TRIANGLES_ADJACENCY },
+ { "triangle_strip", GL_TRIANGLE_STRIP },
+ };
+ for (unsigned i = 0; i < Elements(map); i++) {
+ if (strcmp($1, map[i].s) == 0) {
+ $$.flags.q.prim_type = 1;
+ $$.prim_type = map[i].e;
+ break;
+ }
+ }
+
+ if ($$.flags.i && !state->is_version(150, 0)) {
+ _mesa_glsl_error(& @1, state, "#version 150 layout "
+ "qualifier `%s' used", $1);
+ }
+ }
+
if (!$$.flags.i) {
_mesa_glsl_error(& @1, state, "unrecognized layout identifier "
"`%s'", $1);
@@ -1264,6 +1294,23 @@ layout_qualifier_id:
$$.binding = $3;
}
+ if (strcmp("max_vertices", $1) == 0) {
+ $$.flags.q.max_vertices = 1;
+
+ if ($3 < 0) {
+ _mesa_glsl_error(& @3, state,
+ "invalid max_vertices %d specified", $3);
+ YYERROR;
+ } else {
+ $$.max_vertices = $3;
+ if (!state->is_version(150, 0)) {
+ _mesa_glsl_error(& @3, state,
+ "#version 150 max_vertices qualifier "
+ "specified", $3);
+ }
+ }
+ }
+
/* If the identifier didn't match any known layout identifiers,
* emit an error.
*/
@@ -2046,7 +2093,7 @@ external_declaration:
function_definition { $$ = $1; }
| declaration { $$ = $1; }
| pragma_statement { $$ = NULL; }
- | layout_defaults { $$ = NULL; }
+ | layout_defaults { $$ = $1; }
;
function_definition:
@@ -2197,25 +2244,22 @@ instance_name_opt:
/* empty */
{
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
- NULL, NULL);
+ NULL, false, NULL);
}
| NEW_IDENTIFIER
{
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
- $1, NULL);
+ $1, false, NULL);
}
| NEW_IDENTIFIER '[' constant_expression ']'
{
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
- $1, $3);
+ $1, true, $3);
}
| NEW_IDENTIFIER '[' ']'
{
- _mesa_glsl_error(& @1, state,
- "instance block arrays must be explicitly sized");
-
$$ = new(state) ast_interface_block(*state->default_uniform_qualifier,
- $1, NULL);
+ $1, true, NULL);
}
;
@@ -2263,4 +2307,32 @@ layout_defaults:
if (!state->default_uniform_qualifier->merge_qualifier(& @1, state, $1)) {
YYERROR;
}
+ $$ = NULL;
+ }
+
+ | layout_qualifier IN_TOK ';'
+ {
+ void *ctx = state;
+ if (state->target != geometry_shader) {
+ _mesa_glsl_error(& @1, state,
+ "input layout qualifiers only valid in "
+ "geometry shaders");
+ } else if (!$1.flags.q.prim_type) {
+ _mesa_glsl_error(& @1, state,
+ "input layout qualifiers must specify a primitive"
+ " type");
+ }
+ $$ = new(ctx) ast_gs_input_layout(@1, $1.prim_type);
+ }
+
+ | layout_qualifier OUT_TOK ';'
+ {
+ if (state->target != geometry_shader) {
+ _mesa_glsl_error(& @1, state,
+ "out layout qualifiers only valid in "
+ "geometry shaders");
+ } else if (!state->out_qualifier->merge_qualifier(& @1, state, $1)) {
+ YYERROR;
+ }
+ $$ = NULL;
}
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index a5bc20c23..88f048365 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -159,6 +159,10 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
this->default_uniform_qualifier = new(this) ast_type_qualifier();
this->default_uniform_qualifier->flags.q.shared = 1;
this->default_uniform_qualifier->flags.q.column_major = 1;
+
+ this->gs_input_prim_type_specified = false;
+ this->gs_input_prim_type = GL_POINTS;
+ this->out_qualifier = new(this) ast_type_qualifier();
}
/**
@@ -1410,6 +1414,34 @@ ast_struct_specifier::ast_struct_specifier(const char *identifier,
is_declaration = true;
}
+static void
+set_shader_inout_layout(struct gl_shader *shader,
+ struct _mesa_glsl_parse_state *state)
+{
+ if (shader->Type != GL_GEOMETRY_SHADER) {
+ /* Should have been prevented by the parser. */
+ assert(!state->gs_input_prim_type_specified);
+ assert(!state->out_qualifier->flags.i);
+ return;
+ }
+
+ shader->Geom.VerticesOut = 0;
+ if (state->out_qualifier->flags.q.max_vertices)
+ shader->Geom.VerticesOut = state->out_qualifier->max_vertices;
+
+ if (state->gs_input_prim_type_specified) {
+ shader->Geom.InputType = state->gs_input_prim_type;
+ } else {
+ shader->Geom.InputType = PRIM_UNKNOWN;
+ }
+
+ if (state->out_qualifier->flags.q.prim_type) {
+ shader->Geom.OutputType = state->out_qualifier->prim_type;
+ } else {
+ shader->Geom.OutputType = PRIM_UNKNOWN;
+ }
+}
+
extern "C" {
void
@@ -1485,6 +1517,9 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
shader->UniformBlocks = state->uniform_blocks;
ralloc_steal(shader, shader->UniformBlocks);
+ if (!state->error)
+ set_shader_inout_layout(shader, state);
+
/* Retain any live IR, but trash the rest. */
reparent_ir(shader->ir, shader->ir);
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index 1e386dd31..b9ca4e3a4 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -166,6 +166,24 @@ struct _mesa_glsl_parse_state {
struct ast_type_qualifier *default_uniform_qualifier;
/**
+ * True if a geometry shader input primitive type was specified using a
+ * layout directive.
+ *
+ * Note: this value is computed at ast_to_hir time rather than at parse
+ * time.
+ */
+ bool gs_input_prim_type_specified;
+
+ /**
+ * If gs_input_prim_type_specified is true, the primitive type that was
+ * specified. Otherwise ignored.
+ */
+ GLenum gs_input_prim_type;
+
+ /** Output layout qualifiers from GLSL 1.50. (geometry shader controls)*/
+ struct ast_type_qualifier *out_qualifier;
+
+ /**
* Printable list of GLSL versions supported by the current context
*
* \note
@@ -298,6 +316,15 @@ struct _mesa_glsl_parse_state {
/** Shaders containing built-in functions that are used for linking. */
struct gl_shader *builtins_to_link[16];
unsigned num_builtins_to_link;
+
+ /**
+ * For geometry shaders, size of the most recently seen input declaration
+ * that was a sized array, or 0 if no sized input array declarations have
+ * been seen.
+ *
+ * Unused for other shader types.
+ */
+ unsigned gs_input_size;
};
# define YYLLOC_DEFAULT(Current, Rhs, N) \
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index 8324b8ade..0c7e8eb11 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -828,3 +828,58 @@ glsl_type::std140_size(bool row_major) const
assert(!"not reached");
return -1;
}
+
+
+unsigned
+glsl_type::count_attribute_slots() const
+{
+ /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
+ *
+ * "A scalar input counts the same amount against this limit as a vec4,
+ * so applications may want to consider packing groups of four
+ * unrelated float inputs together into a vector to better utilize the
+ * capabilities of the underlying hardware. A matrix input will use up
+ * multiple locations. The number of locations used will equal the
+ * number of columns in the matrix."
+ *
+ * The spec does not explicitly say how arrays are counted. However, it
+ * should be safe to assume the total number of slots consumed by an array
+ * is the number of entries in the array multiplied by the number of slots
+ * consumed by a single element of the array.
+ *
+ * The spec says nothing about how structs are counted, because vertex
+ * attributes are not allowed to be (or contain) structs. However, Mesa
+ * allows varying structs, the number of varying slots taken up by a
+ * varying struct is simply equal to the sum of the number of slots taken
+ * up by each element.
+ */
+ switch (this->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_BOOL:
+ return this->matrix_columns;
+
+ case GLSL_TYPE_STRUCT:
+ case GLSL_TYPE_INTERFACE: {
+ unsigned size = 0;
+
+ for (unsigned i = 0; i < this->length; i++)
+ size += this->fields.structure[i].type->count_attribute_slots();
+
+ return size;
+ }
+
+ case GLSL_TYPE_ARRAY:
+ return this->length * this->fields.array->count_attribute_slots();
+
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_VOID:
+ case GLSL_TYPE_ERROR:
+ break;
+ }
+
+ assert(!"Unexpected type in count_attribute_slots()");
+
+ return 0;
+}
diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h
index 8172309a7..647867a23 100644
--- a/mesalib/src/glsl/glsl_types.h
+++ b/mesalib/src/glsl/glsl_types.h
@@ -253,6 +253,18 @@ struct glsl_type {
unsigned component_slots() const;
/**
+ * Calculate the number of attribute slots required to hold this type
+ *
+ * This implements the language rules of GLSL 1.50 for counting the number
+ * of slots used by a vertex attribute. It also determines the number of
+ * varying slots the type will use up in the absence of varying packing
+ * (and thus, it can be used to measure the number of varying slots used by
+ * the varyings that are generated by lower_packed_varyings).
+ */
+ unsigned count_attribute_slots() const;
+
+
+ /**
* Alignment in bytes of the start of this type in a std140 uniform
* block.
*/
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index dad58deeb..99dceacf8 100644
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -1778,3 +1778,24 @@ ir_rvalue::as_rvalue_to_saturate()
return NULL;
}
+
+
+unsigned
+vertices_per_prim(GLenum prim)
+{
+ switch (prim) {
+ case GL_POINTS:
+ return 1;
+ case GL_LINES:
+ return 2;
+ case GL_TRIANGLES:
+ return 3;
+ case GL_LINES_ADJACENCY:
+ return 4;
+ case GL_TRIANGLES_ADJACENCY:
+ return 6;
+ default:
+ assert(!"Bad primitive");
+ return 3;
+ }
+}
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h
index 7ac291cf4..62e3b27ca 100644
--- a/mesalib/src/glsl/ir.h
+++ b/mesalib/src/glsl/ir.h
@@ -81,6 +81,8 @@ enum ir_node_type {
ir_type_return,
ir_type_swizzle,
ir_type_texture,
+ ir_type_emit_vertex,
+ ir_type_end_primitive,
ir_type_max /**< maximum ir_type enum number, for validation */
};
@@ -519,6 +521,8 @@ public:
*
* - Vertex shader input: one of the values from \c gl_vert_attrib.
* - Vertex shader output: one of the values from \c gl_varying_slot.
+ * - Geometry shader input: one of the values from \c gl_varying_slot.
+ * - Geometry shader output: one of the values from \c gl_varying_slot.
* - Fragment shader input: one of the values from \c gl_varying_slot.
* - Fragment shader output: one of the values from \c gl_frag_result.
* - Uniforms: Per-stage uniform slot number for default uniform block.
@@ -1992,6 +1996,53 @@ private:
/*@}*/
/**
+ * IR instruction to emit a vertex in a geometry shader.
+ */
+class ir_emit_vertex : public ir_instruction {
+public:
+ ir_emit_vertex()
+ {
+ ir_type = ir_type_emit_vertex;
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_emit_vertex *clone(void *mem_ctx, struct hash_table *) const
+ {
+ return new(mem_ctx) ir_emit_vertex();
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+};
+
+/**
+ * IR instruction to complete the current primitive and start a new one in a
+ * geometry shader.
+ */
+class ir_end_primitive : public ir_instruction {
+public:
+ ir_end_primitive()
+ {
+ ir_type = ir_type_end_primitive;
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_end_primitive *clone(void *mem_ctx, struct hash_table *) const
+ {
+ return new(mem_ctx) ir_end_primitive();
+ }
+
+ virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+};
+
+/**
* Apply a visitor to each IR node in a list
*/
void
@@ -2061,7 +2112,7 @@ ir_has_call(ir_instruction *ir);
extern void
do_set_program_inouts(exec_list *instructions, struct gl_program *prog,
- bool is_fragment_shader);
+ GLenum shader_type);
extern char *
prototype_string(const glsl_type *return_type, const char *name,
@@ -2077,4 +2128,7 @@ extern void _mesa_print_ir(struct exec_list *instructions,
} /* extern "C" */
#endif
+unsigned
+vertices_per_prim(GLenum prim);
+
#endif /* IR_H */
diff --git a/mesalib/src/glsl/ir_builder.cpp b/mesalib/src/glsl/ir_builder.cpp
index 8fb30a02a..7d9cf5e47 100644
--- a/mesalib/src/glsl/ir_builder.cpp
+++ b/mesalib/src/glsl/ir_builder.cpp
@@ -219,6 +219,12 @@ saturate(operand a)
new(mem_ctx) ir_constant(0.0f));
}
+ir_expression *
+abs(operand a)
+{
+ return expr(ir_unop_abs, a);
+}
+
ir_expression*
equal(operand a, operand b)
{
@@ -226,6 +232,12 @@ equal(operand a, operand b)
}
ir_expression*
+nequal(operand a, operand b)
+{
+ return expr(ir_binop_nequal, a, b);
+}
+
+ir_expression*
less(operand a, operand b)
{
return expr(ir_binop_less, a, b);
@@ -304,12 +316,24 @@ f2i(operand a)
}
ir_expression*
+bitcast_f2i(operand a)
+{
+ return expr(ir_unop_bitcast_f2i, a);
+}
+
+ir_expression*
i2f(operand a)
{
return expr(ir_unop_i2f, a);
}
ir_expression*
+bitcast_i2f(operand a)
+{
+ return expr(ir_unop_bitcast_i2f, a);
+}
+
+ir_expression*
i2u(operand a)
{
return expr(ir_unop_i2u, a);
@@ -328,11 +352,35 @@ f2u(operand a)
}
ir_expression*
+bitcast_f2u(operand a)
+{
+ return expr(ir_unop_bitcast_f2u, a);
+}
+
+ir_expression*
u2f(operand a)
{
return expr(ir_unop_u2f, a);
}
+ir_expression*
+bitcast_u2f(operand a)
+{
+ return expr(ir_unop_bitcast_u2f, a);
+}
+
+ir_expression*
+i2b(operand a)
+{
+ return expr(ir_unop_i2b, a);
+}
+
+ir_expression*
+b2i(operand a)
+{
+ return expr(ir_unop_b2i, a);
+}
+
ir_if*
if_tree(operand condition,
ir_instruction *then_branch)
diff --git a/mesalib/src/glsl/ir_builder.h b/mesalib/src/glsl/ir_builder.h
index 690ac74eb..7049476a1 100644
--- a/mesalib/src/glsl/ir_builder.h
+++ b/mesalib/src/glsl/ir_builder.h
@@ -133,8 +133,10 @@ ir_expression *round_even(operand a);
ir_expression *dot(operand a, operand b);
ir_expression *clamp(operand a, operand b, operand c);
ir_expression *saturate(operand a);
+ir_expression *abs(operand a);
ir_expression *equal(operand a, operand b);
+ir_expression *nequal(operand a, operand b);
ir_expression *less(operand a, operand b);
ir_expression *greater(operand a, operand b);
ir_expression *lequal(operand a, operand b);
@@ -151,11 +153,17 @@ ir_expression *lshift(operand a, operand b);
ir_expression *rshift(operand a, operand b);
ir_expression *f2i(operand a);
+ir_expression *bitcast_f2i(operand a);
ir_expression *i2f(operand a);
+ir_expression *bitcast_i2f(operand a);
ir_expression *f2u(operand a);
+ir_expression *bitcast_f2u(operand a);
ir_expression *u2f(operand a);
+ir_expression *bitcast_u2f(operand a);
ir_expression *i2u(operand a);
ir_expression *u2i(operand a);
+ir_expression *b2i(operand a);
+ir_expression *i2b(operand a);
/**
* Swizzle away later components, but preserve the ordering.
diff --git a/mesalib/src/glsl/ir_hierarchical_visitor.cpp b/mesalib/src/glsl/ir_hierarchical_visitor.cpp
index f24414046..2e606dda4 100644
--- a/mesalib/src/glsl/ir_hierarchical_visitor.cpp
+++ b/mesalib/src/glsl/ir_hierarchical_visitor.cpp
@@ -69,6 +69,24 @@ ir_hierarchical_visitor::visit(ir_loop_jump *ir)
}
ir_visitor_status
+ir_hierarchical_visitor::visit(ir_emit_vertex *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit(ir_end_primitive *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
{
if (this->callback != NULL)
diff --git a/mesalib/src/glsl/ir_hierarchical_visitor.h b/mesalib/src/glsl/ir_hierarchical_visitor.h
index 1988ad091..647d2e002 100644
--- a/mesalib/src/glsl/ir_hierarchical_visitor.h
+++ b/mesalib/src/glsl/ir_hierarchical_visitor.h
@@ -87,6 +87,8 @@ public:
virtual ir_visitor_status visit(class ir_variable *);
virtual ir_visitor_status visit(class ir_constant *);
virtual ir_visitor_status visit(class ir_loop_jump *);
+ virtual ir_visitor_status visit(class ir_emit_vertex *);
+ virtual ir_visitor_status visit(class ir_end_primitive *);
/**
* ir_dereference_variable isn't technically a leaf, but it is treated as a
diff --git a/mesalib/src/glsl/ir_hv_accept.cpp b/mesalib/src/glsl/ir_hv_accept.cpp
index 559b71af3..76a607d17 100644
--- a/mesalib/src/glsl/ir_hv_accept.cpp
+++ b/mesalib/src/glsl/ir_hv_accept.cpp
@@ -415,3 +415,16 @@ ir_if::accept(ir_hierarchical_visitor *v)
return v->visit_leave(this);
}
+
+ir_visitor_status
+ir_emit_vertex::accept(ir_hierarchical_visitor *v)
+{
+ return v->visit(this);
+}
+
+
+ir_visitor_status
+ir_end_primitive::accept(ir_hierarchical_visitor *v)
+{
+ return v->visit(this);
+}
diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h
index 2c1479ff4..b79c2b787 100644
--- a/mesalib/src/glsl/ir_optimization.h
+++ b/mesalib/src/glsl/ir_optimization.h
@@ -77,7 +77,7 @@ bool do_copy_propagation(exec_list *instructions);
bool do_copy_propagation_elements(exec_list *instructions);
bool do_constant_propagation(exec_list *instructions);
void do_dead_builtin_varyings(struct gl_context *ctx,
- exec_list *producer, exec_list *consumer,
+ gl_shader *producer, gl_shader *consumer,
unsigned num_tfeedback_decls,
class tfeedback_decl *tfeedback_decls);
bool do_dead_code(exec_list *instructions, bool uniform_locations_assigned);
@@ -112,7 +112,7 @@ bool lower_packing_builtins(exec_list *instructions, int op_mask);
void lower_ubo_reference(struct gl_shader *shader, exec_list *instructions);
void lower_packed_varyings(void *mem_ctx, unsigned location_base,
unsigned locations_used, ir_variable_mode mode,
- gl_shader *shader);
+ unsigned gs_input_vertices, gl_shader *shader);
bool lower_vector_insert(exec_list *instructions, bool lower_nonconstant_index);
void lower_named_interface_blocks(void *mem_ctx, gl_shader *shader);
bool optimize_redundant_jumps(exec_list *instructions);
diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp
index ca973a5f3..541231a33 100644
--- a/mesalib/src/glsl/ir_print_visitor.cpp
+++ b/mesalib/src/glsl/ir_print_visitor.cpp
@@ -539,3 +539,15 @@ ir_print_visitor::visit(ir_loop_jump *ir)
{
printf("%s", ir->is_break() ? "break" : "continue");
}
+
+void
+ir_print_visitor::visit(ir_emit_vertex *ir)
+{
+ printf("(emit-vertex)");
+}
+
+void
+ir_print_visitor::visit(ir_end_primitive *ir)
+{
+ printf("(end-primitive)");
+}
diff --git a/mesalib/src/glsl/ir_print_visitor.h b/mesalib/src/glsl/ir_print_visitor.h
index a84056d16..865376fe0 100644
--- a/mesalib/src/glsl/ir_print_visitor.h
+++ b/mesalib/src/glsl/ir_print_visitor.h
@@ -69,6 +69,8 @@ public:
virtual void visit(ir_if *);
virtual void visit(ir_loop *);
virtual void visit(ir_loop_jump *);
+ virtual void visit(ir_emit_vertex *);
+ virtual void visit(ir_end_primitive *);
/*@}*/
private:
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp
index 51534ca7c..f263fe810 100644
--- a/mesalib/src/glsl/ir_reader.cpp
+++ b/mesalib/src/glsl/ir_reader.cpp
@@ -59,6 +59,8 @@ private:
ir_swizzle *read_swizzle(s_expression *);
ir_constant *read_constant(s_expression *);
ir_texture *read_texture(s_expression *);
+ ir_emit_vertex *read_emit_vertex(s_expression *);
+ ir_end_primitive *read_end_primitive(s_expression *);
ir_dereference *read_dereference(s_expression *);
ir_dereference_variable *read_var_ref(s_expression *);
@@ -355,6 +357,10 @@ ir_reader::read_instruction(s_expression *expr, ir_loop *loop_ctx)
inst = read_return(list);
} else if (strcmp(tag->value(), "function") == 0) {
inst = read_function(list, false);
+ } else if (strcmp(tag->value(), "emit-vertex") == 0) {
+ inst = read_emit_vertex(list);
+ } else if (strcmp(tag->value(), "end-primitive") == 0) {
+ inst = read_end_primitive(list);
} else {
inst = read_rvalue(list);
if (inst == NULL)
@@ -1065,3 +1071,27 @@ ir_reader::read_texture(s_expression *expr)
};
return tex;
}
+
+ir_emit_vertex *
+ir_reader::read_emit_vertex(s_expression *expr)
+{
+ s_pattern pat[] = { "emit-vertex" };
+
+ if (MATCH(expr, pat)) {
+ return new(mem_ctx) ir_emit_vertex();
+ }
+ ir_read_error(NULL, "when reading emit-vertex");
+ return NULL;
+}
+
+ir_end_primitive *
+ir_reader::read_end_primitive(s_expression *expr)
+{
+ s_pattern pat[] = { "end-primitive" };
+
+ if (MATCH(expr, pat)) {
+ return new(mem_ctx) ir_end_primitive();
+ }
+ ir_read_error(NULL, "when reading end-primitive");
+ return NULL;
+}
diff --git a/mesalib/src/glsl/ir_set_program_inouts.cpp b/mesalib/src/glsl/ir_set_program_inouts.cpp
index 91a8b4526..6196d6a64 100644
--- a/mesalib/src/glsl/ir_set_program_inouts.cpp
+++ b/mesalib/src/glsl/ir_set_program_inouts.cpp
@@ -44,11 +44,10 @@
class ir_set_program_inouts_visitor : public ir_hierarchical_visitor {
public:
- ir_set_program_inouts_visitor(struct gl_program *prog,
- bool is_fragment_shader)
+ ir_set_program_inouts_visitor(struct gl_program *prog, GLenum shader_type)
{
this->prog = prog;
- this->is_fragment_shader = is_fragment_shader;
+ this->shader_type = shader_type;
}
~ir_set_program_inouts_visitor()
{
@@ -60,8 +59,12 @@ public:
virtual ir_visitor_status visit_enter(ir_discard *);
virtual ir_visitor_status visit(ir_dereference_variable *);
+private:
+ void mark_whole_variable(ir_variable *var);
+ bool try_mark_partial_variable(ir_variable *var, ir_rvalue *index);
+
struct gl_program *prog;
- bool is_fragment_shader;
+ GLenum shader_type;
};
static inline bool
@@ -104,6 +107,23 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len,
}
}
+/**
+ * Mark an entire variable as used. Caller must ensure that the variable
+ * represents a shader input or output.
+ */
+void
+ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var)
+{
+ const glsl_type *type = var->type;
+ if (this->shader_type == GL_GEOMETRY_SHADER &&
+ var->mode == ir_var_shader_in && type->is_array()) {
+ type = type->fields.array;
+ }
+
+ mark(this->prog, var, 0, type->count_attribute_slots(),
+ this->shader_type == GL_FRAGMENT_SHADER);
+}
+
/* Default handler: Mark all the locations in the variable as used. */
ir_visitor_status
ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir)
@@ -111,43 +131,154 @@ ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir)
if (!is_shader_inout(ir->var))
return visit_continue;
- if (ir->type->is_array()) {
- mark(this->prog, ir->var, 0,
- ir->type->length * ir->type->fields.array->matrix_columns,
- this->is_fragment_shader);
- } else {
- mark(this->prog, ir->var, 0, ir->type->matrix_columns,
- this->is_fragment_shader);
- }
+ mark_whole_variable(ir->var);
return visit_continue;
}
-ir_visitor_status
-ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
+/**
+ * Try to mark a portion of the given variable as used. Caller must ensure
+ * that the variable represents a shader input or output which can be indexed
+ * into in array fashion (an array or matrix). For the purpose of geometry
+ * shader inputs (which are always arrays*), this means that the array element
+ * must be something that can be indexed into in array fashion.
+ *
+ * *Except gl_PrimitiveIDIn, as noted below.
+ *
+ * If the index can't be interpreted as a constant, or some other problem
+ * occurs, then nothing will be marked and false will be returned.
+ */
+bool
+ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var,
+ ir_rvalue *index)
{
- ir_dereference_variable *deref_var;
- ir_constant *index = ir->array_index->as_constant();
- deref_var = ir->array->as_dereference_variable();
- ir_variable *var = deref_var ? deref_var->var : NULL;
+ const glsl_type *type = var->type;
- /* Check that we're dereferencing a shader in or out */
- if (!var || !is_shader_inout(var))
- return visit_continue;
+ if (this->shader_type == GL_GEOMETRY_SHADER &&
+ var->mode == ir_var_shader_in) {
+ /* The only geometry shader input that is not an array is
+ * gl_PrimitiveIDIn, and in that case, this code will never be reached,
+ * because gl_PrimitiveIDIn can't be indexed into in array fashion.
+ */
+ assert(type->is_array());
+ type = type->fields.array;
+ }
- if (index) {
- int width = 1;
+ /* The code below only handles:
+ *
+ * - Indexing into matrices
+ * - Indexing into arrays of (matrices, vectors, or scalars)
+ *
+ * All other possibilities are either prohibited by GLSL (vertex inputs and
+ * fragment outputs can't be structs) or should have been eliminated by
+ * lowering passes (do_vec_index_to_swizzle() gets rid of indexing into
+ * vectors, and lower_packed_varyings() gets rid of structs that occur in
+ * varyings).
+ */
+ if (!(type->is_matrix() ||
+ (type->is_array() &&
+ (type->fields.array->is_numeric() ||
+ type->fields.array->is_boolean())))) {
+ assert(!"Unexpected indexing in ir_set_program_inouts");
- if (deref_var->type->is_array() &&
- deref_var->type->fields.array->is_matrix()) {
- width = deref_var->type->fields.array->matrix_columns;
- }
+ /* For safety in release builds, in case we ever encounter unexpected
+ * indexing, give up and let the caller mark the whole variable as used.
+ */
+ return false;
+ }
+
+ ir_constant *index_as_constant = index->as_constant();
+ if (!index_as_constant)
+ return false;
+
+ unsigned elem_width;
+ unsigned num_elems;
+ if (type->is_array()) {
+ num_elems = type->length;
+ if (type->fields.array->is_matrix())
+ elem_width = type->fields.array->matrix_columns;
+ else
+ elem_width = 1;
+ } else {
+ num_elems = type->matrix_columns;
+ elem_width = 1;
+ }
- mark(this->prog, var, index->value.i[0] * width, width,
- this->is_fragment_shader);
- return visit_continue_with_parent;
+ if (index_as_constant->value.u[0] >= num_elems) {
+ /* Constant index outside the bounds of the matrix/array. This could
+ * arise as a result of constant folding of a legal GLSL program.
+ *
+ * Even though the spec says that indexing outside the bounds of a
+ * matrix/array results in undefined behaviour, we don't want to pass
+ * out-of-range values to mark() (since this could result in slots that
+ * don't exist being marked as used), so just let the caller mark the
+ * whole variable as used.
+ */
+ return false;
}
+ mark(this->prog, var, index_as_constant->value.u[0] * elem_width,
+ elem_width, this->shader_type == GL_FRAGMENT_SHADER);
+ return true;
+}
+
+ir_visitor_status
+ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
+{
+ /* Note: for geometry shader inputs, lower_named_interface_blocks may
+ * create 2D arrays, so we need to be able to handle those. 2D arrays
+ * shouldn't be able to crop up for any other reason.
+ */
+ if (ir_dereference_array * const inner_array =
+ ir->array->as_dereference_array()) {
+ /* ir => foo[i][j]
+ * inner_array => foo[i]
+ */
+ if (ir_dereference_variable * const deref_var =
+ inner_array->array->as_dereference_variable()) {
+ if (this->shader_type == GL_GEOMETRY_SHADER &&
+ deref_var->var->mode == ir_var_shader_in) {
+ /* foo is a geometry shader input, so i is the vertex, and j the
+ * part of the input we're accessing.
+ */
+ if (try_mark_partial_variable(deref_var->var, ir->array_index))
+ {
+ /* We've now taken care of foo and j, but i might contain a
+ * subexpression that accesses shader inputs. So manually
+ * visit i and then continue with the parent.
+ */
+ inner_array->array_index->accept(this);
+ return visit_continue_with_parent;
+ }
+ }
+ }
+ } else if (ir_dereference_variable * const deref_var =
+ ir->array->as_dereference_variable()) {
+ /* ir => foo[i], where foo is a variable. */
+ if (this->shader_type == GL_GEOMETRY_SHADER &&
+ deref_var->var->mode == ir_var_shader_in) {
+ /* foo is a geometry shader input, so i is the vertex, and we're
+ * accessing the entire input.
+ */
+ mark_whole_variable(deref_var->var);
+ /* We've now taken care of foo, but i might contain a subexpression
+ * that accesses shader inputs. So manually visit i and then
+ * continue with the parent.
+ */
+ ir->array_index->accept(this);
+ return visit_continue_with_parent;
+ } else if (is_shader_inout(deref_var->var)) {
+ /* foo is a shader input/output, but not a geometry shader input,
+ * so i is the part of the input we're accessing.
+ */
+ if (try_mark_partial_variable(deref_var->var, ir->array_index))
+ return visit_continue_with_parent;
+ }
+ }
+
+ /* The expression is something we don't recognize. Just visit its
+ * subexpressions.
+ */
return visit_continue;
}
@@ -164,7 +295,8 @@ ir_set_program_inouts_visitor::visit_enter(ir_function_signature *ir)
ir_visitor_status
ir_set_program_inouts_visitor::visit_enter(ir_expression *ir)
{
- if (is_fragment_shader && ir->operation == ir_unop_dFdy) {
+ if (this->shader_type == GL_FRAGMENT_SHADER &&
+ ir->operation == ir_unop_dFdy) {
gl_fragment_program *fprog = (gl_fragment_program *) prog;
fprog->UsesDFdy = true;
}
@@ -175,7 +307,7 @@ ir_visitor_status
ir_set_program_inouts_visitor::visit_enter(ir_discard *)
{
/* discards are only allowed in fragment shaders. */
- assert(is_fragment_shader);
+ assert(this->shader_type == GL_FRAGMENT_SHADER);
gl_fragment_program *fprog = (gl_fragment_program *) prog;
fprog->UsesKill = true;
@@ -185,14 +317,14 @@ ir_set_program_inouts_visitor::visit_enter(ir_discard *)
void
do_set_program_inouts(exec_list *instructions, struct gl_program *prog,
- bool is_fragment_shader)
+ GLenum shader_type)
{
- ir_set_program_inouts_visitor v(prog, is_fragment_shader);
+ ir_set_program_inouts_visitor v(prog, shader_type);
prog->InputsRead = 0;
prog->OutputsWritten = 0;
prog->SystemValuesRead = 0;
- if (is_fragment_shader) {
+ if (shader_type == GL_FRAGMENT_SHADER) {
gl_fragment_program *fprog = (gl_fragment_program *) prog;
memset(fprog->InterpQualifier, 0, sizeof(fprog->InterpQualifier));
fprog->IsCentroid = 0;
diff --git a/mesalib/src/glsl/ir_visitor.h b/mesalib/src/glsl/ir_visitor.h
index bd47ef7d5..40f96ffbc 100644
--- a/mesalib/src/glsl/ir_visitor.h
+++ b/mesalib/src/glsl/ir_visitor.h
@@ -63,6 +63,8 @@ public:
virtual void visit(class ir_if *) = 0;
virtual void visit(class ir_loop *) = 0;
virtual void visit(class ir_loop_jump *) = 0;
+ virtual void visit(class ir_emit_vertex *) = 0;
+ virtual void visit(class ir_end_primitive *) = 0;
/*@}*/
};
@@ -81,6 +83,8 @@ public:
virtual void visit(class ir_assignment *) {}
virtual void visit(class ir_constant *) {}
virtual void visit(class ir_call *) {}
+ virtual void visit(class ir_emit_vertex *) {}
+ virtual void visit(class ir_end_primitive *) {}
};
#endif /* __cplusplus */
diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp
index 2c7e4514e..4ceb1d33e 100644
--- a/mesalib/src/glsl/link_varyings.cpp
+++ b/mesalib/src/glsl/link_varyings.cpp
@@ -68,6 +68,10 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
/* Find all shader inputs in the "consumer" stage. Any variables that have
* matching outputs already in the symbol table must have the same type and
* qualifiers.
+ *
+ * Exception: if the consumer is the geometry shader, then the inputs
+ * should be arrays and the type of the array element should match the type
+ * of the corresponding producer output.
*/
foreach_list(node, consumer->ir) {
ir_variable *const input = ((ir_instruction *) node)->as_variable();
@@ -79,7 +83,12 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
if (output != NULL) {
/* Check that the types match between stages.
*/
- if (input->type != output->type) {
+ const glsl_type *type_to_match = input->type;
+ if (consumer->Type == GL_GEOMETRY_SHADER) {
+ assert(type_to_match->is_array()); /* Enforced by ast_to_hir */
+ type_to_match = type_to_match->element_type();
+ }
+ if (type_to_match != output->type) {
/* There is a bit of a special case for gl_TexCoord. This
* built-in is unsized by default. Applications that variable
* access it must redeclare it with a size. There is some
@@ -973,6 +982,9 @@ private:
* each of these objects that matches one of the outputs of the
* producer.
*
+ * \param gs_input_vertices: if \c consumer is a geometry shader, this is the
+ * number of input vertices it accepts. Otherwise zero.
+ *
* When num_tfeedback_decls is nonzero, it is permissible for the consumer to
* be NULL. In this case, varying locations are assigned solely based on the
* requirements of transform feedback.
@@ -983,7 +995,8 @@ assign_varying_locations(struct gl_context *ctx,
struct gl_shader_program *prog,
gl_shader *producer, gl_shader *consumer,
unsigned num_tfeedback_decls,
- tfeedback_decl *tfeedback_decls)
+ tfeedback_decl *tfeedback_decls,
+ unsigned gs_input_vertices)
{
const unsigned producer_base = VARYING_SLOT_VAR0;
const unsigned consumer_base = VARYING_SLOT_VAR0;
@@ -1104,10 +1117,10 @@ assign_varying_locations(struct gl_context *ctx,
assert(!ctx->Extensions.EXT_transform_feedback);
} else {
lower_packed_varyings(mem_ctx, producer_base, slots_used,
- ir_var_shader_out, producer);
+ ir_var_shader_out, 0, producer);
if (consumer) {
lower_packed_varyings(mem_ctx, consumer_base, slots_used,
- ir_var_shader_in, consumer);
+ ir_var_shader_in, gs_input_vertices, consumer);
}
}
@@ -1164,7 +1177,7 @@ check_against_varying_limit(struct gl_context *ctx,
/* The packing rules used for vertex shader inputs are also
* used for fragment shader inputs.
*/
- varying_vectors += count_attribute_slots(var->type);
+ varying_vectors += var->type->count_attribute_slots();
}
}
diff --git a/mesalib/src/glsl/link_varyings.h b/mesalib/src/glsl/link_varyings.h
index cfc6e474f..302ab5c26 100644
--- a/mesalib/src/glsl/link_varyings.h
+++ b/mesalib/src/glsl/link_varyings.h
@@ -234,7 +234,8 @@ assign_varying_locations(struct gl_context *ctx,
struct gl_shader_program *prog,
gl_shader *producer, gl_shader *consumer,
unsigned num_tfeedback_decls,
- tfeedback_decl *tfeedback_decls);
+ tfeedback_decl *tfeedback_decls,
+ unsigned gs_input_vertices);
bool
check_against_varying_limit(struct gl_context *ctx,
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 942f90615..f87ae0eec 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -73,11 +73,15 @@
#include "linker.h"
#include "link_varyings.h"
#include "ir_optimization.h"
+#include "ir_rvalue_visitor.h"
extern "C" {
#include "main/shaderobj.h"
+#include "main/enums.h"
}
+void linker_error(gl_shader_program *, const char *, ...);
+
/**
* Visitor that determines whether or not a variable is ever written.
*/
@@ -174,6 +178,77 @@ private:
};
+class geom_array_resize_visitor : public ir_hierarchical_visitor {
+public:
+ unsigned num_vertices;
+ gl_shader_program *prog;
+
+ geom_array_resize_visitor(unsigned num_vertices, gl_shader_program *prog)
+ {
+ this->num_vertices = num_vertices;
+ this->prog = prog;
+ }
+
+ virtual ~geom_array_resize_visitor()
+ {
+ /* empty */
+ }
+
+ virtual ir_visitor_status visit(ir_variable *var)
+ {
+ if (!var->type->is_array() || var->mode != ir_var_shader_in)
+ return visit_continue;
+
+ unsigned size = var->type->length;
+
+ /* Generate a link error if the shader has declared this array with an
+ * incorrect size.
+ */
+ if (size && size != this->num_vertices) {
+ linker_error(this->prog, "size of array %s declared as %u, "
+ "but number of input vertices is %u\n",
+ var->name, size, this->num_vertices);
+ return visit_continue;
+ }
+
+ /* Generate a link error if the shader attempts to access an input
+ * array using an index too large for its actual size assigned at link
+ * time.
+ */
+ if (var->max_array_access >= this->num_vertices) {
+ linker_error(this->prog, "geometry shader accesses element %i of "
+ "%s, but only %i input vertices\n",
+ var->max_array_access, var->name, this->num_vertices);
+ return visit_continue;
+ }
+
+ var->type = glsl_type::get_array_instance(var->type->element_type(),
+ this->num_vertices);
+ var->max_array_access = this->num_vertices - 1;
+
+ return visit_continue;
+ }
+
+ /* Dereferences of input variables need to be updated so that their type
+ * matches the newly assigned type of the variable they are accessing. */
+ virtual ir_visitor_status visit(ir_dereference_variable *ir)
+ {
+ ir->type = ir->var->type;
+ return visit_continue;
+ }
+
+ /* Dereferences of 2D input arrays need to be updated so that their type
+ * matches the newly assigned type of the array they are accessing. */
+ virtual ir_visitor_status visit_leave(ir_dereference_array *ir)
+ {
+ const glsl_type *const vt = ir->array->type;
+ if (vt->is_array())
+ ir->type = vt->element_type();
+ return visit_continue;
+ }
+};
+
+
void
linker_error(gl_shader_program *prog, const char *fmt, ...)
{
@@ -298,41 +373,6 @@ link_invalidate_variable_locations(gl_shader *sh, int input_base,
/**
- * Determine the number of attribute slots required for a particular type
- *
- * This code is here because it implements the language rules of a specific
- * GLSL version. Since it's a property of the language and not a property of
- * types in general, it doesn't really belong in glsl_type.
- */
-unsigned
-count_attribute_slots(const glsl_type *t)
-{
- /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
- *
- * "A scalar input counts the same amount against this limit as a vec4,
- * so applications may want to consider packing groups of four
- * unrelated float inputs together into a vector to better utilize the
- * capabilities of the underlying hardware. A matrix input will use up
- * multiple locations. The number of locations used will equal the
- * number of columns in the matrix."
- *
- * The spec does not explicitly say how arrays are counted. However, it
- * should be safe to assume the total number of slots consumed by an array
- * is the number of entries in the array multiplied by the number of slots
- * consumed by a single element of the array.
- */
-
- if (t->is_array())
- return t->array_size() * count_attribute_slots(t->element_type());
-
- if (t->is_matrix())
- return t->matrix_columns;
-
- return 1;
-}
-
-
-/**
* Verify that a vertex shader executable meets all semantic requirements.
*
* Also sets prog->Vert.UsesClipDistance and prog->Vert.ClipDistanceArraySize
@@ -437,6 +477,24 @@ validate_fragment_shader_executable(struct gl_shader_program *prog,
}
}
+/**
+ * Verify that a geometry shader executable meets all semantic requirements
+ *
+ * Also sets prog->Geom.VerticesIn as a side effect.
+ *
+ * \param shader Geometry shader executable to be verified
+ */
+void
+validate_geometry_shader_executable(struct gl_shader_program *prog,
+ struct gl_shader *shader)
+{
+ if (shader == NULL)
+ return;
+
+ unsigned num_vertices = vertices_per_prim(prog->Geom.InputType);
+ prog->Geom.VerticesIn = num_vertices;
+}
+
/**
* Generate a string describing the mode of a variable
@@ -931,6 +989,99 @@ public:
};
/**
+ * Performs the cross-validation of geometry shader max_vertices and
+ * primitive type layout qualifiers for the attached geometry shaders,
+ * and propagates them to the linked GS and linked shader program.
+ */
+static void
+link_gs_inout_layout_qualifiers(struct gl_shader_program *prog,
+ struct gl_shader *linked_shader,
+ struct gl_shader **shader_list,
+ unsigned num_shaders)
+{
+ linked_shader->Geom.VerticesOut = 0;
+ linked_shader->Geom.InputType = PRIM_UNKNOWN;
+ linked_shader->Geom.OutputType = PRIM_UNKNOWN;
+
+ /* No in/out qualifiers defined for anything but GLSL 1.50+
+ * geometry shaders so far.
+ */
+ if (linked_shader->Type != GL_GEOMETRY_SHADER || prog->Version < 150)
+ return;
+
+ /* From the GLSL 1.50 spec, page 46:
+ *
+ * "All geometry shader output layout declarations in a program
+ * must declare the same layout and same value for
+ * max_vertices. There must be at least one geometry output
+ * layout declaration somewhere in a program, but not all
+ * geometry shaders (compilation units) are required to
+ * declare it."
+ */
+
+ for (unsigned i = 0; i < num_shaders; i++) {
+ struct gl_shader *shader = shader_list[i];
+
+ if (shader->Geom.InputType != PRIM_UNKNOWN) {
+ if (linked_shader->Geom.InputType != PRIM_UNKNOWN &&
+ linked_shader->Geom.InputType != shader->Geom.InputType) {
+ linker_error(prog, "geometry shader defined with conflicting "
+ "input types\n");
+ return;
+ }
+ linked_shader->Geom.InputType = shader->Geom.InputType;
+ }
+
+ if (shader->Geom.OutputType != PRIM_UNKNOWN) {
+ if (linked_shader->Geom.OutputType != PRIM_UNKNOWN &&
+ linked_shader->Geom.OutputType != shader->Geom.OutputType) {
+ linker_error(prog, "geometry shader defined with conflicting "
+ "output types\n");
+ return;
+ }
+ linked_shader->Geom.OutputType = shader->Geom.OutputType;
+ }
+
+ if (shader->Geom.VerticesOut != 0) {
+ if (linked_shader->Geom.VerticesOut != 0 &&
+ linked_shader->Geom.VerticesOut != shader->Geom.VerticesOut) {
+ linker_error(prog, "geometry shader defined with conflicting "
+ "output vertex count (%d and %d)\n",
+ linked_shader->Geom.VerticesOut,
+ shader->Geom.VerticesOut);
+ return;
+ }
+ linked_shader->Geom.VerticesOut = shader->Geom.VerticesOut;
+ }
+ }
+
+ /* Just do the intrastage -> interstage propagation right now,
+ * since we already know we're in the right type of shader program
+ * for doing it.
+ */
+ if (linked_shader->Geom.InputType == PRIM_UNKNOWN) {
+ linker_error(prog,
+ "geometry shader didn't declare primitive input type\n");
+ return;
+ }
+ prog->Geom.InputType = linked_shader->Geom.InputType;
+
+ if (linked_shader->Geom.OutputType == PRIM_UNKNOWN) {
+ linker_error(prog,
+ "geometry shader didn't declare primitive output type\n");
+ return;
+ }
+ prog->Geom.OutputType = linked_shader->Geom.OutputType;
+
+ if (linked_shader->Geom.VerticesOut == 0) {
+ linker_error(prog,
+ "geometry shader didn't declare max_vertices\n");
+ return;
+ }
+ prog->Geom.VerticesOut = linked_shader->Geom.VerticesOut;
+}
+
+/**
* Combine a group of shaders for a single stage to generate a linked shader
*
* \note
@@ -1034,6 +1185,8 @@ link_intrastage_shaders(void *mem_ctx,
linked->NumUniformBlocks = num_uniform_blocks;
ralloc_steal(linked, linked->UniformBlocks);
+ link_gs_inout_layout_qualifiers(prog, linked, shader_list, num_shaders);
+
populate_symbol_table(linked);
/* The a pointer to the main function in the final linked shader (i.e., the
@@ -1080,7 +1233,8 @@ link_intrastage_shaders(void *mem_ctx,
if (!link_function_calls(prog, linked, linking_shaders,
num_linking_shaders)) {
ctx->Driver.DeleteShader(ctx, linked);
- linked = NULL;
+ free(linking_shaders);
+ return NULL;
}
free(linking_shaders);
@@ -1088,18 +1242,24 @@ link_intrastage_shaders(void *mem_ctx,
/* At this point linked should contain all of the linked IR, so
* validate it to make sure nothing went wrong.
*/
- if (linked)
- validate_ir_tree(linked->ir);
+ validate_ir_tree(linked->ir);
+
+ /* Set the size of geometry shader input arrays */
+ if (linked->Type == GL_GEOMETRY_SHADER) {
+ unsigned num_vertices = vertices_per_prim(prog->Geom.InputType);
+ geom_array_resize_visitor input_resize_visitor(num_vertices, prog);
+ foreach_iter(exec_list_iterator, iter, *linked->ir) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ ir->accept(&input_resize_visitor);
+ }
+ }
/* Make a pass over all variable declarations to ensure that arrays with
* unspecified sizes have a size specified. The size is inferred from the
* max_array_access field.
*/
- if (linked != NULL) {
- array_sizing_visitor v;
-
- v.run(linked->ir);
- }
+ array_sizing_visitor v;
+ v.run(linked->ir);
return linked;
}
@@ -1129,9 +1289,7 @@ update_array_sizes(struct gl_shader_program *prog)
foreach_list(node, prog->_LinkedShaders[i]->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if ((var == NULL) || (var->mode != ir_var_uniform &&
- var->mode != ir_var_shader_in &&
- var->mode != ir_var_shader_out) ||
+ if ((var == NULL) || (var->mode != ir_var_uniform) ||
!var->type->is_array())
continue;
@@ -1334,7 +1492,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
* that it doesn't collide with other assigned locations. Otherwise,
* add it to the list of variables that need linker-assigned locations.
*/
- const unsigned slots = count_attribute_slots(var->type);
+ const unsigned slots = var->type->count_attribute_slots();
if (var->location != -1) {
if (var->location >= generic_base && var->index < 1) {
/* From page 61 of the OpenGL 4.0 spec:
@@ -1650,10 +1808,15 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
unsigned num_vert_shaders = 0;
struct gl_shader **frag_shader_list;
unsigned num_frag_shaders = 0;
+ struct gl_shader **geom_shader_list;
+ unsigned num_geom_shaders = 0;
vert_shader_list = (struct gl_shader **)
- calloc(2 * prog->NumShaders, sizeof(struct gl_shader *));
- frag_shader_list = &vert_shader_list[prog->NumShaders];
+ calloc(prog->NumShaders, sizeof(struct gl_shader *));
+ frag_shader_list = (struct gl_shader **)
+ calloc(prog->NumShaders, sizeof(struct gl_shader *));
+ geom_shader_list = (struct gl_shader **)
+ calloc(prog->NumShaders, sizeof(struct gl_shader *));
unsigned min_version = UINT_MAX;
unsigned max_version = 0;
@@ -1679,8 +1842,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
num_frag_shaders++;
break;
case GL_GEOMETRY_SHADER:
- /* FINISHME: Support geometry shaders. */
- assert(prog->Shaders[i]->Type != GL_GEOMETRY_SHADER);
+ geom_shader_list[num_geom_shaders] = prog->Shaders[i];
+ num_geom_shaders++;
break;
}
}
@@ -1701,6 +1864,14 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
prog->Version = max_version;
prog->IsES = is_es_prog;
+ /* Geometry shaders have to be linked with vertex shaders.
+ */
+ if (num_geom_shaders > 0 && num_vert_shaders == 0) {
+ linker_error(prog, "Geometry shader must be linked with "
+ "vertex shader\n");
+ goto done;
+ }
+
for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) {
if (prog->_LinkedShaders[i] != NULL)
ctx->Driver.DeleteShader(ctx, prog->_LinkedShaders[i]);
@@ -1742,6 +1913,22 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
sh);
}
+ if (num_geom_shaders > 0) {
+ gl_shader *const sh =
+ link_intrastage_shaders(mem_ctx, ctx, prog, geom_shader_list,
+ num_geom_shaders);
+
+ if (!prog->LinkStatus)
+ goto done;
+
+ validate_geometry_shader_executable(prog, sh);
+ if (!prog->LinkStatus)
+ goto done;
+
+ _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_GEOMETRY],
+ sh);
+ }
+
/* Here begins the inter-stage linking phase. Some initial validation is
* performed, then locations are assigned for uniforms, attributes, and
* varyings.
@@ -1828,7 +2015,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
prog->_LinkedShaders[MESA_SHADER_VERTEX],
VERT_ATTRIB_GENERIC0, VARYING_SLOT_VAR0);
}
- /* FINISHME: Geometry shaders not implemented yet */
+ if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
+ link_invalidate_variable_locations(
+ prog->_LinkedShaders[MESA_SHADER_GEOMETRY],
+ VARYING_SLOT_VAR0, VARYING_SLOT_VAR0);
+ }
if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {
link_invalidate_variable_locations(
prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
@@ -1862,7 +2053,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
* non-zero, but the program object has no vertex or geometry
* shader;
*/
- if (first >= MESA_SHADER_FRAGMENT) {
+ if (first == MESA_SHADER_FRAGMENT) {
linker_error(prog, "Transform feedback varyings specified, but "
"no vertex or geometry shader is present.");
goto done;
@@ -1895,11 +2086,12 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
*/
if (!assign_varying_locations(ctx, mem_ctx, prog,
sh, NULL,
- num_tfeedback_decls, tfeedback_decls))
+ num_tfeedback_decls, tfeedback_decls,
+ 0))
goto done;
}
- do_dead_builtin_varyings(ctx, sh->ir, NULL,
+ do_dead_builtin_varyings(ctx, sh, NULL,
num_tfeedback_decls, tfeedback_decls);
demote_shader_inputs_and_outputs(sh, ir_var_shader_out);
@@ -1914,7 +2106,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
*/
gl_shader *const sh = prog->_LinkedShaders[first];
- do_dead_builtin_varyings(ctx, NULL, sh->ir,
+ do_dead_builtin_varyings(ctx, NULL, sh,
num_tfeedback_decls, tfeedback_decls);
demote_shader_inputs_and_outputs(sh, ir_var_shader_in);
@@ -1930,13 +2122,15 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
gl_shader *const sh_i = prog->_LinkedShaders[i];
gl_shader *const sh_next = prog->_LinkedShaders[next];
+ unsigned gs_input_vertices =
+ next == MESA_SHADER_GEOMETRY ? prog->Geom.VerticesIn : 0;
if (!assign_varying_locations(ctx, mem_ctx, prog, sh_i, sh_next,
next == MESA_SHADER_FRAGMENT ? num_tfeedback_decls : 0,
- tfeedback_decls))
+ tfeedback_decls, gs_input_vertices))
goto done;
- do_dead_builtin_varyings(ctx, sh_i->ir, sh_next->ir,
+ do_dead_builtin_varyings(ctx, sh_i, sh_next,
next == MESA_SHADER_FRAGMENT ? num_tfeedback_decls : 0,
tfeedback_decls);
@@ -1985,6 +2179,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
done:
free(vert_shader_list);
+ free(frag_shader_list);
+ free(geom_shader_list);
for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
if (prog->_LinkedShaders[i] == NULL)
diff --git a/mesalib/src/glsl/linker.h b/mesalib/src/glsl/linker.h
index 0ce747d6c..64a683d15 100644
--- a/mesalib/src/glsl/linker.h
+++ b/mesalib/src/glsl/linker.h
@@ -155,7 +155,4 @@ linker_error(gl_shader_program *prog, const char *fmt, ...);
void
linker_warning(gl_shader_program *prog, const char *fmt, ...);
-unsigned
-count_attribute_slots(const glsl_type *t);
-
#endif /* GLSL_LINKER_H */
diff --git a/mesalib/src/glsl/lower_output_reads.cpp b/mesalib/src/glsl/lower_output_reads.cpp
index b93e254ec..5ba9720d0 100644
--- a/mesalib/src/glsl/lower_output_reads.cpp
+++ b/mesalib/src/glsl/lower_output_reads.cpp
@@ -50,6 +50,7 @@ public:
output_read_remover();
~output_read_remover();
virtual ir_visitor_status visit(class ir_dereference_variable *);
+ virtual ir_visitor_status visit(class ir_emit_vertex *);
virtual ir_visitor_status visit_leave(class ir_return *);
virtual ir_visitor_status visit_leave(class ir_function_signature *);
};
@@ -117,7 +118,9 @@ copy(void *ctx, ir_variable *output, ir_variable *temp)
return new(ctx) ir_assignment(lhs, rhs);
}
-/** Insert a copy-back assignment before a "return" statement */
+/** Insert a copy-back assignment before a "return" statement or a call to
+ * EmitVertex().
+ */
static void
emit_return_copy(const void *key, void *data, void *closure)
{
@@ -141,6 +144,14 @@ output_read_remover::visit_leave(ir_return *ir)
}
ir_visitor_status
+output_read_remover::visit(ir_emit_vertex *ir)
+{
+ hash_table_call_foreach(replacements, emit_return_copy, ir);
+ hash_table_clear(replacements);
+ return visit_continue;
+}
+
+ir_visitor_status
output_read_remover::visit_leave(ir_function_signature *sig)
{
if (strcmp(sig->function_name(), "main") != 0)
diff --git a/mesalib/src/glsl/lower_packed_varyings.cpp b/mesalib/src/glsl/lower_packed_varyings.cpp
index cdf2289b4..31a50bba5 100644
--- a/mesalib/src/glsl/lower_packed_varyings.cpp
+++ b/mesalib/src/glsl/lower_packed_varyings.cpp
@@ -74,6 +74,74 @@
* This lowering pass also handles varyings whose type is a struct or an array
* of struct. Structs are packed in order and with no gaps, so there may be a
* performance penalty due to structure elements being double-parked.
+ *
+ * Lowering of geometry shader inputs is slightly more complex, since geometry
+ * inputs are always arrays, so we need to lower arrays to arrays. For
+ * example, the following input:
+ *
+ * in struct Foo {
+ * float f;
+ * vec3 v;
+ * vec2 a[2];
+ * } arr[3]; // location=4, location_frac=0
+ *
+ * Would get lowered like this if it occurred in a fragment shader:
+ *
+ * struct Foo {
+ * float f;
+ * vec3 v;
+ * vec2 a[2];
+ * } arr[3];
+ * in vec4 packed4; // location=4, location_frac=0
+ * in vec4 packed5; // location=5, location_frac=0
+ * in vec4 packed6; // location=6, location_frac=0
+ * in vec4 packed7; // location=7, location_frac=0
+ * in vec4 packed8; // location=8, location_frac=0
+ * in vec4 packed9; // location=9, location_frac=0
+ *
+ * main()
+ * {
+ * arr[0].f = packed4.x;
+ * arr[0].v = packed4.yzw;
+ * arr[0].a[0] = packed5.xy;
+ * arr[0].a[1] = packed5.zw;
+ * arr[1].f = packed6.x;
+ * arr[1].v = packed6.yzw;
+ * arr[1].a[0] = packed7.xy;
+ * arr[1].a[1] = packed7.zw;
+ * arr[2].f = packed8.x;
+ * arr[2].v = packed8.yzw;
+ * arr[2].a[0] = packed9.xy;
+ * arr[2].a[1] = packed9.zw;
+ * ...
+ * }
+ *
+ * But it would get lowered like this if it occurred in a geometry shader:
+ *
+ * struct Foo {
+ * float f;
+ * vec3 v;
+ * vec2 a[2];
+ * } arr[3];
+ * in vec4 packed4[3]; // location=4, location_frac=0
+ * in vec4 packed5[3]; // location=5, location_frac=0
+ *
+ * main()
+ * {
+ * arr[0].f = packed4[0].x;
+ * arr[0].v = packed4[0].yzw;
+ * arr[0].a[0] = packed5[0].xy;
+ * arr[0].a[1] = packed5[0].zw;
+ * arr[1].f = packed4[1].x;
+ * arr[1].v = packed4[1].yzw;
+ * arr[1].a[0] = packed5[1].xy;
+ * arr[1].a[1] = packed5[1].zw;
+ * arr[2].f = packed4[2].x;
+ * arr[2].v = packed4[2].yzw;
+ * arr[2].a[0] = packed5[2].xy;
+ * arr[2].a[1] = packed5[2].zw;
+ * ...
+ * }
*/
#include "glsl_symbol_table.h"
@@ -93,7 +161,8 @@ public:
lower_packed_varyings_visitor(void *mem_ctx, unsigned location_base,
unsigned locations_used,
ir_variable_mode mode,
- exec_list *main_instructions);
+ unsigned gs_input_vertices,
+ exec_list *out_instructions);
void run(exec_list *instructions);
@@ -101,13 +170,16 @@ private:
ir_assignment *bitwise_assign_pack(ir_rvalue *lhs, ir_rvalue *rhs);
ir_assignment *bitwise_assign_unpack(ir_rvalue *lhs, ir_rvalue *rhs);
unsigned lower_rvalue(ir_rvalue *rvalue, unsigned fine_location,
- ir_variable *unpacked_var, const char *name);
+ ir_variable *unpacked_var, const char *name,
+ bool gs_input_toplevel, unsigned vertex_index);
unsigned lower_arraylike(ir_rvalue *rvalue, unsigned array_size,
unsigned fine_location,
- ir_variable *unpacked_var, const char *name);
- ir_variable *get_packed_varying(unsigned location,
- ir_variable *unpacked_var,
- const char *name);
+ ir_variable *unpacked_var, const char *name,
+ bool gs_input_toplevel, unsigned vertex_index);
+ ir_dereference *get_packed_varying_deref(unsigned location,
+ ir_variable *unpacked_var,
+ const char *name,
+ unsigned vertex_index);
bool needs_lowering(ir_variable *var);
/**
@@ -145,15 +217,23 @@ private:
const ir_variable_mode mode;
/**
- * List of instructions corresponding to the main() function. This is
- * where we add instructions to pack or unpack the varyings.
+ * If we are currently lowering geometry shader inputs, the number of input
+ * vertices the geometry shader accepts. Otherwise zero.
*/
- exec_list *main_instructions;
+ const unsigned gs_input_vertices;
+
+ /**
+ * Exec list into which the visitor should insert the packing instructions.
+ * Caller provides this list; it should insert the instructions into the
+ * appropriate place in the shader once the visitor has finished running.
+ */
+ exec_list *out_instructions;
};
lower_packed_varyings_visitor::lower_packed_varyings_visitor(
void *mem_ctx, unsigned location_base, unsigned locations_used,
- ir_variable_mode mode, exec_list *main_instructions)
+ ir_variable_mode mode, unsigned gs_input_vertices,
+ exec_list *out_instructions)
: mem_ctx(mem_ctx),
location_base(location_base),
locations_used(locations_used),
@@ -161,7 +241,8 @@ lower_packed_varyings_visitor::lower_packed_varyings_visitor(
rzalloc_array_size(mem_ctx, sizeof(*packed_varyings),
locations_used)),
mode(mode),
- main_instructions(main_instructions)
+ gs_input_vertices(gs_input_vertices),
+ out_instructions(out_instructions)
{
}
@@ -195,7 +276,7 @@ lower_packed_varyings_visitor::run(exec_list *instructions)
/* Recursively pack or unpack it. */
this->lower_rvalue(deref, var->location * 4 + var->location_frac, var,
- var->name);
+ var->name, this->gs_input_vertices != 0, 0);
}
}
@@ -277,6 +358,15 @@ lower_packed_varyings_visitor::bitwise_assign_unpack(ir_rvalue *lhs,
* in multiples of a float, rather than multiples of a vec4 as is used
* elsewhere in Mesa.
*
+ * \param gs_input_toplevel should be set to true if we are lowering geometry
+ * shader inputs, and we are currently lowering the whole input variable
+ * (i.e. we are lowering the array whose index selects the vertex).
+ *
+ * \param vertex_index: if we are lowering geometry shader inputs, and the
+ * level of the array that we are currently lowering is *not* the top level,
+ * then this indicates which vertex we are currently lowering. Otherwise it
+ * is ignored.
+ *
* \return the location where the next constituent vector (after this one)
* should be packed.
*/
@@ -284,8 +374,15 @@ unsigned
lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
unsigned fine_location,
ir_variable *unpacked_var,
- const char *name)
+ const char *name,
+ bool gs_input_toplevel,
+ unsigned vertex_index)
{
+ /* When gs_input_toplevel is set, we should be looking at a geometry shader
+ * input array.
+ */
+ assert(!gs_input_toplevel || rvalue->type->is_array());
+
if (rvalue->type->is_record()) {
for (unsigned i = 0; i < rvalue->type->length; i++) {
if (i != 0)
@@ -296,7 +393,8 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
char *deref_name
= ralloc_asprintf(this->mem_ctx, "%s.%s", name, field_name);
fine_location = this->lower_rvalue(dereference_record, fine_location,
- unpacked_var, deref_name);
+ unpacked_var, deref_name, false,
+ vertex_index);
}
return fine_location;
} else if (rvalue->type->is_array()) {
@@ -304,13 +402,15 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
* sequence.
*/
return this->lower_arraylike(rvalue, rvalue->type->array_size(),
- fine_location, unpacked_var, name);
+ fine_location, unpacked_var, name,
+ gs_input_toplevel, vertex_index);
} else if (rvalue->type->is_matrix()) {
/* Matrices are packed/unpacked by considering each column vector in
* sequence.
*/
return this->lower_arraylike(rvalue, rvalue->type->matrix_columns,
- fine_location, unpacked_var, name);
+ fine_location, unpacked_var, name,
+ false, vertex_index);
} else if (rvalue->type->vector_elements + fine_location % 4 > 4) {
/* This vector is going to be "double parked" across two varying slots,
* so handle it as two separate assignments.
@@ -340,9 +440,10 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
char *right_name
= ralloc_asprintf(this->mem_ctx, "%s.%s", name, right_swizzle_name);
fine_location = this->lower_rvalue(left_swizzle, fine_location,
- unpacked_var, left_name);
+ unpacked_var, left_name, false,
+ vertex_index);
return this->lower_rvalue(right_swizzle, fine_location, unpacked_var,
- right_name);
+ right_name, false, vertex_index);
} else {
/* No special handling is necessary; pack the rvalue into the
* varying.
@@ -353,19 +454,19 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
unsigned location_frac = fine_location % 4;
for (unsigned i = 0; i < components; ++i)
swizzle_values[i] = i + location_frac;
- ir_dereference_variable *packed_deref = new(this->mem_ctx)
- ir_dereference_variable(this->get_packed_varying(location,
- unpacked_var, name));
+ ir_dereference *packed_deref =
+ this->get_packed_varying_deref(location, unpacked_var, name,
+ vertex_index);
ir_swizzle *swizzle = new(this->mem_ctx)
ir_swizzle(packed_deref, swizzle_values, components);
if (this->mode == ir_var_shader_out) {
ir_assignment *assignment
= this->bitwise_assign_pack(swizzle, rvalue);
- this->main_instructions->push_tail(assignment);
+ this->out_instructions->push_tail(assignment);
} else {
ir_assignment *assignment
= this->bitwise_assign_unpack(rvalue, swizzle);
- this->main_instructions->push_head(assignment);
+ this->out_instructions->push_tail(assignment);
}
return fine_location + components;
}
@@ -376,13 +477,24 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
* constituent elements, accessing each one using an ir_dereference_array.
* This takes care of both arrays and matrices, since ir_dereference_array
* treats a matrix like an array of its column vectors.
+ *
+ * \param gs_input_toplevel should be set to true if we are lowering geometry
+ * shader inputs, and we are currently lowering the whole input variable
+ * (i.e. we are lowering the array whose index selects the vertex).
+ *
+ * \param vertex_index: if we are lowering geometry shader inputs, and the
+ * level of the array that we are currently lowering is *not* the top level,
+ * then this indicates which vertex we are currently lowering. Otherwise it
+ * is ignored.
*/
unsigned
lower_packed_varyings_visitor::lower_arraylike(ir_rvalue *rvalue,
unsigned array_size,
unsigned fine_location,
ir_variable *unpacked_var,
- const char *name)
+ const char *name,
+ bool gs_input_toplevel,
+ unsigned vertex_index)
{
for (unsigned i = 0; i < array_size; i++) {
if (i != 0)
@@ -392,8 +504,20 @@ lower_packed_varyings_visitor::lower_arraylike(ir_rvalue *rvalue,
ir_dereference_array(rvalue, constant);
char *subscripted_name
= ralloc_asprintf(this->mem_ctx, "%s[%d]", name, i);
- fine_location = this->lower_rvalue(dereference_array, fine_location,
- unpacked_var, subscripted_name);
+ if (gs_input_toplevel) {
+ /* Geometry shader inputs are a special case. Instead of storing
+ * each element of the array at a different location, all elements
+ * are at the same location, but with a different vertex index.
+ */
+ (void) this->lower_rvalue(dereference_array, fine_location,
+ unpacked_var, subscripted_name,
+ false, i);
+ } else {
+ fine_location =
+ this->lower_rvalue(dereference_array, fine_location,
+ unpacked_var, subscripted_name,
+ false, vertex_index);
+ }
}
return fine_location;
}
@@ -406,11 +530,14 @@ lower_packed_varyings_visitor::lower_arraylike(ir_rvalue *rvalue,
* The newly created varying inherits its interpolation parameters from \c
* unpacked_var. Its base type is ivec4 if we are lowering a flat varying,
* vec4 otherwise.
+ *
+ * \param vertex_index: if we are lowering geometry shader inputs, then this
+ * indicates which vertex we are currently lowering. Otherwise it is ignored.
*/
-ir_variable *
-lower_packed_varyings_visitor::get_packed_varying(unsigned location,
- ir_variable *unpacked_var,
- const char *name)
+ir_dereference *
+lower_packed_varyings_visitor::get_packed_varying_deref(
+ unsigned location, ir_variable *unpacked_var, const char *name,
+ unsigned vertex_index)
{
unsigned slot = location - this->location_base;
assert(slot < locations_used);
@@ -421,18 +548,44 @@ lower_packed_varyings_visitor::get_packed_varying(unsigned location,
packed_type = glsl_type::ivec4_type;
else
packed_type = glsl_type::vec4_type;
+ if (this->gs_input_vertices != 0) {
+ packed_type =
+ glsl_type::get_array_instance(packed_type,
+ this->gs_input_vertices);
+ }
ir_variable *packed_var = new(this->mem_ctx)
ir_variable(packed_type, packed_name, this->mode);
+ if (this->gs_input_vertices != 0) {
+ /* Prevent update_array_sizes() from messing with the size of the
+ * array.
+ */
+ packed_var->max_array_access = this->gs_input_vertices - 1;
+ }
packed_var->centroid = unpacked_var->centroid;
packed_var->interpolation = unpacked_var->interpolation;
packed_var->location = location;
unpacked_var->insert_before(packed_var);
this->packed_varyings[slot] = packed_var;
} else {
- ralloc_asprintf_append((char **) &this->packed_varyings[slot]->name,
- ",%s", name);
+ /* For geometry shader inputs, only update the packed variable name the
+ * first time we visit each component.
+ */
+ if (this->gs_input_vertices == 0 || vertex_index == 0) {
+ ralloc_asprintf_append((char **) &this->packed_varyings[slot]->name,
+ ",%s", name);
+ }
+ }
+
+ ir_dereference *deref = new(this->mem_ctx)
+ ir_dereference_variable(this->packed_varyings[slot]);
+ if (this->gs_input_vertices != 0) {
+ /* When lowering GS inputs, the packed variable is an array, so we need
+ * to dereference it using vertex_index.
+ */
+ ir_constant *constant = new(this->mem_ctx) ir_constant(vertex_index);
+ deref = new(this->mem_ctx) ir_dereference_array(deref, constant);
}
- return this->packed_varyings[slot];
+ return deref;
}
bool
@@ -440,6 +593,10 @@ lower_packed_varyings_visitor::needs_lowering(ir_variable *var)
{
/* Things composed of vec4's don't need lowering. Everything else does. */
const glsl_type *type = var->type;
+ if (this->gs_input_vertices != 0) {
+ assert(type->is_array());
+ type = type->element_type();
+ }
if (type->is_array())
type = type->fields.array;
if (type->vector_elements == 4)
@@ -447,19 +604,81 @@ lower_packed_varyings_visitor::needs_lowering(ir_variable *var)
return true;
}
+
+/**
+ * Visitor that splices varying packing code before every use of EmitVertex()
+ * in a geometry shader.
+ */
+class lower_packed_varyings_gs_splicer : public ir_hierarchical_visitor
+{
+public:
+ explicit lower_packed_varyings_gs_splicer(void *mem_ctx,
+ const exec_list *instructions);
+
+ virtual ir_visitor_status visit(ir_emit_vertex *ev);
+
+private:
+ /**
+ * Memory context used to allocate new instructions for the shader.
+ */
+ void * const mem_ctx;
+
+ /**
+ * Instructions that should be spliced into place before each EmitVertex()
+ * call.
+ */
+ const exec_list *instructions;
+};
+
+
+lower_packed_varyings_gs_splicer::lower_packed_varyings_gs_splicer(
+ void *mem_ctx, const exec_list *instructions)
+ : mem_ctx(mem_ctx), instructions(instructions)
+{
+}
+
+
+ir_visitor_status
+lower_packed_varyings_gs_splicer::visit(ir_emit_vertex *ev)
+{
+ foreach_list(node, this->instructions) {
+ ir_instruction *ir = (ir_instruction *) node;
+ ev->insert_before(ir->clone(this->mem_ctx, NULL));
+ }
+ return visit_continue;
+}
+
+
void
lower_packed_varyings(void *mem_ctx, unsigned location_base,
unsigned locations_used, ir_variable_mode mode,
- gl_shader *shader)
+ unsigned gs_input_vertices, gl_shader *shader)
{
exec_list *instructions = shader->ir;
ir_function *main_func = shader->symbols->get_function("main");
exec_list void_parameters;
ir_function_signature *main_func_sig
= main_func->matching_signature(&void_parameters);
- exec_list *main_instructions = &main_func_sig->body;
+ exec_list new_instructions;
lower_packed_varyings_visitor visitor(mem_ctx, location_base,
locations_used, mode,
- main_instructions);
+ gs_input_vertices, &new_instructions);
visitor.run(instructions);
+ if (mode == ir_var_shader_out) {
+ if (shader->Type == GL_GEOMETRY_SHADER) {
+ /* For geometry shaders, outputs need to be lowered before each call
+ * to EmitVertex()
+ */
+ lower_packed_varyings_gs_splicer splicer(mem_ctx, &new_instructions);
+ splicer.run(instructions);
+ } else {
+ /* For other shader types, outputs need to be lowered at the end of
+ * main()
+ */
+ main_func_sig->body.append_list(&new_instructions);
+ }
+ } else {
+ /* Shader inputs need to be lowered at the beginning of main() */
+ main_func_sig->body.head->insert_before(&new_instructions);
+ }
}
diff --git a/mesalib/src/glsl/opt_dead_builtin_varyings.cpp b/mesalib/src/glsl/opt_dead_builtin_varyings.cpp
index 2e813d24e..6745d5c64 100644
--- a/mesalib/src/glsl/opt_dead_builtin_varyings.cpp
+++ b/mesalib/src/glsl/opt_dead_builtin_varyings.cpp
@@ -409,7 +409,7 @@ lower_texcoord_array(exec_list *ir, const varying_info_visitor *info)
void
do_dead_builtin_varyings(struct gl_context *ctx,
- exec_list *producer, exec_list *consumer,
+ gl_shader *producer, gl_shader *consumer,
unsigned num_tfeedback_decls,
tfeedback_decl *tfeedback_decls)
{
@@ -431,44 +431,55 @@ do_dead_builtin_varyings(struct gl_context *ctx,
varying_info_visitor consumer_info(ir_var_shader_in);
if (producer) {
- producer_info.get(producer, num_tfeedback_decls, tfeedback_decls);
+ producer_info.get(producer->ir, num_tfeedback_decls, tfeedback_decls);
if (!consumer) {
/* At least eliminate unused gl_TexCoord elements. */
if (producer_info.lower_texcoord_array) {
- lower_texcoord_array(producer, &producer_info);
+ lower_texcoord_array(producer->ir, &producer_info);
}
return;
}
}
if (consumer) {
- consumer_info.get(consumer, 0, NULL);
+ consumer_info.get(consumer->ir, 0, NULL);
if (!producer) {
/* At least eliminate unused gl_TexCoord elements. */
if (consumer_info.lower_texcoord_array) {
- lower_texcoord_array(consumer, &consumer_info);
+ lower_texcoord_array(consumer->ir, &consumer_info);
}
return;
}
}
- /* Eliminate the varyings unused by the other shader. */
+ /* Eliminate the outputs unused by the consumer. */
if (producer_info.lower_texcoord_array ||
producer_info.color_usage ||
producer_info.has_fog) {
- replace_varyings_visitor(producer,
+ replace_varyings_visitor(producer->ir,
&producer_info,
consumer_info.texcoord_usage,
consumer_info.color_usage,
consumer_info.has_fog);
}
+ /* The gl_TexCoord fragment shader inputs can be initialized
+ * by GL_COORD_REPLACE, so we can't eliminate them.
+ *
+ * This doesn't prevent elimination of the gl_TexCoord elements which
+ * are not read by the fragment shader. We want to eliminate those anyway.
+ */
+ if (consumer->Type == GL_FRAGMENT_SHADER) {
+ producer_info.texcoord_usage = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
+ }
+
+ /* Eliminate the inputs uninitialized by the producer. */
if (consumer_info.lower_texcoord_array ||
consumer_info.color_usage ||
consumer_info.has_fog) {
- replace_varyings_visitor(consumer,
+ replace_varyings_visitor(consumer->ir,
&consumer_info,
producer_info.texcoord_usage,
producer_info.color_usage,
diff --git a/mesalib/src/glsl/opt_dead_code_local.cpp b/mesalib/src/glsl/opt_dead_code_local.cpp
index 8c31802a6..42a30b3d8 100644
--- a/mesalib/src/glsl/opt_dead_code_local.cpp
+++ b/mesalib/src/glsl/opt_dead_code_local.cpp
@@ -114,6 +114,23 @@ public:
return visit_continue_with_parent;
}
+ virtual ir_visitor_status visit(ir_emit_vertex *ir)
+ {
+ /* For the purpose of dead code elimination, emitting a vertex counts as
+ * "reading" all of the currently assigned output variables.
+ */
+ foreach_iter(exec_list_iterator, iter, *this->assignments) {
+ assignment_entry *entry = (assignment_entry *)iter.get();
+ if (entry->lhs->mode == ir_var_shader_out) {
+ if (debug)
+ printf("kill %s\n", entry->lhs->name);
+ entry->remove();
+ }
+ }
+
+ return visit_continue;
+ }
+
private:
exec_list *assignments;
};
diff --git a/mesalib/src/mapi/glapi/gen/EXT_framebuffer_object.xml b/mesalib/src/mapi/glapi/gen/EXT_framebuffer_object.xml
index 16c82a4a2..2cf75bc67 100644
--- a/mesalib/src/mapi/glapi/gen/EXT_framebuffer_object.xml
+++ b/mesalib/src/mapi/glapi/gen/EXT_framebuffer_object.xml
@@ -78,7 +78,7 @@
<return type="GLboolean"/>
</function>
- <function name="BindRenderbufferEXT" offset="assign">
+ <function name="BindRenderbufferEXT" offset="assign" deprecated="3.1">
<param name="target" type="GLenum"/>
<param name="renderbuffer" type="GLuint"/>
<glx rop="4316"/>
@@ -112,7 +112,7 @@
<return type="GLboolean"/>
</function>
- <function name="BindFramebufferEXT" offset="assign">
+ <function name="BindFramebufferEXT" offset="assign" deprecated="3.1">
<param name="target" type="GLenum"/>
<param name="framebuffer" type="GLuint"/>
<glx rop="4319"/>
diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c
index 4a3497c9a..60157af98 100644
--- a/mesalib/src/mesa/drivers/common/meta.c
+++ b/mesalib/src/mesa/drivers/common/meta.c
@@ -704,9 +704,14 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
_mesa_LoadIdentity();
_mesa_MatrixMode(GL_PROJECTION);
_mesa_LoadIdentity();
- _mesa_Ortho(0.0, ctx->DrawBuffer->Width,
- 0.0, ctx->DrawBuffer->Height,
- -1.0, 1.0);
+
+ /* glOrtho with width = 0 or height = 0 generates GL_INVALID_VALUE.
+ * This can occur when there is no draw buffer.
+ */
+ if (ctx->DrawBuffer->Width != 0 && ctx->DrawBuffer->Height != 0)
+ _mesa_Ortho(0.0, ctx->DrawBuffer->Width,
+ 0.0, ctx->DrawBuffer->Height,
+ -1.0, 1.0);
}
if (state & MESA_META_CLIP) {
@@ -956,7 +961,7 @@ _mesa_meta_end(struct gl_context *ctx)
if (ctx->Extensions.ARB_vertex_shader)
_mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader);
- if (ctx->Extensions.ARB_geometry_shader4)
+ if (_mesa_has_geometry_shaders(ctx))
_mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB,
save->GeometryShader);
@@ -1879,19 +1884,24 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx,
const GLenum rb_base_format =
_mesa_base_tex_format(ctx, colorReadRb->InternalFormat);
- newTex = alloc_texture(tex, srcW, srcH, rb_base_format);
- setup_copypix_texture(ctx, tex, newTex, srcX, srcY, srcW, srcH,
+ /* Using the exact source rectangle to create the texture does incorrect
+ * linear filtering along the edges. So, allocate the texture extended along
+ * edges by one pixel in x, y directions.
+ */
+ newTex = alloc_texture(tex, srcW + 2, srcH + 2, rb_base_format);
+ setup_copypix_texture(ctx, tex, newTex,
+ srcX - 1, srcY - 1, srcW + 2, srcH + 2,
rb_base_format, filter);
/* texcoords (after texture allocation!) */
{
- verts[0].s = 0.0F;
- verts[0].t = 0.0F;
- verts[1].s = tex->Sright;
- verts[1].t = 0.0F;
- verts[2].s = tex->Sright;
- verts[2].t = tex->Ttop;
- verts[3].s = 0.0F;
- verts[3].t = tex->Ttop;
+ verts[0].s = 1.0F;
+ verts[0].t = 1.0F;
+ verts[1].s = tex->Sright - 1.0F;
+ verts[1].t = 1.0F;
+ verts[2].s = tex->Sright - 1.0F;
+ verts[2].t = tex->Ttop - 1.0F;
+ verts[3].s = 1.0F;
+ verts[3].t = tex->Ttop - 1.0F;
/* upload new vertex data */
_mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c
index 9ed9df4b3..fa520ea90 100644
--- a/mesalib/src/mesa/drivers/dri/common/dri_util.c
+++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c
@@ -52,8 +52,6 @@ PUBLIC const char __dri2ConfigOptions[] =
DRI_CONF_SECTION_END
DRI_CONF_END;
-static const uint __dri2NConfigOptions = 1;
-
/*****************************************************************/
/** \name Screen handling functions */
/*****************************************************************/
@@ -112,7 +110,7 @@ dri2CreateNewScreen(int scrn, int fd,
return NULL;
}
- driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions, __dri2NConfigOptions);
+ driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions);
driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum, "dri2");
return psp;
diff --git a/mesalib/src/mesa/drivers/dri/common/xmlconfig.c b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c
index 5c97c20fc..b95e452f1 100644
--- a/mesalib/src/mesa/drivers/dri/common/xmlconfig.c
+++ b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c
@@ -132,16 +132,6 @@ static GLuint findOption (const driOptionCache *cache, const char *name) {
return hash;
}
-/** \brief Count the real number of options in an option cache */
-static GLuint countOptions (const driOptionCache *cache) {
- GLuint size = 1 << cache->tableSize;
- GLuint i, count = 0;
- for (i = 0; i < size; ++i)
- if (cache->info[i].name)
- count++;
- return count;
-}
-
/** \brief Like strdup but using malloc and with error checking. */
#define XSTRDUP(dest,source) do { \
GLuint len = strlen (source); \
@@ -685,25 +675,18 @@ static void optInfoEndElem (void *userData, const XML_Char *name) {
}
}
-void driParseOptionInfo (driOptionCache *info,
- const char *configOptions, GLuint nConfigOptions) {
+void driParseOptionInfo (driOptionCache *info, const char *configOptions) {
XML_Parser p;
int status;
struct OptInfoData userData;
struct OptInfoData *data = &userData;
- GLuint realNoptions;
-
- /* determine hash table size and allocate memory:
- * 3/2 of the number of options, rounded up, so there remains always
- * at least one free entry. This is needed for detecting undefined
- * options in configuration files without getting a hash table overflow.
- * Round this up to a power of two. */
- GLuint minSize = (nConfigOptions*3 + 1) / 2;
- GLuint size, log2size;
- for (size = 1, log2size = 0; size < minSize; size <<= 1, ++log2size);
- info->tableSize = log2size;
- info->info = calloc(size, sizeof (driOptionInfo));
- info->values = calloc(size, sizeof (driOptionValue));
+
+ /* Make the hash table big enough to fit more than the maximum number of
+ * config options we've ever seen in a driver.
+ */
+ info->tableSize = 6;
+ info->info = calloc(1 << info->tableSize, sizeof (driOptionInfo));
+ info->values = calloc(1 << info->tableSize, sizeof (driOptionValue));
if (info->info == NULL || info->values == NULL) {
fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__);
abort();
@@ -728,17 +711,6 @@ void driParseOptionInfo (driOptionCache *info,
XML_FATAL ("%s.", XML_ErrorString(XML_GetErrorCode(p)));
XML_ParserFree (p);
-
- /* Check if the actual number of options matches nConfigOptions.
- * A mismatch is not fatal (a hash table overflow would be) but we
- * want the driver developer's attention anyway. */
- realNoptions = countOptions (info);
- if (realNoptions != nConfigOptions) {
- fprintf (stderr,
- "Error: nConfigOptions (%u) does not match the actual number of options in\n"
- " __driConfigOptions (%u).\n",
- nConfigOptions, realNoptions);
- }
}
/** \brief Parser context for configuration files. */
diff --git a/mesalib/src/mesa/drivers/dri/common/xmlconfig.h b/mesalib/src/mesa/drivers/dri/common/xmlconfig.h
index c363af764..d0ad42c19 100644
--- a/mesalib/src/mesa/drivers/dri/common/xmlconfig.h
+++ b/mesalib/src/mesa/drivers/dri/common/xmlconfig.h
@@ -76,7 +76,6 @@ typedef struct driOptionCache {
GLuint tableSize;
/**< \brief Size of the arrays
*
- * Depending on the hash function this may differ from __driNConfigOptions.
* In the current implementation it's not actually a size but log2(size).
* The value is the same in the screen and all contexts. */
} driOptionCache;
@@ -87,14 +86,13 @@ typedef struct driOptionCache {
*
* \param info pointer to a driOptionCache that will store the option info
* \param configOptions XML document describing available configuration opts
- * \param nConfigOptions number of options, used to choose a hash table size
*
* For the option information to be available to external configuration tools
* it must be a public symbol __driConfigOptions. It is also passed as a
* parameter to driParseOptionInfo in order to avoid driver-independent code
* depending on symbols in driver-specific code. */
void driParseOptionInfo (driOptionCache *info,
- const char *configOptions, GLuint nConfigOptions);
+ const char *configOptions);
/** \brief Initialize option cache from info and parse configuration files
*
* To be called in <driver>CreateContext. screenNum and driverName select
diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c
index 7ab8e305d..243bb89d1 100644
--- a/mesalib/src/mesa/main/api_validate.c
+++ b/mesalib/src/mesa/main/api_validate.c
@@ -222,7 +222,7 @@ _mesa_is_valid_prim_mode(struct gl_context *ctx, GLenum mode)
case GL_LINE_STRIP_ADJACENCY:
case GL_TRIANGLES_ADJACENCY:
case GL_TRIANGLE_STRIP_ADJACENCY:
- return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;
+ return _mesa_has_geometry_shaders(ctx);
default:
return false;
}
@@ -245,6 +245,74 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
return GL_FALSE;
}
+ /* From the ARB_geometry_shader4 spec:
+ *
+ * The error INVALID_OPERATION is generated if Begin, or any command that
+ * implicitly calls Begin, is called when a geometry shader is active and:
+ *
+ * * the input primitive type of the current geometry shader is
+ * POINTS and <mode> is not POINTS,
+ *
+ * * the input primitive type of the current geometry shader is
+ * LINES and <mode> is not LINES, LINE_STRIP, or LINE_LOOP,
+ *
+ * * the input primitive type of the current geometry shader is
+ * TRIANGLES and <mode> is not TRIANGLES, TRIANGLE_STRIP or
+ * TRIANGLE_FAN,
+ *
+ * * the input primitive type of the current geometry shader is
+ * LINES_ADJACENCY_ARB and <mode> is not LINES_ADJACENCY_ARB or
+ * LINE_STRIP_ADJACENCY_ARB, or
+ *
+ * * the input primitive type of the current geometry shader is
+ * TRIANGLES_ADJACENCY_ARB and <mode> is not
+ * TRIANGLES_ADJACENCY_ARB or TRIANGLE_STRIP_ADJACENCY_ARB.
+ *
+ */
+ if (ctx->Shader.CurrentGeometryProgram) {
+ const GLenum geom_mode =
+ ctx->Shader.CurrentGeometryProgram->Geom.InputType;
+ switch (mode) {
+ case GL_POINTS:
+ valid_enum = (geom_mode == GL_POINTS);
+ break;
+ case GL_LINES:
+ case GL_LINE_LOOP:
+ case GL_LINE_STRIP:
+ valid_enum = (geom_mode == GL_LINES);
+ break;
+ case GL_TRIANGLES:
+ case GL_TRIANGLE_STRIP:
+ case GL_TRIANGLE_FAN:
+ valid_enum = (geom_mode == GL_TRIANGLES);
+ break;
+ case GL_QUADS:
+ case GL_QUAD_STRIP:
+ case GL_POLYGON:
+ valid_enum = false;
+ break;
+ case GL_LINES_ADJACENCY:
+ case GL_LINE_STRIP_ADJACENCY:
+ valid_enum = (geom_mode == GL_LINES_ADJACENCY);
+ break;
+ case GL_TRIANGLES_ADJACENCY:
+ case GL_TRIANGLE_STRIP_ADJACENCY:
+ valid_enum = (geom_mode == GL_TRIANGLES_ADJACENCY);
+ break;
+ default:
+ valid_enum = false;
+ break;
+ }
+ if (!valid_enum) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(mode=%s vs geometry shader input %s)",
+ name,
+ _mesa_lookup_prim_by_nr(mode),
+ _mesa_lookup_prim_by_nr(geom_mode));
+ return GL_FALSE;
+ }
+ }
+
/* From the GL_EXT_transform_feedback spec:
*
* "The error INVALID_OPERATION is generated if Begin, or any command
diff --git a/mesalib/src/mesa/main/context.h b/mesalib/src/mesa/main/context.h
index 8872be1f4..792ab4cd5 100644
--- a/mesalib/src/mesa/main/context.h
+++ b/mesalib/src/mesa/main/context.h
@@ -312,6 +312,17 @@ _mesa_is_gles3(const struct gl_context *ctx)
}
+/**
+ * Checks if the context supports geometry shaders.
+ */
+static inline GLboolean
+_mesa_has_geometry_shaders(const struct gl_context *ctx)
+{
+ return _mesa_is_desktop_gl(ctx) &&
+ (ctx->Version >= 32 || ctx->Extensions.ARB_geometry_shader4);
+}
+
+
#ifdef __cplusplus
}
#endif
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index bf7e85c88..1034c7a71 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -343,6 +343,28 @@ _mesa_remove_attachment(struct gl_context *ctx,
}
/**
+ * Verify a couple error conditions that will lead to an incomplete FBO and
+ * may cause problems for the driver's RenderTexture path.
+ */
+static bool
+driver_RenderTexture_is_safe(const struct gl_renderbuffer_attachment *att)
+{
+ const struct gl_texture_image *const texImage =
+ att->Texture->Image[att->CubeMapFace][att->TextureLevel];
+
+ if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
+ return false;
+
+ if ((texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY
+ && att->Zoffset >= texImage->Height)
+ || (texImage->TexObject->Target != GL_TEXTURE_1D_ARRAY
+ && att->Zoffset >= texImage->Depth))
+ return false;
+
+ return true;
+}
+
+/**
* Create a renderbuffer which will be set up by the driver to wrap the
* texture image slice.
*
@@ -363,8 +385,6 @@ _mesa_update_texture_renderbuffer(struct gl_context *ctx,
struct gl_renderbuffer *rb;
texImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
- if (!texImage)
- return;
rb = att->Renderbuffer;
if (!rb) {
@@ -383,6 +403,9 @@ _mesa_update_texture_renderbuffer(struct gl_context *ctx,
rb->NeedsFinishRenderTexture = ctx->Driver.FinishRenderTexture != NULL;
}
+ if (!texImage)
+ return;
+
rb->_BaseFormat = texImage->_BaseFormat;
rb->Format = texImage->TexFormat;
rb->InternalFormat = texImage->InternalFormat;
@@ -391,7 +414,8 @@ _mesa_update_texture_renderbuffer(struct gl_context *ctx,
rb->NumSamples = texImage->NumSamples;
rb->TexImage = texImage;
- ctx->Driver.RenderTexture(ctx, fb, att);
+ if (driver_RenderTexture_is_safe(att))
+ ctx->Driver.RenderTexture(ctx, fb, att);
}
/**
@@ -703,15 +727,39 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format,
}
if (texImage->Width < 1 || texImage->Height < 1) {
att_incomplete("teximage width/height=0");
- printf("texobj = %u\n", texObj->Name);
- printf("level = %d\n", att->TextureLevel);
att->Complete = GL_FALSE;
return;
}
- if (texObj->Target == GL_TEXTURE_3D && att->Zoffset >= texImage->Depth) {
- att_incomplete("bad z offset");
- att->Complete = GL_FALSE;
- return;
+
+ switch (texObj->Target) {
+ case GL_TEXTURE_3D:
+ if (att->Zoffset >= texImage->Depth) {
+ att_incomplete("bad z offset");
+ att->Complete = GL_FALSE;
+ return;
+ }
+ break;
+ case GL_TEXTURE_1D_ARRAY:
+ if (att->Zoffset >= texImage->Height) {
+ att_incomplete("bad 1D-array layer");
+ att->Complete = GL_FALSE;
+ return;
+ }
+ break;
+ case GL_TEXTURE_2D_ARRAY:
+ if (att->Zoffset >= texImage->Depth) {
+ att_incomplete("bad 2D-array layer");
+ att->Complete = GL_FALSE;
+ return;
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ if (att->Zoffset >= texImage->Depth) {
+ att_incomplete("bad cube-array layer");
+ att->Complete = GL_FALSE;
+ return;
+ }
+ break;
}
baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
@@ -1104,8 +1152,8 @@ _mesa_IsRenderbuffer(GLuint renderbuffer)
}
-void GLAPIENTRY
-_mesa_BindRenderbuffer(GLenum target, GLuint renderbuffer)
+static void
+bind_renderbuffer(GLenum target, GLuint renderbuffer, bool allow_user_names)
{
struct gl_renderbuffer *newRb;
GET_CURRENT_CONTEXT(ctx);
@@ -1125,9 +1173,7 @@ _mesa_BindRenderbuffer(GLenum target, GLuint renderbuffer)
/* ID was reserved, but no real renderbuffer object made yet */
newRb = NULL;
}
- else if (!newRb
- && _mesa_is_desktop_gl(ctx)
- && ctx->Extensions.ARB_framebuffer_object) {
+ else if (!newRb && !allow_user_names) {
/* All RB IDs must be Gen'd */
_mesa_error(ctx, GL_INVALID_OPERATION, "glBindRenderbuffer(buffer)");
return;
@@ -1154,32 +1200,68 @@ _mesa_BindRenderbuffer(GLenum target, GLuint renderbuffer)
_mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb);
}
+void GLAPIENTRY
+_mesa_BindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ /* OpenGL ES glBindRenderbuffer and glBindRenderbufferOES use this same
+ * entry point, but they allow the use of user-generated names.
+ */
+ bind_renderbuffer(target, renderbuffer, _mesa_is_gles(ctx));
+}
void GLAPIENTRY
_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
{
- _mesa_BindRenderbuffer(target, renderbuffer);
+ /* This function should not be in the dispatch table for core profile /
+ * OpenGL 3.1, so execution should never get here in those cases -- no
+ * need for an explicit test.
+ */
+ bind_renderbuffer(target, renderbuffer, true);
}
/**
- * If the given renderbuffer is anywhere attached to the framebuffer, detach
- * the renderbuffer.
- * This is used when a renderbuffer object is deleted.
- * The spec calls for unbinding.
+ * Remove the specified renderbuffer or texture from any attachment point in
+ * the framebuffer.
+ *
+ * \returns
+ * \c true if the renderbuffer was detached from an attachment point. \c
+ * false otherwise.
*/
-static void
-detach_renderbuffer(struct gl_context *ctx,
- struct gl_framebuffer *fb,
- struct gl_renderbuffer *rb)
+bool
+_mesa_detach_renderbuffer(struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ const void *att)
{
- GLuint i;
+ unsigned i;
+ bool progress = false;
+
for (i = 0; i < BUFFER_COUNT; i++) {
- if (fb->Attachment[i].Renderbuffer == rb) {
+ if (fb->Attachment[i].Texture == att
+ || fb->Attachment[i].Renderbuffer == att) {
_mesa_remove_attachment(ctx, &fb->Attachment[i]);
+ progress = true;
}
}
- invalidate_framebuffer(fb);
+
+ /* Section 4.4.4 (Framebuffer Completeness), subsection "Whole Framebuffer
+ * Completeness," of the OpenGL 3.1 spec says:
+ *
+ * "Performing any of the following actions may change whether the
+ * framebuffer is considered complete or incomplete:
+ *
+ * ...
+ *
+ * - Deleting, with DeleteTextures or DeleteRenderbuffers, an object
+ * containing an image that is attached to a framebuffer object
+ * that is bound to the framebuffer."
+ */
+ if (progress)
+ invalidate_framebuffer(fb);
+
+ return progress;
}
@@ -1203,12 +1285,29 @@ _mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
_mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
}
+ /* Section 4.4.2 (Attaching Images to Framebuffer Objects),
+ * subsection "Attaching Renderbuffer Images to a Framebuffer," of
+ * the OpenGL 3.1 spec says:
+ *
+ * "If a renderbuffer object is deleted while its image is
+ * attached to one or more attachment points in the currently
+ * bound framebuffer, then it is as if FramebufferRenderbuffer
+ * had been called, with a renderbuffer of 0, for each
+ * attachment point to which this image was attached in the
+ * currently bound framebuffer. In other words, this
+ * renderbuffer image is first detached from all attachment
+ * points in the currently bound framebuffer. Note that the
+ * renderbuffer image is specifically not detached from any
+ * non-bound framebuffers. Detaching the image from any
+ * non-bound framebuffers is the responsibility of the
+ * application.
+ */
if (_mesa_is_user_fbo(ctx->DrawBuffer)) {
- detach_renderbuffer(ctx, ctx->DrawBuffer, rb);
+ _mesa_detach_renderbuffer(ctx, ctx->DrawBuffer, rb);
}
if (_mesa_is_user_fbo(ctx->ReadBuffer)
&& ctx->ReadBuffer != ctx->DrawBuffer) {
- detach_renderbuffer(ctx, ctx->ReadBuffer, rb);
+ _mesa_detach_renderbuffer(ctx, ctx->ReadBuffer, rb);
}
/* Remove from hash table immediately, to free the ID.
@@ -1875,7 +1974,8 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
for (i = 0; i < BUFFER_COUNT; i++) {
struct gl_renderbuffer_attachment *att = fb->Attachment + i;
- if (att->Texture && att->Renderbuffer->TexImage) {
+ if (att->Texture && att->Renderbuffer->TexImage
+ && driver_RenderTexture_is_safe(att)) {
ctx->Driver.RenderTexture(ctx, fb, att);
}
}
@@ -1906,8 +2006,8 @@ check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
}
-void GLAPIENTRY
-_mesa_BindFramebuffer(GLenum target, GLuint framebuffer)
+static void
+bind_framebuffer(GLenum target, GLuint framebuffer, bool allow_user_names)
{
struct gl_framebuffer *newDrawFb, *newReadFb;
struct gl_framebuffer *oldDrawFb, *oldReadFb;
@@ -1953,9 +2053,7 @@ _mesa_BindFramebuffer(GLenum target, GLuint framebuffer)
/* ID was reserved, but no real framebuffer object made yet */
newDrawFb = NULL;
}
- else if (!newDrawFb
- && _mesa_is_desktop_gl(ctx)
- && ctx->Extensions.ARB_framebuffer_object) {
+ else if (!newDrawFb && !allow_user_names) {
/* All FBO IDs must be Gen'd */
_mesa_error(ctx, GL_INVALID_OPERATION, "glBindFramebuffer(buffer)");
return;
@@ -2033,12 +2131,25 @@ _mesa_BindFramebuffer(GLenum target, GLuint framebuffer)
}
void GLAPIENTRY
-_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
+_mesa_BindFramebuffer(GLenum target, GLuint framebuffer)
{
- _mesa_BindFramebuffer(target, framebuffer);
-}
+ GET_CURRENT_CONTEXT(ctx);
+ /* OpenGL ES glBindFramebuffer and glBindFramebufferOES use this same entry
+ * point, but they allow the use of user-generated names.
+ */
+ bind_framebuffer(target, framebuffer, _mesa_is_gles(ctx));
+}
+void GLAPIENTRY
+_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
+{
+ /* This function should not be in the dispatch table for core profile /
+ * OpenGL 3.1, so execution should never get here in those cases -- no
+ * need for an explicit test.
+ */
+ bind_framebuffer(target, framebuffer, true);
+}
void GLAPIENTRY
_mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
@@ -2476,7 +2587,7 @@ _mesa_FramebufferTexture(GLenum target, GLenum attachment,
{
GET_CURRENT_CONTEXT(ctx);
- if (ctx->Version >= 32 || ctx->Extensions.ARB_geometry_shader4) {
+ if (_mesa_has_geometry_shaders(ctx)) {
framebuffer_texture(ctx, "Layer", target, attachment, 0, texture,
level, 0, GL_TRUE);
} else {
diff --git a/mesalib/src/mesa/main/fbobject.h b/mesalib/src/mesa/main/fbobject.h
index 0a2a5cc59..ab138cfff 100644
--- a/mesalib/src/mesa/main/fbobject.h
+++ b/mesalib/src/mesa/main/fbobject.h
@@ -28,6 +28,7 @@
#include "compiler.h"
#include "glheader.h"
+#include <stdbool.h>
struct gl_context;
struct gl_texture_object;
@@ -113,6 +114,11 @@ _mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat);
extern GLenum
_mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat);
+extern bool
+_mesa_detach_renderbuffer(struct gl_context *ctx,
+ struct gl_framebuffer *fb,
+ const void *att);
+
extern GLboolean GLAPIENTRY
_mesa_IsRenderbuffer(GLuint renderbuffer);
diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c
index 0b33fa49b..09b008a07 100644
--- a/mesalib/src/mesa/main/get.c
+++ b/mesalib/src/mesa/main/get.c
@@ -989,7 +989,7 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d
case EXTRA_EXT_UBO_GS4:
api_check = GL_TRUE;
api_found = (ctx->Extensions.ARB_uniform_buffer_object &&
- ctx->Extensions.ARB_geometry_shader4);
+ _mesa_has_geometry_shaders(ctx));
break;
case EXTRA_END:
break;
diff --git a/mesalib/src/mesa/main/lines.c b/mesalib/src/mesa/main/lines.c
index 0df9d66b0..3c08ed2e7 100644
--- a/mesalib/src/mesa/main/lines.c
+++ b/mesalib/src/mesa/main/lines.c
@@ -62,7 +62,8 @@ _mesa_LineWidth( GLfloat width )
*/
if (ctx->API == API_OPENGL_CORE
&& ((ctx->Const.ContextFlags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
- != 0)) {
+ != 0)
+ && width > 1.0) {
_mesa_error( ctx, GL_INVALID_VALUE, "glLineWidth" );
return;
}
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 5bb680745..5f9b7f983 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -1152,31 +1152,32 @@ struct gl_sampler_object
*/
struct gl_texture_object
{
- _glthread_Mutex Mutex; /**< for thread safety */
- GLint RefCount; /**< reference count */
- GLuint Name; /**< the user-visible texture object ID */
- GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */
+ _glthread_Mutex Mutex; /**< for thread safety */
+ GLint RefCount; /**< reference count */
+ GLuint Name; /**< the user-visible texture object ID */
+ GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */
struct gl_sampler_object Sampler;
- GLenum DepthMode; /**< GL_ARB_depth_texture */
-
- GLfloat Priority; /**< in [0,1] */
- GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */
- GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */
- GLint ImmutableLevels; /**< ES 3.0 / ARB_texture_view */
- GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */
- GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */
- GLint CropRect[4]; /**< GL_OES_draw_texture */
- GLenum Swizzle[4]; /**< GL_EXT_texture_swizzle */
- GLuint _Swizzle; /**< same as Swizzle, but SWIZZLE_* format */
- GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */
- GLboolean _BaseComplete; /**< Is the base texture level valid? */
- GLboolean _MipmapComplete; /**< Is the whole mipmap valid? */
- GLboolean _IsIntegerFormat; /**< Does the texture store integer values? */
- GLboolean _RenderToTexture; /**< Any rendering to this texture? */
- GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
- GLboolean Immutable; /**< GL_ARB_texture_storage */
+ GLenum DepthMode; /**< GL_ARB_depth_texture */
+
+ GLfloat Priority; /**< in [0,1] */
+ GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */
+ GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */
+ GLint ImmutableLevels; /**< ES 3.0 / ARB_texture_view */
+ GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */
+ GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - p in spec) */
+ GLint CropRect[4]; /**< GL_OES_draw_texture */
+ GLenum Swizzle[4]; /**< GL_EXT_texture_swizzle */
+ GLuint _Swizzle; /**< same as Swizzle, but SWIZZLE_* format */
+ GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */
+ GLboolean _BaseComplete; /**< Is the base texture level valid? */
+ GLboolean _MipmapComplete; /**< Is the whole mipmap valid? */
+ GLboolean _IsIntegerFormat; /**< Does the texture store integer values? */
+ GLboolean _RenderToTexture; /**< Any rendering to this texture? */
+ GLboolean Purgeable; /**< Is the buffer purgeable under memory
+ pressure? */
+ GLboolean Immutable; /**< GL_ARB_texture_storage */
/** Actual texture images, indexed by [cube face] and [mipmap level] */
struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS];
@@ -1851,7 +1852,7 @@ struct gl_program
GLuint Id;
GLubyte *String; /**< Null-terminated program text */
GLint RefCount;
- GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB */
+ GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_GEOMETRY_PROGRAM_NV */
GLenum Format; /**< String encoding format */
struct prog_instruction *Instructions;
@@ -1918,6 +1919,7 @@ struct gl_geometry_program
{
struct gl_program Base; /**< base class */
+ GLint VerticesIn;
GLint VerticesOut;
GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
@@ -2169,6 +2171,24 @@ struct gl_shader
/** Shaders containing built-in functions that are used for linking. */
struct gl_shader *builtins_to_link[16];
unsigned num_builtins_to_link;
+
+ /**
+ * Geometry shader state from GLSL 1.50 layout qualifiers.
+ */
+ struct {
+ GLint VerticesOut;
+ /**
+ * GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES, or
+ * GL_TRIANGLES_ADJACENCY, or PRIM_UNKNOWN if it's not set in this
+ * shader.
+ */
+ GLenum InputType;
+ /**
+ * GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP, or PRIM_UNKNOWN if
+ * it's not set in this shader.
+ */
+ GLenum OutputType;
+ } Geom;
};
@@ -2318,17 +2338,25 @@ struct gl_shader_program
/** Post-link gl_FragDepth layout for ARB_conservative_depth. */
enum gl_frag_depth_layout FragDepthLayout;
- /** Geometry shader state - copied into gl_geometry_program at link time */
+ /**
+ * Geometry shader state - copied into gl_geometry_program by
+ * _mesa_copy_linked_program_data().
+ */
struct {
+ GLint VerticesIn;
GLint VerticesOut;
GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
} Geom;
- /** Vertex shader state - copied into gl_vertex_program at link time */
+ /** Vertex shader state */
struct {
- GLboolean UsesClipDistance; /**< True if gl_ClipDistance is written to. */
+ /**
+ * True if gl_ClipDistance is written to. Copied into gl_vertex_program
+ * by _mesa_copy_linked_program_data().
+ */
+ GLboolean UsesClipDistance;
GLuint ClipDistanceArraySize; /**< Size of the gl_ClipDistance array, or
0 if not present. */
} Vert;
diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c
index c349b0cb5..d184b114c 100644
--- a/mesalib/src/mesa/main/shaderapi.c
+++ b/mesalib/src/mesa/main/shaderapi.c
@@ -179,7 +179,7 @@ validate_shader_target(const struct gl_context *ctx, GLenum type)
case GL_VERTEX_SHADER:
return ctx->Extensions.ARB_vertex_shader;
case GL_GEOMETRY_SHADER_ARB:
- return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;
+ return _mesa_has_geometry_shaders(ctx);
default:
return false;
}
@@ -478,8 +478,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param
/* Are geometry shaders available in this context?
*/
- const bool has_gs =
- _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;
+ const bool has_gs = _mesa_has_geometry_shaders(ctx);
/* Are uniform buffer objects available in this context?
*/
@@ -743,6 +742,12 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj)
if (!sh)
return;
+ /* Geometry shaders are not yet fully supported, so issue a warning message
+ * if we're compiling one.
+ */
+ if (sh->Type == GL_GEOMETRY_SHADER)
+ printf("WARNING: Geometry shader support is currently experimental.\n");
+
options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(sh->Type)];
/* set default pragma state for shader */
@@ -1635,10 +1640,10 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
break;
- if (value < 1 ||
+ if (value < 0 ||
(unsigned) value > ctx->Const.MaxGeometryOutputVertices) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d",
+ "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d)",
value);
return;
}
@@ -1658,7 +1663,7 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
break;
default:
_mesa_error(ctx, GL_INVALID_VALUE,
- "glProgramParameteri(geometry input type = %s",
+ "glProgramParameteri(geometry input type = %s)",
_mesa_lookup_enum_by_nr(value));
return;
}
@@ -1675,7 +1680,7 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
break;
default:
_mesa_error(ctx, GL_INVALID_VALUE,
- "glProgramParameteri(geometry output type = %s",
+ "glProgramParameteri(geometry output type = %s)",
_mesa_lookup_enum_by_nr(value));
return;
}
@@ -1843,3 +1848,32 @@ _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
return program;
}
+
+
+/**
+ * Copy program-specific data generated by linking from the gl_shader_program
+ * object to a specific gl_program object.
+ */
+void
+_mesa_copy_linked_program_data(gl_shader_type type,
+ const struct gl_shader_program *src,
+ struct gl_program *dst)
+{
+ switch (type) {
+ case MESA_SHADER_VERTEX: {
+ struct gl_vertex_program *dst_vp = (struct gl_vertex_program *) dst;
+ dst_vp->UsesClipDistance = src->Vert.UsesClipDistance;
+ }
+ break;
+ case MESA_SHADER_GEOMETRY: {
+ struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) dst;
+ dst_gp->VerticesIn = src->Geom.VerticesIn;
+ dst_gp->VerticesOut = src->Geom.VerticesOut;
+ dst_gp->InputType = src->Geom.InputType;
+ dst_gp->OutputType = src->Geom.OutputType;
+ }
+ break;
+ default:
+ break;
+ }
+}
diff --git a/mesalib/src/mesa/main/shaderapi.h b/mesalib/src/mesa/main/shaderapi.h
index 1cd4ffcea..fe58e7de9 100644
--- a/mesalib/src/mesa/main/shaderapi.h
+++ b/mesalib/src/mesa/main/shaderapi.h
@@ -210,6 +210,11 @@ _mesa_ActiveProgramEXT(GLuint program);
extern GLuint GLAPIENTRY
_mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string);
+extern void
+_mesa_copy_linked_program_data(gl_shader_type type,
+ const struct gl_shader_program *src,
+ struct gl_program *dst);
+
#ifdef __cplusplus
}
diff --git a/mesalib/src/mesa/main/shared.c b/mesalib/src/mesa/main/shared.c
index 5ef88098f..2f73cf3ca 100644
--- a/mesalib/src/mesa/main/shared.c
+++ b/mesalib/src/mesa/main/shared.c
@@ -218,7 +218,8 @@ delete_shader_cb(GLuint id, void *data, void *userData)
{
struct gl_context *ctx = (struct gl_context *) userData;
struct gl_shader *sh = (struct gl_shader *) data;
- if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
+ if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER ||
+ sh->Type == GL_GEOMETRY_SHADER) {
ctx->Driver.DeleteShader(ctx, sh);
}
else {
diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c
index 334dee77b..7c8f04db9 100644
--- a/mesalib/src/mesa/main/texobj.c
+++ b/mesalib/src/mesa/main/texobj.c
@@ -548,12 +548,13 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
ASSERT(maxLevels > 0);
- t->_MaxLevel =
- baseLevel + baseImage->MaxNumLevels - 1; /* 'p' in the GL spec */
- t->_MaxLevel = MIN2(t->_MaxLevel, t->MaxLevel);
- t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1); /* 'q' in the GL spec */
+ t->_MaxLevel = MIN3(t->MaxLevel,
+ /* 'p' in the GL spec */
+ baseLevel + baseImage->MaxNumLevels - 1,
+ /* 'q' in the GL spec */
+ maxLevels - 1);
- /* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */
+ /* Compute _MaxLambda = q - p in the spec used during mipmapping */
t->_MaxLambda = (GLfloat) (t->_MaxLevel - baseLevel);
if (t->Immutable) {
@@ -1040,23 +1041,35 @@ static void
unbind_texobj_from_fbo(struct gl_context *ctx,
struct gl_texture_object *texObj)
{
- const GLuint n = (ctx->DrawBuffer == ctx->ReadBuffer) ? 1 : 2;
- GLuint i;
+ bool progress = false;
- for (i = 0; i < n; i++) {
- struct gl_framebuffer *fb = (i == 0) ? ctx->DrawBuffer : ctx->ReadBuffer;
- if (_mesa_is_user_fbo(fb)) {
- GLuint j;
- for (j = 0; j < BUFFER_COUNT; j++) {
- if (fb->Attachment[j].Type == GL_TEXTURE &&
- fb->Attachment[j].Texture == texObj) {
- /* Vertices are already flushed by _mesa_DeleteTextures */
- ctx->NewState |= _NEW_BUFFERS;
- _mesa_remove_attachment(ctx, fb->Attachment + j);
- }
- }
- }
+ /* Section 4.4.2 (Attaching Images to Framebuffer Objects), subsection
+ * "Attaching Texture Images to a Framebuffer," of the OpenGL 3.1 spec
+ * says:
+ *
+ * "If a texture object is deleted while its image is attached to one
+ * or more attachment points in the currently bound framebuffer, then
+ * it is as if FramebufferTexture* had been called, with a texture of
+ * zero, for each attachment point to which this image was attached in
+ * the currently bound framebuffer. In other words, this texture image
+ * is first detached from all attachment points in the currently bound
+ * framebuffer. Note that the texture image is specifically not
+ * detached from any other framebuffer objects. Detaching the texture
+ * image from any other framebuffer objects is the responsibility of
+ * the application."
+ */
+ if (_mesa_is_user_fbo(ctx->DrawBuffer)) {
+ progress = _mesa_detach_renderbuffer(ctx, ctx->DrawBuffer, texObj);
}
+ if (_mesa_is_user_fbo(ctx->ReadBuffer)
+ && ctx->ReadBuffer != ctx->DrawBuffer) {
+ progress = _mesa_detach_renderbuffer(ctx, ctx->ReadBuffer, texObj)
+ || progress;
+ }
+
+ if (progress)
+ /* Vertices are already flushed by _mesa_DeleteTextures */
+ ctx->NewState |= _NEW_BUFFERS;
}
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index 32109951c..757ae80ec 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -386,7 +386,13 @@ set_tex_parameteri(struct gl_context *ctx,
return GL_FALSE;
}
incomplete(ctx, texObj);
- texObj->BaseLevel = params[0];
+
+ /** See note about ARB_texture_storage below */
+ if (texObj->Immutable)
+ texObj->BaseLevel = MIN2(texObj->ImmutableLevels - 1, params[0]);
+ else
+ texObj->BaseLevel = params[0];
+
return GL_TRUE;
case GL_TEXTURE_MAX_LEVEL:
@@ -399,7 +405,19 @@ set_tex_parameteri(struct gl_context *ctx,
return GL_FALSE;
}
incomplete(ctx, texObj);
- texObj->MaxLevel = params[0];
+
+ /** From ARB_texture_storage:
+ * However, if TEXTURE_IMMUTABLE_FORMAT is TRUE, then level_base is
+ * clamped to the range [0, <levels> - 1] and level_max is then clamped to
+ * the range [level_base, <levels> - 1], where <levels> is the parameter
+ * passed the call to TexStorage* for the texture object.
+ */
+ if (texObj->Immutable)
+ texObj->MaxLevel = CLAMP(params[0], texObj->BaseLevel,
+ texObj->ImmutableLevels - 1);
+ else
+ texObj->MaxLevel = params[0];
+
return GL_TRUE;
case GL_GENERATE_MIPMAP_SGIS:
diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c
index afff01359..dad69a8f6 100644
--- a/mesalib/src/mesa/main/texstate.c
+++ b/mesalib/src/mesa/main/texstate.c
@@ -528,6 +528,7 @@ update_texture_state( struct gl_context *ctx )
GLuint unit;
struct gl_program *fprog = NULL;
struct gl_program *vprog = NULL;
+ struct gl_program *gprog = NULL;
GLbitfield enabledFragUnits = 0x0;
if (ctx->Shader.CurrentVertexProgram &&
@@ -535,6 +536,11 @@ update_texture_state( struct gl_context *ctx )
vprog = ctx->Shader.CurrentVertexProgram->_LinkedShaders[MESA_SHADER_VERTEX]->Program;
}
+ if (ctx->Shader.CurrentGeometryProgram &&
+ ctx->Shader.CurrentGeometryProgram->LinkStatus) {
+ gprog = ctx->Shader.CurrentGeometryProgram->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program;
+ }
+
if (ctx->Shader.CurrentFragmentProgram &&
ctx->Shader.CurrentFragmentProgram->LinkStatus) {
fprog = ctx->Shader.CurrentFragmentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program;
@@ -543,10 +549,6 @@ update_texture_state( struct gl_context *ctx )
fprog = &ctx->FragmentProgram.Current->Base;
}
- /* FINISHME: Geometry shader texture accesses should also be considered
- * FINISHME: here.
- */
-
/* TODO: only set this if there are actual changes */
ctx->NewState |= _NEW_TEXTURE;
@@ -562,6 +564,7 @@ update_texture_state( struct gl_context *ctx )
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
GLbitfield enabledVertTargets = 0x0;
GLbitfield enabledFragTargets = 0x0;
+ GLbitfield enabledGeomTargets = 0x0;
GLbitfield enabledTargets = 0x0;
GLuint texIndex;
@@ -575,6 +578,10 @@ update_texture_state( struct gl_context *ctx )
enabledVertTargets |= vprog->TexturesUsed[unit];
}
+ if (gprog) {
+ enabledGeomTargets |= gprog->TexturesUsed[unit];
+ }
+
if (fprog) {
enabledFragTargets |= fprog->TexturesUsed[unit];
}
@@ -583,7 +590,8 @@ update_texture_state( struct gl_context *ctx )
enabledFragTargets |= texUnit->Enabled;
}
- enabledTargets = enabledVertTargets | enabledFragTargets;
+ enabledTargets = enabledVertTargets | enabledFragTargets |
+ enabledGeomTargets;
texUnit->_ReallyEnabled = 0x0;
diff --git a/mesalib/src/mesa/main/varray.c b/mesalib/src/mesa/main/varray.c
index 529d93324..dee476abb 100644
--- a/mesalib/src/mesa/main/varray.c
+++ b/mesalib/src/mesa/main/varray.c
@@ -196,6 +196,16 @@ update_array(struct gl_context *ctx,
if (ctx->Extensions.EXT_vertex_array_bgra &&
sizeMax == BGRA_OR_4 &&
size == GL_BGRA) {
+ /* Page 298 of the PDF of the OpenGL 4.3 (Core Profile) spec says:
+ *
+ * "An INVALID_OPERATION error is generated under any of the following
+ * conditions:
+ * ...
+ * • size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV
+ * or UNSIGNED_INT_2_10_10_10_REV;
+ * ...
+ * • size is BGRA and normalized is FALSE;"
+ */
GLboolean bgra_error = GL_FALSE;
if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) {
@@ -207,9 +217,17 @@ update_array(struct gl_context *ctx,
bgra_error = GL_TRUE;
if (bgra_error) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(GL_BGRA/GLubyte)", func);
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=GL_BGRA and type=%s)",
+ func, _mesa_lookup_enum_by_nr(type));
return;
}
+
+ if (!normalized) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(size=GL_BGRA and normalized=GL_FALSE)", func);
+ return;
+ }
+
format = GL_BGRA;
size = 4;
}
diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c
index ab9b14c02..55411faf8 100644
--- a/mesalib/src/mesa/main/version.c
+++ b/mesalib/src/mesa/main/version.c
@@ -262,7 +262,6 @@ compute_version(struct gl_context *ctx)
ctx->Extensions.ARB_depth_clamp &&
ctx->Extensions.ARB_draw_elements_base_vertex &&
ctx->Extensions.ARB_fragment_coord_conventions &&
- ctx->Extensions.ARB_geometry_shader4 &&
ctx->Extensions.EXT_provoking_vertex &&
ctx->Extensions.ARB_seamless_cube_map &&
ctx->Extensions.ARB_sync &&
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index f0fc1b9b1..f612f41ba 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -265,6 +265,8 @@ public:
virtual void visit(ir_discard *);
virtual void visit(ir_texture *);
virtual void visit(ir_if *);
+ virtual void visit(ir_emit_vertex *);
+ virtual void visit(ir_end_primitive *);
/*@}*/
src_reg result;
@@ -2252,6 +2254,18 @@ ir_to_mesa_visitor::visit(ir_if *ir)
if_inst = emit(ir->condition, OPCODE_ENDIF);
}
+void
+ir_to_mesa_visitor::visit(ir_emit_vertex *ir)
+{
+ assert(!"Geometry shaders not supported.");
+}
+
+void
+ir_to_mesa_visitor::visit(ir_end_primitive *ir)
+{
+ assert(!"Geometry shaders not supported.");
+}
+
ir_to_mesa_visitor::ir_to_mesa_visitor()
{
result.file = PROGRAM_UNDEFINED;
@@ -2961,7 +2975,7 @@ get_mesa_program(struct gl_context *ctx,
*/
mesa_instructions = NULL;
- do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER);
+ do_set_program_inouts(shader->ir, prog, shader->Type);
prog->SamplersUsed = shader->active_samplers;
prog->ShadowSamplers = shader->shadow_samplers;
@@ -3073,10 +3087,7 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
if (linked_prog) {
- if (i == MESA_SHADER_VERTEX) {
- ((struct gl_vertex_program *)linked_prog)->UsesClipDistance
- = prog->Vert.UsesClipDistance;
- }
+ _mesa_copy_linked_program_data((gl_shader_type) i, prog, linked_prog);
_mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program,
linked_prog);
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 3dfd5e5b3..4e29e4500 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -369,6 +369,8 @@ public:
virtual void visit(ir_discard *);
virtual void visit(ir_texture *);
virtual void visit(ir_if *);
+ virtual void visit(ir_emit_vertex *);
+ virtual void visit(ir_end_primitive *);
/*@}*/
st_src_reg result;
@@ -418,8 +420,6 @@ public:
void emit_scalar(ir_instruction *ir, unsigned op,
st_dst_reg dst, st_src_reg src0, st_src_reg src1);
- void try_emit_float_set(ir_instruction *ir, unsigned op, st_dst_reg dst);
-
void emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg src0);
void emit_scs(ir_instruction *ir, unsigned op,
@@ -592,9 +592,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
this->instructions.push_tail(inst);
- if (native_integers)
- try_emit_float_set(ir, op, dst);
-
return inst;
}
@@ -620,25 +617,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op)
return emit(ir, op, undef_dst, undef_src, undef_src, undef_src);
}
- /**
- * Emits the code to convert the result of float SET instructions to integers.
- */
-void
-glsl_to_tgsi_visitor::try_emit_float_set(ir_instruction *ir, unsigned op,
- st_dst_reg dst)
-{
- if ((op == TGSI_OPCODE_SEQ ||
- op == TGSI_OPCODE_SNE ||
- op == TGSI_OPCODE_SGE ||
- op == TGSI_OPCODE_SLT))
- {
- st_src_reg src = st_src_reg(dst);
- src.negate = ~src.negate;
- dst.type = GLSL_TYPE_FLOAT;
- emit(ir, TGSI_OPCODE_F2I, dst, src);
- }
-}
-
/**
* Determines whether to use an integer, unsigned integer, or float opcode
* based on the operands and input opcode, then emits the result.
@@ -662,14 +640,30 @@ glsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op,
#define case4(c, f, i, u) \
case TGSI_OPCODE_##c: \
- if (type == GLSL_TYPE_INT) op = TGSI_OPCODE_##i; \
- else if (type == GLSL_TYPE_UINT) op = TGSI_OPCODE_##u; \
- else op = TGSI_OPCODE_##f; \
+ if (type == GLSL_TYPE_INT) \
+ op = TGSI_OPCODE_##i; \
+ else if (type == GLSL_TYPE_UINT) \
+ op = TGSI_OPCODE_##u; \
+ else \
+ op = TGSI_OPCODE_##f; \
break;
+
#define case3(f, i, u) case4(f, f, i, u)
#define case2fi(f, i) case4(f, f, i, i)
#define case2iu(i, u) case4(i, LAST, i, u)
-
+
+#define casecomp(c, f, i, u) \
+ case TGSI_OPCODE_##c: \
+ if (type == GLSL_TYPE_INT) \
+ op = TGSI_OPCODE_##i; \
+ else if (type == GLSL_TYPE_UINT) \
+ op = TGSI_OPCODE_##u; \
+ else if (native_integers) \
+ op = TGSI_OPCODE_##f; \
+ else \
+ op = TGSI_OPCODE_##c; \
+ break;
+
switch(op) {
case2fi(ADD, UADD);
case2fi(MUL, UMUL);
@@ -678,12 +672,12 @@ glsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op,
case3(MAX, IMAX, UMAX);
case3(MIN, IMIN, UMIN);
case2iu(MOD, UMOD);
-
- case2fi(SEQ, USEQ);
- case2fi(SNE, USNE);
- case3(SGE, ISGE, USGE);
- case3(SLT, ISLT, USLT);
-
+
+ casecomp(SEQ, FSEQ, USEQ, USEQ);
+ casecomp(SNE, FSNE, USNE, USNE);
+ casecomp(SGE, FSGE, ISGE, USGE);
+ casecomp(SLT, FSLT, ISLT, USLT);
+
case2iu(ISHR, USHR);
case2fi(SSG, ISSG);
@@ -3015,6 +3009,18 @@ glsl_to_tgsi_visitor::visit(ir_if *ir)
if_inst = emit(ir->condition, TGSI_OPCODE_ENDIF);
}
+void
+glsl_to_tgsi_visitor::visit(ir_emit_vertex *ir)
+{
+ assert(!"Geometry shaders not supported.");
+}
+
+void
+glsl_to_tgsi_visitor::visit(ir_end_primitive *ir)
+{
+ assert(!"Geometry shaders not supported.");
+}
+
glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
{
result.file = PROGRAM_UNDEFINED;
@@ -5121,7 +5127,7 @@ get_mesa_program(struct gl_context *ctx,
prog->Instructions = NULL;
prog->NumInstructions = 0;
- do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER);
+ do_set_program_inouts(shader->ir, prog, shader->Type);
count_resources(v, prog);
_mesa_reference_program(ctx, &shader->Program, prog);
diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c
index 75831faf9..bd05cd0c3 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_array.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_array.c
@@ -442,41 +442,77 @@ recalculate_input_bindings(struct gl_context *ctx)
break;
case VP_ARB:
- /* GL_ARB_vertex_program or GLSL vertex shader - Only the generic[0]
+ /* There are no shaders in OpenGL ES 1.x, so this code path should be
+ * impossible to reach. The meta code is careful to not use shaders in
+ * ES1.
+ */
+ assert(ctx->API != API_OPENGLES);
+
+ /* In the compatibility profile of desktop OpenGL, the generic[0]
* attribute array aliases and overrides the legacy position array.
- *
* Otherwise, legacy attributes available in the legacy slots,
* generic attributes in the generic slots and materials are not
* available as per-vertex attributes.
+ *
+ * In all other APIs, only the generic attributes exist, and none of the
+ * slots are considered "magic."
*/
- if (vertexAttrib[VERT_ATTRIB_GENERIC0].Enabled)
- inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0];
- else if (vertexAttrib[VERT_ATTRIB_POS].Enabled)
- inputs[0] = &vertexAttrib[VERT_ATTRIB_POS];
- else {
- inputs[0] = &vbo->currval[VBO_ATTRIB_POS];
- const_inputs |= VERT_BIT_POS;
- }
+ if (ctx->API == API_OPENGL_COMPAT) {
+ if (vertexAttrib[VERT_ATTRIB_GENERIC0].Enabled)
+ inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0];
+ else if (vertexAttrib[VERT_ATTRIB_POS].Enabled)
+ inputs[0] = &vertexAttrib[VERT_ATTRIB_POS];
+ else {
+ inputs[0] = &vbo->currval[VBO_ATTRIB_POS];
+ const_inputs |= VERT_BIT_POS;
+ }
- for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) {
- if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled)
- inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
- else {
- inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
+ for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) {
+ if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled)
+ inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
+ else {
+ inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
+ const_inputs |= VERT_BIT_FF(i);
+ }
+ }
+
+ for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) {
+ if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
+ inputs[VERT_ATTRIB_GENERIC(i)] =
+ &vertexAttrib[VERT_ATTRIB_GENERIC(i)];
+ else {
+ inputs[VERT_ATTRIB_GENERIC(i)] =
+ &vbo->currval[VBO_ATTRIB_GENERIC0+i];
+ const_inputs |= VERT_BIT_GENERIC(i);
+ }
+ }
+
+ inputs[VERT_ATTRIB_GENERIC0] = inputs[0];
+ } else {
+ /* Other parts of the code assume that inputs[0] through
+ * inputs[VERT_ATTRIB_FF_MAX] will be non-NULL. However, in OpenGL
+ * ES 2.0+ or OpenGL core profile, none of these arrays should ever
+ * be enabled.
+ */
+ for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) {
+ assert(!vertexAttrib[VERT_ATTRIB_FF(i)].Enabled);
+
+ inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
const_inputs |= VERT_BIT_FF(i);
}
- }
- for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) {
- if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
- inputs[VERT_ATTRIB_GENERIC(i)] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)];
- else {
- inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i];
- const_inputs |= VERT_BIT_GENERIC(i);
+ for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) {
+ if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
+ inputs[VERT_ATTRIB_GENERIC(i)] =
+ &vertexAttrib[VERT_ATTRIB_GENERIC(i)];
+ else {
+ inputs[VERT_ATTRIB_GENERIC(i)] =
+ &vbo->currval[VBO_ATTRIB_GENERIC0+i];
+ const_inputs |= VERT_BIT_GENERIC(i);
+ }
}
}
- inputs[VERT_ATTRIB_GENERIC0] = inputs[0];
break;
}
diff --git a/pixman/RELEASING b/pixman/RELEASING
index fbe15813d..657857de2 100644
--- a/pixman/RELEASING
+++ b/pixman/RELEASING
@@ -55,3 +55,5 @@ Here are the steps to follow to create a new pixman release:
You must use "--tags" here; otherwise the new tag will not
be pushed out.
+8) Change the topic of the #cairo IRC channel on freenode to advertise
+ the new version.
diff --git a/pixman/pixman/pixman-fast-path.c b/pixman/pixman/pixman-fast-path.c
index 3982dce8b..2608268d9 100644
--- a/pixman/pixman/pixman-fast-path.c
+++ b/pixman/pixman/pixman-fast-path.c
@@ -2261,6 +2261,237 @@ fast_write_back_r5g6b5 (pixman_iter_t *iter)
}
}
+typedef struct
+{
+ int y;
+ uint64_t * buffer;
+} line_t;
+
+typedef struct
+{
+ line_t line0;
+ line_t line1;
+ pixman_fixed_t y;
+ pixman_fixed_t x;
+ uint64_t data[1];
+} bilinear_info_t;
+
+static void
+fetch_horizontal (bits_image_t *image, line_t *line,
+ int y, pixman_fixed_t x, pixman_fixed_t ux, int n)
+{
+ uint32_t *bits = image->bits + y * image->rowstride;
+ int i;
+
+ for (i = 0; i < n; ++i)
+ {
+ int x0 = pixman_fixed_to_int (x);
+ int x1 = x0 + 1;
+ int32_t dist_x;
+
+ uint32_t left = *(bits + x0);
+ uint32_t right = *(bits + x1);
+
+ dist_x = pixman_fixed_to_bilinear_weight (x);
+ dist_x <<= (8 - BILINEAR_INTERPOLATION_BITS);
+
+#if SIZEOF_LONG <= 4
+ {
+ uint32_t lag, rag, ag;
+ uint32_t lrb, rrb, rb;
+
+ lag = (left & 0xff00ff00) >> 8;
+ rag = (right & 0xff00ff00) >> 8;
+ ag = (lag << 8) + dist_x * (rag - lag);
+
+ lrb = (left & 0x00ff00ff);
+ rrb = (right & 0x00ff00ff);
+ rb = (lrb << 8) + dist_x * (rrb - lrb);
+
+ *((uint32_t *)(line->buffer + i)) = ag;
+ *((uint32_t *)(line->buffer + i) + 1) = rb;
+ }
+#else
+ {
+ uint64_t lagrb, ragrb;
+ uint32_t lag, rag;
+ uint32_t lrb, rrb;
+
+ lag = (left & 0xff00ff00);
+ lrb = (left & 0x00ff00ff);
+ rag = (right & 0xff00ff00);
+ rrb = (right & 0x00ff00ff);
+ lagrb = (((uint64_t)lag) << 24) | lrb;
+ ragrb = (((uint64_t)rag) << 24) | rrb;
+
+ line->buffer[i] = (lagrb << 8) + dist_x * (ragrb - lagrb);
+ }
+#endif
+
+ x += ux;
+ }
+
+ line->y = y;
+}
+
+static uint32_t *
+fast_fetch_bilinear_cover (pixman_iter_t *iter, const uint32_t *mask)
+{
+ pixman_fixed_t fx, ux;
+ bilinear_info_t *info = iter->data;
+ line_t *line0, *line1;
+ int y0, y1;
+ int32_t dist_y;
+ int i;
+
+ fx = info->x;
+ ux = iter->image->common.transform->matrix[0][0];
+
+ y0 = pixman_fixed_to_int (info->y);
+ y1 = y0 + 1;
+ dist_y = pixman_fixed_to_bilinear_weight (info->y);
+ dist_y <<= (8 - BILINEAR_INTERPOLATION_BITS);
+
+ line0 = &info->line0;
+ line1 = &info->line1;
+
+ if (line0->y != y0 || line1->y != y1)
+ {
+ if (line0->y == y1 || line1->y == y0)
+ {
+ line_t tmp = *line0;
+ *line0 = *line1;
+ *line1 = tmp;
+ }
+
+ if (line0->y != y0)
+ {
+ fetch_horizontal (
+ &iter->image->bits, line0, y0, fx, ux, iter->width);
+ }
+
+ if (line1->y != y1)
+ {
+ fetch_horizontal (
+ &iter->image->bits, line1, y1, fx, ux, iter->width);
+ }
+ }
+
+ for (i = 0; i < iter->width; ++i)
+ {
+#if SIZEOF_LONG <= 4
+ uint32_t ta, tr, tg, tb;
+ uint32_t ba, br, bg, bb;
+ uint32_t tag, trb;
+ uint32_t bag, brb;
+ uint32_t a, r, g, b;
+
+ tag = *((uint32_t *)(line0->buffer + i));
+ trb = *((uint32_t *)(line0->buffer + i) + 1);
+ bag = *((uint32_t *)(line1->buffer + i));
+ brb = *((uint32_t *)(line1->buffer + i) + 1);
+
+ ta = tag >> 16;
+ ba = bag >> 16;
+ a = (ta << 8) + dist_y * (ba - ta);
+
+ tr = trb >> 16;
+ br = brb >> 16;
+ r = (tr << 8) + dist_y * (br - tr);
+
+ tg = tag & 0xffff;
+ bg = bag & 0xffff;
+ g = (tg << 8) + dist_y * (bg - tg);
+
+ tb = trb & 0xffff;
+ bb = brb & 0xffff;
+ b = (tb << 8) + dist_y * (bb - tb);
+
+ a = (a << 8) & 0xff000000;
+ r = (r << 0) & 0x00ff0000;
+ g = (g >> 8) & 0x0000ff00;
+ b = (b >> 16) & 0x000000ff;
+#else
+ uint64_t top = line0->buffer[i];
+ uint64_t bot = line1->buffer[i];
+ uint64_t tar = (top & 0xffff0000ffff0000ULL) >> 16;
+ uint64_t bar = (bot & 0xffff0000ffff0000ULL) >> 16;
+ uint64_t tgb = (top & 0x0000ffff0000ffffULL);
+ uint64_t bgb = (bot & 0x0000ffff0000ffffULL);
+ uint64_t ar, gb;
+ uint32_t a, r, g, b;
+
+ ar = (tar << 8) + dist_y * (bar - tar);
+ gb = (tgb << 8) + dist_y * (bgb - tgb);
+
+ a = ((ar >> 24) & 0xff000000);
+ r = ((ar >> 0) & 0x00ff0000);
+ g = ((gb >> 40) & 0x0000ff00);
+ b = ((gb >> 16) & 0x000000ff);
+#endif
+
+ iter->buffer[i] = a | r | g | b;
+ }
+
+ info->y += iter->image->common.transform->matrix[1][1];
+
+ return iter->buffer;
+}
+
+static void
+bilinear_cover_iter_fini (pixman_iter_t *iter)
+{
+ free (iter->data);
+}
+
+static void
+fast_bilinear_cover_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *iter_info)
+{
+ int width = iter->width;
+ bilinear_info_t *info;
+ pixman_vector_t v;
+
+ /* Reference point is the center of the pixel */
+ v.vector[0] = pixman_int_to_fixed (iter->x) + pixman_fixed_1 / 2;
+ v.vector[1] = pixman_int_to_fixed (iter->y) + pixman_fixed_1 / 2;
+ v.vector[2] = pixman_fixed_1;
+
+ if (!pixman_transform_point_3d (iter->image->common.transform, &v))
+ goto fail;
+
+ info = malloc (sizeof (*info) + (2 * width - 1) * sizeof (uint64_t));
+ if (!info)
+ goto fail;
+
+ info->x = v.vector[0] - pixman_fixed_1 / 2;
+ info->y = v.vector[1] - pixman_fixed_1 / 2;
+
+ /* It is safe to set the y coordinates to -1 initially
+ * because COVER_CLIP_BILINEAR ensures that we will only
+ * be asked to fetch lines in the [0, height) interval
+ */
+ info->line0.y = -1;
+ info->line0.buffer = &(info->data[0]);
+ info->line1.y = -1;
+ info->line1.buffer = &(info->data[width]);
+
+ iter->get_scanline = fast_fetch_bilinear_cover;
+ iter->fini = bilinear_cover_iter_fini;
+
+ iter->data = info;
+ return;
+
+fail:
+ /* Something went wrong, either a bad matrix or OOM; in such cases,
+ * we don't guarantee any particular rendering.
+ */
+ _pixman_log_error (
+ FUNC, "Allocation failure or bad matrix, skipping rendering\n");
+
+ iter->get_scanline = _pixman_iter_get_scanline_noop;
+ iter->fini = bilinear_cover_iter_fini;
+}
+
#define IMAGE_FLAGS \
(FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | \
FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
@@ -2280,6 +2511,16 @@ static const pixman_iter_info_t fast_iters[] =
_pixman_iter_init_bits_stride,
fast_dest_fetch_noop, fast_write_back_r5g6b5 },
+ { PIXMAN_a8r8g8b8,
+ (FAST_PATH_STANDARD_FLAGS |
+ FAST_PATH_SCALE_TRANSFORM |
+ FAST_PATH_BILINEAR_FILTER |
+ FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR),
+ ITER_NARROW | ITER_SRC,
+ fast_bilinear_cover_iter_init,
+ NULL, NULL
+ },
+
{ PIXMAN_null },
};
diff --git a/pixman/pixman/pixman-general.c b/pixman/pixman/pixman-general.c
index 4da5da5e2..6310bff9d 100644
--- a/pixman/pixman/pixman-general.c
+++ b/pixman/pixman/pixman-general.c
@@ -208,6 +208,13 @@ general_composite_rect (pixman_implementation_t *imp,
dest_iter.write_back (&dest_iter);
}
+ if (src_iter.fini)
+ src_iter.fini (&src_iter);
+ if (mask_iter.fini)
+ mask_iter.fini (&mask_iter);
+ if (dest_iter.fini)
+ dest_iter.fini (&dest_iter);
+
if (scanline_buffer != (uint8_t *) stack_scanline_buffer)
free (scanline_buffer);
}
diff --git a/pixman/pixman/pixman-image.c b/pixman/pixman/pixman-image.c
index 4f9c2f966..1ff1a4974 100644
--- a/pixman/pixman/pixman-image.c
+++ b/pixman/pixman/pixman-image.c
@@ -926,6 +926,9 @@ _pixman_image_get_solid (pixman_implementation_t *imp,
ITER_NARROW | ITER_SRC, image->common.flags);
result = *iter.get_scanline (&iter, NULL);
+
+ if (iter.fini)
+ iter.fini (&iter);
}
/* If necessary, convert RGB <--> BGR. */
diff --git a/pixman/pixman/pixman-implementation.c b/pixman/pixman/pixman-implementation.c
index 160847ad0..588405451 100644
--- a/pixman/pixman/pixman-implementation.c
+++ b/pixman/pixman/pixman-implementation.c
@@ -313,6 +313,7 @@ _pixman_implementation_iter_init (pixman_implementation_t *imp,
iter->height = height;
iter->iter_flags = iter_flags;
iter->image_flags = image_flags;
+ iter->fini = NULL;
if (!iter->image)
{
diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h
index af4a0b6e0..964660508 100644
--- a/pixman/pixman/pixman-private.h
+++ b/pixman/pixman/pixman-private.h
@@ -209,6 +209,7 @@ union pixman_image
typedef struct pixman_iter_t pixman_iter_t;
typedef uint32_t *(* pixman_iter_get_scanline_t) (pixman_iter_t *iter, const uint32_t *mask);
typedef void (* pixman_iter_write_back_t) (pixman_iter_t *iter);
+typedef void (* pixman_iter_fini_t) (pixman_iter_t *iter);
typedef enum
{
@@ -255,6 +256,7 @@ struct pixman_iter_t
/* These function pointers are initialized by the implementation */
pixman_iter_get_scanline_t get_scanline;
pixman_iter_write_back_t write_back;
+ pixman_iter_fini_t fini;
/* These fields are scratch data that implementations can use */
void * data;
diff --git a/pixman/test/Makefile.sources b/pixman/test/Makefile.sources
index b5fc740f3..2fabdb574 100644
--- a/pixman/test/Makefile.sources
+++ b/pixman/test/Makefile.sources
@@ -33,6 +33,7 @@ OTHERPROGRAMS = \
lowlevel-blt-bench \
radial-perf-test \
check-formats \
+ scaling-bench \
$(NULL)
# Utility functions
diff --git a/pixman/test/alpha-loop.c b/pixman/test/alpha-loop.c
index eca761537..4d4384d00 100644
--- a/pixman/test/alpha-loop.c
+++ b/pixman/test/alpha-loop.c
@@ -8,6 +8,7 @@
int
main (int argc, char **argv)
{
+ pixman_image_t *a, *d, *s;
uint8_t *alpha;
uint32_t *src, *dest;
@@ -17,9 +18,9 @@ main (int argc, char **argv)
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);
- pixman_image_t *s = pixman_image_create_bits (PIXMAN_a2r10g10b10, WIDTH, HEIGHT, src, WIDTH * 4);
+ a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, (uint32_t *)alpha, WIDTH);
+ d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4);
+ s = pixman_image_create_bits (PIXMAN_a2r10g10b10, WIDTH, HEIGHT, src, WIDTH * 4);
fail_after (5, "Infinite loop detected: 5 seconds without progress\n");
diff --git a/pixman/test/matrix-test.c b/pixman/test/matrix-test.c
index 8437dd291..0a5f203f5 100644
--- a/pixman/test/matrix-test.c
+++ b/pixman/test/matrix-test.c
@@ -70,6 +70,53 @@ pixman_bool_t does_it_fit_fixed_48_16 (__float128 x)
#endif
+static inline uint32_t
+byteswap32 (uint32_t x)
+{
+ return ((x & ((uint32_t)0xFF << 24)) >> 24) |
+ ((x & ((uint32_t)0xFF << 16)) >> 8) |
+ ((x & ((uint32_t)0xFF << 8)) << 8) |
+ ((x & ((uint32_t)0xFF << 0)) << 24);
+}
+
+static inline uint64_t
+byteswap64 (uint64_t x)
+{
+ return ((x & ((uint64_t)0xFF << 56)) >> 56) |
+ ((x & ((uint64_t)0xFF << 48)) >> 40) |
+ ((x & ((uint64_t)0xFF << 40)) >> 24) |
+ ((x & ((uint64_t)0xFF << 32)) >> 8) |
+ ((x & ((uint64_t)0xFF << 24)) << 8) |
+ ((x & ((uint64_t)0xFF << 16)) << 24) |
+ ((x & ((uint64_t)0xFF << 8)) << 40) |
+ ((x & ((uint64_t)0xFF << 0)) << 56);
+}
+
+static void
+byteswap_transform (pixman_transform_t *t)
+{
+ int i, j;
+
+ if (is_little_endian ())
+ return;
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ t->matrix[i][j] = byteswap32 (t->matrix[i][j]);
+}
+
+static void
+byteswap_vector_48_16 (pixman_vector_48_16_t *v)
+{
+ int i;
+
+ if (is_little_endian ())
+ return;
+
+ for (i = 0; i < 3; i++)
+ v->v[i] = byteswap64 (v->v[i]);
+}
+
uint32_t
test_matrix (int testnum, int verbose)
{
@@ -90,6 +137,8 @@ test_matrix (int testnum, int verbose)
#endif
prng_randmemset (&ti, sizeof(ti), 0);
prng_randmemset (&vi, sizeof(vi), 0);
+ byteswap_transform (&ti);
+ byteswap_vector_48_16 (&vi);
for (j = 0; j < 3; j++)
{
@@ -132,8 +181,6 @@ test_matrix (int testnum, int verbose)
else
transform_ok = pixman_transform_point_31_16 (&ti, &vi, &result_i);
- crc32 = compute_crc32 (crc32, &result_i, sizeof(result_i));
-
#ifdef HAVE_FLOAT128
/* compare with a reference 128-bit floating point implementation */
for (j = 0; j < 3; j++)
@@ -173,6 +220,8 @@ test_matrix (int testnum, int verbose)
}
}
#endif
+ byteswap_vector_48_16 (&result_i);
+ crc32 = compute_crc32 (crc32, &result_i, sizeof (result_i));
}
return crc32;
}
diff --git a/pixman/test/scaling-bench.c b/pixman/test/scaling-bench.c
new file mode 100644
index 000000000..b39adeff5
--- /dev/null
+++ b/pixman/test/scaling-bench.c
@@ -0,0 +1,69 @@
+#include <stdlib.h>
+#include "utils.h"
+
+#define SOURCE_WIDTH 320
+#define SOURCE_HEIGHT 240
+
+static pixman_image_t *
+make_source (void)
+{
+ size_t n_bytes = (SOURCE_WIDTH + 2) * (SOURCE_HEIGHT + 2) * 4;
+ uint32_t *data = malloc (n_bytes);
+ pixman_image_t *source;
+
+ prng_randmemset (data, n_bytes, 0);
+
+ source = pixman_image_create_bits (
+ PIXMAN_a8r8g8b8, SOURCE_WIDTH + 2, SOURCE_HEIGHT + 2,
+ data,
+ (SOURCE_WIDTH + 2) * 4);
+
+ pixman_image_set_filter (source, PIXMAN_FILTER_BILINEAR, NULL, 0);
+
+ return source;
+}
+
+int
+main ()
+{
+ double scale;
+ pixman_image_t *src;
+
+ prng_srand (23874);
+
+ src = make_source ();
+ printf ("# %-6s %-22s %-14s %-12s\n",
+ "ratio",
+ "resolutions",
+ "time / ms",
+ "time per pixel / ns");
+ for (scale = 0.1; scale < 10.005; scale += 0.01)
+ {
+ int dest_width = SOURCE_WIDTH * scale + 0.5;
+ int dest_height = SOURCE_HEIGHT * scale + 0.5;
+ pixman_fixed_t s = (1 / scale) * 65536.0 + 0.5;
+ pixman_transform_t transform;
+ pixman_image_t *dest;
+ double t1, t2;
+
+ pixman_transform_init_scale (&transform, s, s);
+ pixman_image_set_transform (src, &transform);
+
+ dest = pixman_image_create_bits (
+ PIXMAN_a8r8g8b8, dest_width, dest_height, NULL, -1);
+
+ t1 = gettime();
+ pixman_image_composite (
+ PIXMAN_OP_OVER, src, NULL, dest,
+ scale, scale, 0, 0, 0, 0, dest_width, dest_height);
+ t2 = gettime();
+
+ printf ("%6.2f : %4dx%-4d => %4dx%-4d : %12.4f : %12.4f\n",
+ scale, SOURCE_WIDTH, SOURCE_HEIGHT, dest_width, dest_height,
+ (t2 - t1) * 1000, ((t2 - t1) / (dest_width * dest_height)) * 1000000000);
+
+ pixman_image_unref (dest);
+ }
+
+ return 0;
+}
diff --git a/xorg-server/.dir-locals.el b/xorg-server/.dir-locals.el
new file mode 100644
index 000000000..6aceae3a6
--- /dev/null
+++ b/xorg-server/.dir-locals.el
@@ -0,0 +1 @@
+((c-mode . ((c-basic-offset . 4) (indent-tabs-mode . nil)))) \ No newline at end of file
diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac
index c6ecba418..d27ca2392 100644
--- a/xorg-server/configure.ac
+++ b/xorg-server/configure.ac
@@ -215,7 +215,7 @@ AC_SUBST(DLOPEN_LIBS)
dnl Checks for library functions.
AC_CHECK_FUNCS([backtrace ffs geteuid getuid issetugid getresuid \
getdtablesize getifaddrs getpeereid getpeerucred getzoneid \
- mmap shmctl64 strncasecmp vasprintf vsnprintf walkcontext])
+ mmap seteuid shmctl64 strncasecmp vasprintf vsnprintf walkcontext])
AC_REPLACE_FUNCS([strcasecmp strcasestr strlcat strlcpy strndup])
dnl Find the math libary, then check for cbrt function in it.
diff --git a/xorg-server/dix/window.c b/xorg-server/dix/window.c
index 8950f9766..9fa51c288 100644
--- a/xorg-server/dix/window.c
+++ b/xorg-server/dix/window.c
@@ -126,6 +126,7 @@ Equipment Corporation.
#ifdef COMPOSITE
#include "compint.h"
#endif
+#include "selection.h"
#include "privates.h"
#include "xace.h"
diff --git a/xorg-server/exa/Makefile.am b/xorg-server/exa/Makefile.am
index 8b759cd76..c1f1e8638 100644
--- a/xorg-server/exa/Makefile.am
+++ b/xorg-server/exa/Makefile.am
@@ -8,7 +8,7 @@ if XORG
sdk_HEADERS = exa.h
endif
-INCLUDES = \
+AM_CPPFLAGS = \
$(XORG_INCS) \
-I$(srcdir)/../miext/cw
diff --git a/xorg-server/glx/Makefile.am b/xorg-server/glx/Makefile.am
index 591c4ac66..d1c203dc9 100644
--- a/xorg-server/glx/Makefile.am
+++ b/xorg-server/glx/Makefile.am
@@ -15,7 +15,7 @@ AM_CFLAGS = \
# none yet
#sdk_HEADERS =
-INCLUDES = \
+AM_CPPFLAGS = \
-I$(top_srcdir)/hw/xfree86/os-support \
-I$(top_srcdir)/hw/xfree86/os-support/bus \
-I$(top_srcdir)/hw/xfree86/common \
@@ -23,7 +23,7 @@ INCLUDES = \
-I$(top_srcdir)/mi
if DRI2_AIGLX
-INCLUDES += -I$(top_srcdir)/hw/xfree86/dri2
+AM_CPPFLAGS += -I$(top_srcdir)/hw/xfree86/dri2
endif
glapi_sources = \
diff --git a/xorg-server/hw/kdrive/ephyr/Makefile.am b/xorg-server/hw/kdrive/ephyr/Makefile.am
index 2e0613a7c..ab024373c 100644
--- a/xorg-server/hw/kdrive/ephyr/Makefile.am
+++ b/xorg-server/hw/kdrive/ephyr/Makefile.am
@@ -1,6 +1,6 @@
SUBDIRS = man
-INCLUDES = \
+AM_CPPFLAGS = \
@KDRIVE_INCS@ \
@KDRIVE_CFLAGS@ \
@XEPHYR_INCS@ \
diff --git a/xorg-server/hw/kdrive/fake/Makefile.am b/xorg-server/hw/kdrive/fake/Makefile.am
index 6d3ed056e..14c99c3cc 100644
--- a/xorg-server/hw/kdrive/fake/Makefile.am
+++ b/xorg-server/hw/kdrive/fake/Makefile.am
@@ -1,4 +1,4 @@
-INCLUDES = \
+AM_CPPFLAGS = \
@KDRIVE_INCS@ \
@KDRIVE_CFLAGS@
diff --git a/xorg-server/hw/kdrive/fbdev/Makefile.am b/xorg-server/hw/kdrive/fbdev/Makefile.am
index ec9df95e0..7e8ba024c 100644
--- a/xorg-server/hw/kdrive/fbdev/Makefile.am
+++ b/xorg-server/hw/kdrive/fbdev/Makefile.am
@@ -1,4 +1,4 @@
-INCLUDES = \
+AM_CPPFLAGS = \
@KDRIVE_INCS@ \
@KDRIVE_CFLAGS@
diff --git a/xorg-server/hw/kdrive/linux/Makefile.am b/xorg-server/hw/kdrive/linux/Makefile.am
index 93e5d2f9f..1362cd9d8 100644
--- a/xorg-server/hw/kdrive/linux/Makefile.am
+++ b/xorg-server/hw/kdrive/linux/Makefile.am
@@ -1,4 +1,4 @@
-INCLUDES = \
+AM_CPPFLAGS = \
@KDRIVE_INCS@ \
@KDRIVE_CFLAGS@
diff --git a/xorg-server/hw/kdrive/src/Makefile.am b/xorg-server/hw/kdrive/src/Makefile.am
index 51375b950..5799ddbdb 100644
--- a/xorg-server/hw/kdrive/src/Makefile.am
+++ b/xorg-server/hw/kdrive/src/Makefile.am
@@ -1,4 +1,4 @@
-INCLUDES = \
+AM_CPPFLAGS = \
@KDRIVE_INCS@ \
@KDRIVE_CFLAGS@
diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am
index c3899b577..d568e0d7e 100644
--- a/xorg-server/hw/xfree86/Makefile.am
+++ b/xorg-server/hw/xfree86/Makefile.am
@@ -39,7 +39,7 @@ bin_PROGRAMS = Xorg
nodist_Xorg_SOURCES = sdksyms.c
AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
-INCLUDES = $(XORG_INCS) -I$(srcdir)/parser -I$(top_srcdir)/miext/cw \
+AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/parser -I$(top_srcdir)/miext/cw \
-I$(srcdir)/ddc -I$(srcdir)/i2c -I$(srcdir)/modes -I$(srcdir)/ramdac \
-I$(srcdir)/dri -I$(srcdir)/dri2
@@ -115,7 +115,7 @@ CLEANFILES = sdksyms.c sdksyms.dep
EXTRA_DIST += sdksyms.sh
sdksyms.dep sdksyms.c: sdksyms.sh
- $(AM_V_GEN)CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $(srcdir)/sdksyms.sh $(top_srcdir) $(CFLAGS) $(AM_CFLAGS) $(INCLUDES)
+ $(AM_V_GEN)CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $(srcdir)/sdksyms.sh $(top_srcdir) $(CFLAGS) $(AM_CFLAGS) $(AM_CPPFLAGS)
SDKSYMS_DEP = sdksyms.dep
include $(SDKSYMS_DEP)
diff --git a/xorg-server/hw/xfree86/common/Makefile.am b/xorg-server/hw/xfree86/common/Makefile.am
index 532d87bbe..7a2b4bc1e 100644
--- a/xorg-server/hw/xfree86/common/Makefile.am
+++ b/xorg-server/hw/xfree86/common/Makefile.am
@@ -53,7 +53,7 @@ libcommon_la_SOURCES = xf86Configure.c xf86Bus.c xf86Config.c \
nodist_libcommon_la_SOURCES = xf86DefModeSet.c xf86Build.h
libcommon_la_LIBADD = $(top_builddir)/config/libconfig.la
-INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \
+AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \
-I$(srcdir)/../loader -I$(srcdir)/../parser \
-I$(srcdir)/../vbe -I$(srcdir)/../int10 \
-I$(srcdir)/../vgahw -I$(srcdir)/../dixmods/extmod \
diff --git a/xorg-server/hw/xfree86/ddc/Makefile.am b/xorg-server/hw/xfree86/ddc/Makefile.am
index 93ea4a2a5..a7b84adcd 100644
--- a/xorg-server/hw/xfree86/ddc/Makefile.am
+++ b/xorg-server/hw/xfree86/ddc/Makefile.am
@@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libddc.la
libddc_la_SOURCES = ddc.c interpret_edid.c print_edid.c ddcProperty.c
-INCLUDES = $(XORG_INCS) -I$(srcdir)/../i2c
+AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/../i2c
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
diff --git a/xorg-server/hw/xfree86/dixmods/Makefile.am b/xorg-server/hw/xfree86/dixmods/Makefile.am
index f161db60a..9933bc88d 100644
--- a/xorg-server/hw/xfree86/dixmods/Makefile.am
+++ b/xorg-server/hw/xfree86/dixmods/Makefile.am
@@ -12,7 +12,7 @@ extsmoduledir = $(moduledir)/extensions
extsmodule_LTLIBRARIES = $(GLXMODS)
AM_CFLAGS = @XORG_CFLAGS@ @DIX_CFLAGS@
-INCLUDES = @XORG_INCS@ \
+AM_CPPFLAGS = @XORG_INCS@ \
-I$(top_srcdir)/hw/xfree86/loader \
-I$(top_srcdir)/miext/shadow \
-I$(top_srcdir)/glx
diff --git a/xorg-server/hw/xfree86/exa/Makefile.am b/xorg-server/hw/xfree86/exa/Makefile.am
index 433908411..1e42cdacd 100644
--- a/xorg-server/hw/xfree86/exa/Makefile.am
+++ b/xorg-server/hw/xfree86/exa/Makefile.am
@@ -4,7 +4,7 @@ module_LTLIBRARIES = libexa.la
libexa_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG)
-INCLUDES = \
+AM_CPPFLAGS = \
$(XORG_INCS) \
-I$(srcdir)/../../../exa \
-I$(srcdir)/../../../miext/cw
diff --git a/xorg-server/hw/xfree86/fbdevhw/Makefile.am b/xorg-server/hw/xfree86/fbdevhw/Makefile.am
index ee5577a86..37cd88c0e 100644
--- a/xorg-server/hw/xfree86/fbdevhw/Makefile.am
+++ b/xorg-server/hw/xfree86/fbdevhw/Makefile.am
@@ -10,7 +10,7 @@ else
libfbdevhw_la_SOURCES = fbdevhwstub.c
endif
-INCLUDES = $(XORG_INCS) -I$(srcdir)/../i2c -I$(srcdir)/../modes -I$(srcdir)/../ddc -I$(srcdir)/../parser
+AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/../i2c -I$(srcdir)/../modes -I$(srcdir)/../ddc -I$(srcdir)/../parser
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
diff --git a/xorg-server/hw/xfree86/i2c/Makefile.am b/xorg-server/hw/xfree86/i2c/Makefile.am
index cb18db188..c31159196 100644
--- a/xorg-server/hw/xfree86/i2c/Makefile.am
+++ b/xorg-server/hw/xfree86/i2c/Makefile.am
@@ -12,7 +12,7 @@ multimedia_LTLIBRARIES = \
libi2c_la_SOURCES = xf86i2c.c
-INCLUDES = $(XORG_INCS)
+AM_CPPFLAGS = $(XORG_INCS)
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
diff --git a/xorg-server/hw/xfree86/int10/Makefile.am b/xorg-server/hw/xfree86/int10/Makefile.am
index f5ece69ef..66cb14d46 100644
--- a/xorg-server/hw/xfree86/int10/Makefile.am
+++ b/xorg-server/hw/xfree86/int10/Makefile.am
@@ -17,9 +17,10 @@ if I386_VIDEO
I386_VIDEO_CFLAGS = -D_PC
endif
+AM_CPPFLAGS = $(XORG_INCS)
+
if INT10_VM86
AM_CFLAGS = $(I386_VIDEO_CFLAGS) -D_VM86_LINUX $(DIX_CFLAGS) $(XORG_CFLAGS) $(EXTRA_CFLAGS)
-INCLUDES = $(XORG_INCS)
libint10_la_SOURCES = \
$(COMMON_SOURCES) \
$(srcdir)/../os-support/linux/int10/vm86/linux_vm86.c \
@@ -29,7 +30,7 @@ endif
if INT10_X86EMU
AM_CFLAGS = $(I386_VIDEO_CFLAGS) -D_X86EMU -DNO_SYS_HEADERS \
$(XORG_CFLAGS) $(EXTRA_CFLAGS) $(DIX_CFLAGS)
-INCLUDES = $(XORG_INCS) -I$(srcdir)/../x86emu
+AM_CPPFLAGS += -I$(srcdir)/../x86emu
libint10_la_SOURCES = \
$(COMMON_SOURCES) \
xf86x86emu.c \
@@ -39,7 +40,6 @@ endif
if INT10_STUB
AM_CFLAGS = $(I386_VIDEO_CFLAGS) -D_VM86_LINUX $(DIX_CFLAGS) $(XORG_CFLAGS) $(EXTRA_CFLAGS)
-INCLUDES = $(XORG_INCS)
libint10_la_SOURCES = stub.c xf86int10module.c
endif
diff --git a/xorg-server/hw/xfree86/loader/Makefile.am b/xorg-server/hw/xfree86/loader/Makefile.am
index bd47a635b..a658ca50f 100644
--- a/xorg-server/hw/xfree86/loader/Makefile.am
+++ b/xorg-server/hw/xfree86/loader/Makefile.am
@@ -1,6 +1,6 @@
noinst_LTLIBRARIES = libloader.la
-INCLUDES = $(XORG_INCS) -I$(srcdir)/../parser -I$(top_srcdir)/miext/cw \
+AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/../parser -I$(top_srcdir)/miext/cw \
-I$(srcdir)/../ddc -I$(srcdir)/../i2c -I$(srcdir)/../modes \
-I$(srcdir)/../ramdac -I$(srcdir)/../dri -I$(srcdir)/../dri2
diff --git a/xorg-server/hw/xfree86/modes/Makefile.am b/xorg-server/hw/xfree86/modes/Makefile.am
index 7e33ebb17..220643f7b 100644
--- a/xorg-server/hw/xfree86/modes/Makefile.am
+++ b/xorg-server/hw/xfree86/modes/Makefile.am
@@ -19,7 +19,7 @@ libxf86modes_la_SOURCES = \
xf86Rotate.c \
$(DGA_SRCS)
-INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \
+AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \
-I$(srcdir)/../loader -I$(srcdir)/../rac -I$(srcdir)/../parser \
-I$(srcdir)/../vbe -I$(srcdir)/../int10 \
-I$(srcdir)/../vgahw -I$(srcdir)/../ramdac \
diff --git a/xorg-server/hw/xfree86/os-support/bsd/Makefile.am b/xorg-server/hw/xfree86/os-support/bsd/Makefile.am
index b6ecdf1d1..7133c0f21 100644
--- a/xorg-server/hw/xfree86/os-support/bsd/Makefile.am
+++ b/xorg-server/hw/xfree86/os-support/bsd/Makefile.am
@@ -54,7 +54,7 @@ endif
# FIXME: NetBSD Aperture defines (configure.ac)
AM_CFLAGS = -DUSESTDRES $(XORG_CFLAGS) $(DIX_CFLAGS)
-INCLUDES = $(XORG_INCS)
+AM_CPPFLAGS = $(XORG_INCS)
libbsd_la_SOURCES = \
$(srcdir)/../shared/posix_tty.c \
diff --git a/xorg-server/hw/xfree86/os-support/bus/Makefile.am b/xorg-server/hw/xfree86/os-support/bus/Makefile.am
index e09d4d21f..eebb3aed6 100644
--- a/xorg-server/hw/xfree86/os-support/bus/Makefile.am
+++ b/xorg-server/hw/xfree86/os-support/bus/Makefile.am
@@ -17,7 +17,7 @@ endif
libbus_la_SOURCES = $(PCI_SOURCES) $(PLATFORM_SOURCES) nobus.c
-INCLUDES = $(XORG_INCS)
+AM_CPPFLAGS = $(XORG_INCS)
AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
diff --git a/xorg-server/hw/xfree86/os-support/hurd/Makefile.am b/xorg-server/hw/xfree86/os-support/hurd/Makefile.am
index 3e8224753..f228c1ce4 100644
--- a/xorg-server/hw/xfree86/os-support/hurd/Makefile.am
+++ b/xorg-server/hw/xfree86/os-support/hurd/Makefile.am
@@ -12,4 +12,4 @@ libhurd_la_SOURCES = hurd_bell.c hurd_init.c hurd_mmap.c \
AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(XORG_CFLAGS) $(DIX_CFLAGS)
-INCLUDES = $(XORG_INCS)
+AM_CPPFLAGS = $(XORG_INCS)
diff --git a/xorg-server/hw/xfree86/os-support/linux/Makefile.am b/xorg-server/hw/xfree86/os-support/linux/Makefile.am
index 61175b386..83e7e0027 100644
--- a/xorg-server/hw/xfree86/os-support/linux/Makefile.am
+++ b/xorg-server/hw/xfree86/os-support/linux/Makefile.am
@@ -34,7 +34,7 @@ liblinux_la_SOURCES = lnx_init.c lnx_video.c \
AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(DIX_CFLAGS) $(XORG_CFLAGS) $(PLATFORM_DEFINES)
-INCLUDES = $(XORG_INCS) $(PLATFORM_INCLUDES) $(LIBDRM_CFLAGS)
+AM_CPPFLAGS = $(XORG_INCS) $(PLATFORM_INCLUDES) $(LIBDRM_CFLAGS)
EXTRA_DIST = \
$(srcdir)/../shared/xf86Axp.h
diff --git a/xorg-server/hw/xfree86/os-support/misc/Makefile.am b/xorg-server/hw/xfree86/os-support/misc/Makefile.am
index 4bd3fc3e1..0265aecd4 100644
--- a/xorg-server/hw/xfree86/os-support/misc/Makefile.am
+++ b/xorg-server/hw/xfree86/os-support/misc/Makefile.am
@@ -5,7 +5,7 @@ libmisc_la_SOURCES = SlowBcopy.c
#AM_LDFLAGS = -r
-INCLUDES = $(XORG_INCS)
+AM_CPPFLAGS = $(XORG_INCS)
AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
diff --git a/xorg-server/hw/xfree86/os-support/solaris/Makefile.am b/xorg-server/hw/xfree86/os-support/solaris/Makefile.am
index 5163f4423..6cda4b361 100644
--- a/xorg-server/hw/xfree86/os-support/solaris/Makefile.am
+++ b/xorg-server/hw/xfree86/os-support/solaris/Makefile.am
@@ -31,7 +31,7 @@ nodist_sdk_HEADERS = solaris-@SOLARIS_INOUT_ARCH@.il
AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(XORG_CFLAGS) $(DIX_CFLAGS)
-INCLUDES = $(XORG_INCS)
+AM_CPPFLAGS = $(XORG_INCS)
EXTRA_DIST = solaris-amd64.S solaris-ia32.S solaris-sparcv8plus.S \
apSolaris.shar sun_inout.s
diff --git a/xorg-server/hw/xfree86/os-support/stub/Makefile.am b/xorg-server/hw/xfree86/os-support/stub/Makefile.am
index a1156ef1b..a39e17d55 100644
--- a/xorg-server/hw/xfree86/os-support/stub/Makefile.am
+++ b/xorg-server/hw/xfree86/os-support/stub/Makefile.am
@@ -2,7 +2,7 @@ noinst_LTLIBRARIES = libstub.la
AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS)
-INCLUDES = $(XORG_INCS)
+AM_CPPFLAGS = $(XORG_INCS)
libstub_la_SOURCES = \
$(srcdir)/../shared/VTsw_noop.c \
diff --git a/xorg-server/hw/xfree86/parser/Makefile.am b/xorg-server/hw/xfree86/parser/Makefile.am
index 002cfbf5c..3bf62e8af 100644
--- a/xorg-server/hw/xfree86/parser/Makefile.am
+++ b/xorg-server/hw/xfree86/parser/Makefile.am
@@ -51,4 +51,4 @@ sdk_HEADERS = \
xf86Parser.h \
xf86Optrec.h
-INCLUDES = -I$(srcdir)/../common
+AM_CPPFLAGS = -I$(srcdir)/../common
diff --git a/xorg-server/hw/xfree86/parser/write.c b/xorg-server/hw/xfree86/parser/write.c
index 9c706a062..26739b933 100644
--- a/xorg-server/hw/xfree86/parser/write.c
+++ b/xorg-server/hw/xfree86/parser/write.c
@@ -55,6 +55,7 @@
#include <xorg-config.h>
#endif
+#include "os.h"
#include "xf86Parser.h"
#include "xf86tokens.h"
#include "Configint.h"
@@ -65,7 +66,7 @@
#include <signal.h>
#include <errno.h>
-#if defined(SVR4) || defined(__linux__) || defined(CSRG_BASED)
+#if defined(HAVE_SETEUID) && defined(_POSIX_SAVED_IDS) && _POSIX_SAVED_IDS > 0
#define HAS_SAVED_IDS_AND_SETEUID
#endif
#if defined(WIN32)
diff --git a/xorg-server/hw/xfree86/ramdac/Makefile.am b/xorg-server/hw/xfree86/ramdac/Makefile.am
index 346af4ccc..a3d77628c 100644
--- a/xorg-server/hw/xfree86/ramdac/Makefile.am
+++ b/xorg-server/hw/xfree86/ramdac/Makefile.am
@@ -9,4 +9,4 @@ EXTRA_DIST = BTPriv.h IBMPriv.h TIPriv.h xf86CursorPriv.h xf86RamDacPriv.h \
CURSOR.NOTES
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
-INCLUDES = $(XORG_INCS)
+AM_CPPFLAGS = $(XORG_INCS)
diff --git a/xorg-server/hw/xfree86/shadowfb/Makefile.am b/xorg-server/hw/xfree86/shadowfb/Makefile.am
index 5756fca3b..22f7ada2a 100644
--- a/xorg-server/hw/xfree86/shadowfb/Makefile.am
+++ b/xorg-server/hw/xfree86/shadowfb/Makefile.am
@@ -5,6 +5,6 @@ libshadowfb_la_LIBADD = $(PIXMAN_LIBS)
sdk_HEADERS = shadowfb.h
-INCLUDES = $(XORG_INCS)
+AM_CPPFLAGS = $(XORG_INCS)
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
diff --git a/xorg-server/hw/xfree86/utils/cvt/Makefile.am b/xorg-server/hw/xfree86/utils/cvt/Makefile.am
index 754606e8e..26abeb40b 100644
--- a/xorg-server/hw/xfree86/utils/cvt/Makefile.am
+++ b/xorg-server/hw/xfree86/utils/cvt/Makefile.am
@@ -22,7 +22,7 @@
bin_PROGRAMS = cvt
-INCLUDES = $(XORG_INCS) \
+AM_CPPFLAGS = $(XORG_INCS) \
-I$(top_srcdir)/hw/xfree86/ddc \
-I$(top_srcdir)/hw/xfree86/modes \
-I$(top_srcdir)/hw/xfree86/parser
diff --git a/xorg-server/hw/xfree86/vbe/Makefile.am b/xorg-server/hw/xfree86/vbe/Makefile.am
index 1720eb93b..041b47a9f 100644
--- a/xorg-server/hw/xfree86/vbe/Makefile.am
+++ b/xorg-server/hw/xfree86/vbe/Makefile.am
@@ -9,6 +9,6 @@ sdk_HEADERS = vbe.h vbeModes.h
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
-INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \
+AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \
-I$(srcdir)/../modes -I$(srcdir)/../parser \
-I$(srcdir)/../int10
diff --git a/xorg-server/hw/xfree86/vgahw/Makefile.am b/xorg-server/hw/xfree86/vgahw/Makefile.am
index f48e46a11..f0b65740c 100644
--- a/xorg-server/hw/xfree86/vgahw/Makefile.am
+++ b/xorg-server/hw/xfree86/vgahw/Makefile.am
@@ -1,7 +1,7 @@
module_LTLIBRARIES = libvgahw.la
libvgahw_la_LDFLAGS = -avoid-version
libvgahw_la_SOURCES = vgaHW.c vgaHWmodule.c
-INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c
+AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
sdk_HEADERS = vgaHW.h
diff --git a/xorg-server/hw/xfree86/x86emu/Makefile.am b/xorg-server/hw/xfree86/x86emu/Makefile.am
index df9697767..2a55d6353 100644
--- a/xorg-server/hw/xfree86/x86emu/Makefile.am
+++ b/xorg-server/hw/xfree86/x86emu/Makefile.am
@@ -11,7 +11,7 @@ libx86emu_la_SOURCES = debug.c \
sys.c \
x86emu.h
-INCLUDES =
+AM_CPPFLAGS =
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
diff --git a/xorg-server/hw/xwin/Makefile.am b/xorg-server/hw/xwin/Makefile.am
index 74a4243c2..831e7dc47 100644
--- a/xorg-server/hw/xwin/Makefile.am
+++ b/xorg-server/hw/xwin/Makefile.am
@@ -150,7 +150,7 @@ SRCS = InitInput.c \
XWin_SOURCES = $(SRCS)
-INCLUDES = -I$(top_srcdir)/miext/rootless
+AM_CPPFLAGS = -I$(top_srcdir)/miext/rootless
XWIN_SYS_LIBS += -ldxguid
diff --git a/xorg-server/hw/xwin/glx/Makefile.am b/xorg-server/hw/xwin/glx/Makefile.am
index f969af277..067ee5b3c 100644
--- a/xorg-server/hw/xwin/glx/Makefile.am
+++ b/xorg-server/hw/xwin/glx/Makefile.am
@@ -23,7 +23,7 @@ endif
DEFS = $(DEFS_MULTIWINDOW) $(DEFS_MULTIWINDOWEXTWM) $(DEFS_GLX_WINDOWS)
-INCLUDES = -I$(top_srcdir)/miext/rootless
+AM_CPPFLAGS = -I$(top_srcdir)/miext/rootless
AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \
$(XWINMODULES_CFLAGS) \
diff --git a/xorg-server/include/xorg-config.h.in b/xorg-server/include/xorg-config.h.in
index a71b25d72..0df31aeb2 100644
--- a/xorg-server/include/xorg-config.h.in
+++ b/xorg-server/include/xorg-config.h.in
@@ -139,4 +139,7 @@
/* Have X server platform bus support */
#undef XSERVER_PLATFORM_BUS
+/* Define to 1 if you have the `seteuid' function. */
+#undef HAVE_SETEUID
+
#endif /* _XORG_CONFIG_H_ */
diff --git a/xorg-server/mi/miinitext.c b/xorg-server/mi/miinitext.c
index 81c663abe..dbca9f774 100644
--- a/xorg-server/mi/miinitext.c
+++ b/xorg-server/mi/miinitext.c
@@ -157,7 +157,7 @@ static ExtensionToggle ExtensionToggleList[] = {
#ifdef XF86BIGFONT
{"XFree86-Bigfont", &noXFree86BigfontExtension},
#endif
-#ifdef XorgLoader
+#ifdef XORGSERVER
#ifdef XFreeXDGA
{"XFree86-DGA", &noXFree86DGAExtension},
#endif
diff --git a/xorg-server/miext/damage/Makefile.am b/xorg-server/miext/damage/Makefile.am
index 767a65aee..a7f432a61 100644
--- a/xorg-server/miext/damage/Makefile.am
+++ b/xorg-server/miext/damage/Makefile.am
@@ -2,7 +2,7 @@ noinst_LTLIBRARIES = libdamage.la
AM_CFLAGS = $(DIX_CFLAGS)
-INCLUDES = -I$(srcdir)/../cw
+AM_CPPFLAGS = -I$(srcdir)/../cw
if XORG
sdk_HEADERS = damage.h damagestr.h
diff --git a/xorg-server/miext/sync/Makefile.am b/xorg-server/miext/sync/Makefile.am
index 36b2816d7..9aa1ba5d5 100644
--- a/xorg-server/miext/sync/Makefile.am
+++ b/xorg-server/miext/sync/Makefile.am
@@ -2,7 +2,7 @@ noinst_LTLIBRARIES = libsync.la
AM_CFLAGS = $(DIX_CFLAGS)
-INCLUDES =
+AM_CPPFLAGS =
if XORG
sdk_HEADERS = misync.h misyncstr.h
diff --git a/xorg-server/test/Makefile.am b/xorg-server/test/Makefile.am
index 34f53fc1e..eff0c9d81 100644
--- a/xorg-server/test/Makefile.am
+++ b/xorg-server/test/Makefile.am
@@ -13,9 +13,9 @@ TESTS=$(noinst_PROGRAMS)
TESTS_ENVIRONMENT = $(XORG_MALLOC_DEBUG_ENV)
AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
-INCLUDES = $(XORG_INCS) -I$(top_srcdir)/miext/cw
+AM_CPPFLAGS = $(XORG_INCS) -I$(top_srcdir)/miext/cw
if XORG
-INCLUDES += -I$(top_srcdir)/hw/xfree86/parser \
+AM_CPPFLAGS += -I$(top_srcdir)/hw/xfree86/parser \
-I$(top_srcdir)/hw/xfree86/ddc \
-I$(top_srcdir)/hw/xfree86/i2c -I$(top_srcdir)/hw/xfree86/modes \
-I$(top_srcdir)/hw/xfree86/ramdac -I$(top_srcdir)/hw/xfree86/dri \
diff --git a/xorg-server/test/hashtabletest.c b/xorg-server/test/hashtabletest.c
index 64c7091fc..6af14a8e6 100644
--- a/xorg-server/test/hashtabletest.c
+++ b/xorg-server/test/hashtabletest.c
@@ -1,3 +1,7 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
#include <misc.h>
#include <stdlib.h>
#include <stdio.h>
diff --git a/xorg-server/test/xi2/Makefile.am b/xorg-server/test/xi2/Makefile.am
index 9de7abf5d..bfddfef13 100644
--- a/xorg-server/test/xi2/Makefile.am
+++ b/xorg-server/test/xi2/Makefile.am
@@ -17,7 +17,7 @@ TESTS=$(noinst_PROGRAMS)
TESTS_ENVIRONMENT = $(XORG_MALLOC_DEBUG_ENV)
AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
-INCLUDES = @XORG_INCS@
+AM_CPPFLAGS = @XORG_INCS@
TEST_LDADD=../libxservertest.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS) $(GLX_SYS_LIBS)
COMMON_SOURCES=protocol-common.h protocol-common.c
diff --git a/xorg-server/xkeyboard-config/compat/level5 b/xorg-server/xkeyboard-config/compat/level5
index 8d28051c1..8e0cc9c38 100644
--- a/xorg-server/xkeyboard-config/compat/level5
+++ b/xorg-server/xkeyboard-config/compat/level5
@@ -20,6 +20,7 @@ default partial xkb_compatibility "default" {
};
interpret ISO_Level5_Latch+Any {
+ useModMapMods= level1;
virtualModifier= LevelFive;
action= LatchMods(modifiers=LevelFive);
};
@@ -29,6 +30,7 @@ default partial xkb_compatibility "default" {
};
interpret ISO_Level5_Lock+Any {
+ useModMapMods= level1;
virtualModifier= LevelFive;
action= LockMods(modifiers=LevelFive);
};
diff --git a/xorg-server/xkeyboard-config/rules/base.extras.xml.in b/xorg-server/xkeyboard-config/rules/base.extras.xml.in
index 4647bec16..4b3c6234e 100644
--- a/xorg-server/xkeyboard-config/rules/base.extras.xml.in
+++ b/xorg-server/xkeyboard-config/rules/base.extras.xml.in
@@ -301,7 +301,7 @@
</variant>
<variant>
<configItem>
- <name>type6</name>
+ <name>sun_type6</name>
<_description>Polish (Sun Type 6/7)</_description>
</configItem>
</variant>
@@ -333,7 +333,7 @@
</variant>
<variant>
<configItem>
- <name>type6</name>
+ <name>sun_type6</name>
<_description>Romanian (Sun Type 6/7)</_description>
</configItem>
</variant>
@@ -381,7 +381,7 @@
</variant>
<variant>
<configItem>
- <name>type6</name>
+ <name>sun_type6</name>
<_description>Russian (Sun Type 6/7)</_description>
</configItem>
</variant>
diff --git a/xorg-server/xkeyboard-config/rules/base.xml.in b/xorg-server/xkeyboard-config/rules/base.xml.in
index 450154bb5..51c4ca59e 100644
--- a/xorg-server/xkeyboard-config/rules/base.xml.in
+++ b/xorg-server/xkeyboard-config/rules/base.xml.in
@@ -1414,7 +1414,7 @@
<variant>
<configItem>
<name>olpc2</name>
- <_description>English (layout toggle on multiply/divide key)</_description>
+ <_description>English (the divide/multiply keys toggle the layout)</_description>
</configItem>
</variant>
<variant>
@@ -1724,7 +1724,7 @@
<variant>
<configItem>
<name>oss_latin9</name>
- <_description>Belgian (alternative, latin-9 only)</_description>
+ <_description>Belgian (alternative, Latin-9 only)</_description>
</configItem>
</variant>
<variant>
@@ -1882,6 +1882,17 @@
</variant>
<variant>
<configItem>
+ <name>kan-kagapa</name>
+ <!-- Keyboard indicator for Kannada layouts -->
+ <_shortDescription>kn</_shortDescription>
+ <_description>Kannada (KaGaPa phonetic)</_description>
+ <languageList>
+ <iso639Id>kan</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
<name>mal</name>
<!-- Keyboard indicator for Malayalam layouts -->
<_shortDescription>ml</_shortDescription>
@@ -1990,6 +2001,17 @@
</variant>
<variant>
<configItem>
+ <name>tel-kagapa</name>
+ <!-- Keyboard indicator for Telugu layouts -->
+ <_shortDescription>te</_shortDescription>
+ <_description>Telugu (KaGaPa phonetic)</_description>
+ <languageList>
+ <iso639Id>tel</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
<name>urd-phonetic</name>
<!-- Keyboard indicator for Urdu layouts -->
<_shortDescription>ur</_shortDescription>
@@ -2045,6 +2067,39 @@
</variant>
<variant>
<configItem>
+ <name>hin-kagapa</name>
+ <!-- Keyboard indicator for Hindi layouts -->
+ <_shortDescription>hi</_shortDescription>
+ <_description>Hindi (KaGaPa phonetic)</_description>
+ <languageList>
+ <iso639Id>hin</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>san-kagapa</name>
+ <!-- Keyboard indicator for Sanskrit layouts -->
+ <_shortDescription>sa</_shortDescription>
+ <_description>Sanskrit (KaGaPa phonetic)</_description>
+ <languageList>
+ <iso639Id>san</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
+ <name>mar-kagapa</name>
+ <!-- Keyboard indicator for Marathi layouts -->
+ <_shortDescription>mr</_shortDescription>
+ <_description>Marathi (KaGaPa phonetic)</_description>
+ <languageList>
+ <iso639Id>mar</iso639Id>
+ </languageList>
+ </configItem>
+ </variant>
+ <variant>
+ <configItem>
<name>eng</name>
<!-- Keyboard indicator for English layouts -->
<_shortDescription>en</_shortDescription>
@@ -2125,7 +2180,7 @@
<variant>
<configItem>
<name>nativo-us</name>
- <_description>Portuguese (Brazil, nativo for USA keyboards)</_description>
+ <_description>Portuguese (Brazil, nativo for US keyboards)</_description>
</configItem>
</variant>
<variant>
@@ -2880,7 +2935,7 @@
<variant>
<configItem>
<name>oss_latin9</name>
- <_description>French (alternative, latin-9 only)</_description>
+ <_description>French (alternative, Latin-9 only)</_description>
</configItem>
</variant>
<variant>
@@ -2922,7 +2977,7 @@
<variant>
<configItem>
<name>bepo_latin9</name>
- <_description>French (Bepo, ergonomic, Dvorak way, latin-9 only)</_description>
+ <_description>French (Bepo, ergonomic, Dvorak way, Latin-9 only)</_description>
</configItem>
</variant>
<variant>
@@ -4087,7 +4142,7 @@
<variant>
<configItem>
<name>nativo-us</name>
- <_description>Portuguese (Nativo for USA keyboards)</_description>
+ <_description>Portuguese (Nativo for US keyboards)</_description>
</configItem>
</variant>
<variant>
@@ -5869,7 +5924,7 @@
<option>
<configItem>
<name>lv3:ralt_switch_multikey</name>
- <_description>Right Alt, Shift+Right Alt key is Multi_Key</_description>
+ <_description>Right Alt, Shift+Right Alt key is Compose</_description>
</configItem>
</option>
<option>
@@ -6086,7 +6141,7 @@
<option>
<configItem>
<name>kpdl:dotoss_latin9</name>
- <_description>Four-level key with dot, latin-9 restriction</_description>
+ <_description>Four-level key with dot, Latin-9 only</_description>
</configItem>
</option>
<option>
@@ -6112,7 +6167,7 @@
<option>
<configItem>
<name>kpdl:semi</name>
- <_description>Semi-colon on third level</_description>
+ <_description>Semicolon on third level</_description>
</configItem>
</option>
</group>
@@ -6193,7 +6248,7 @@
<option>
<configItem>
<name>caps:shiftlock</name>
- <_description>Caps Lock toggles Shift so all keys are affected</_description>
+ <_description>Caps Lock toggles ShiftLock (affects all keys)</_description>
</configItem>
</option>
<option>
@@ -6447,25 +6502,25 @@
<option>
<configItem>
<name>shift:both_capslock</name>
- <_description>Both Shift-Keys together toggle Caps Lock</_description>
+ <_description>Both Shift keys together toggle Caps Lock</_description>
</configItem>
</option>
<option>
<configItem>
<name>shift:both_capslock_cancel</name>
- <_description>Both Shift-Keys together activate Caps Lock, one Shift-Key deactivates</_description>
+ <_description>Both Shift keys together activate Caps Lock, one Shift key deactivates</_description>
</configItem>
</option>
<option>
<configItem>
<name>shift:both_shiftlock</name>
- <_description>Both Shift-Keys together toggle ShiftLock</_description>
+ <_description>Both Shift keys together toggle ShiftLock</_description>
</configItem>
</option>
<option>
<configItem>
<name>keypad:pointerkeys</name>
- <_description>Toggle PointerKeys with Shift + NumLock.</_description>
+ <_description>Shift + NumLock toggles PointerKeys</_description>
</configItem>
</option>
<option>
@@ -6710,18 +6765,18 @@
<group allowMultipleSelection="false">
<configItem>
<name>esperanto</name>
- <_description>Adding Esperanto circumflexes (supersigno)</_description>
+ <_description>Adding Esperanto supersigned letters</_description>
</configItem>
<option>
<configItem>
<name>esperanto:qwerty</name>
- <_description>To the corresponding key in a Qwerty keyboard.</_description>
+ <_description>To the corresponding key in a Qwerty layout</_description>
</configItem>
</option>
<option>
<configItem>
<name>esperanto:dvorak</name>
- <_description>To the corresponding key in a Dvorak keyboard.</_description>
+ <_description>To the corresponding key in a Dvorak layout</_description>
</configItem>
</option>
</group>
diff --git a/xorg-server/xkeyboard-config/symbols/be b/xorg-server/xkeyboard-config/symbols/be
index cf8e06871..286e9289e 100644
--- a/xorg-server/xkeyboard-config/symbols/be
+++ b/xorg-server/xkeyboard-config/symbols/be
@@ -110,7 +110,7 @@ xkb_symbols "oss_latin9" {
include "be(oss_frbe)"
include "keypad(oss_latin9)"
- name[Group1]="Belgian (alternative, latin-9 only)";
+ name[Group1]="Belgian (alternative, Latin-9 only)";
// First row
key <TLDE> { [ twosuperior, threesuperior, onesuperior, less ] }; // ² ³ ¹ <
diff --git a/xorg-server/xkeyboard-config/symbols/br b/xorg-server/xkeyboard-config/symbols/br
index dee718860..b75ffc98c 100644
--- a/xorg-server/xkeyboard-config/symbols/br
+++ b/xorg-server/xkeyboard-config/symbols/br
@@ -283,7 +283,7 @@ partial alphanumeric_keys
xkb_symbols "nativo-us" {
include "br(nativo)"
- name[Group1]="Portuguese (Brazil, nativo for USA keyboards)";
+ name[Group1]="Portuguese (Brazil, nativo for US keyboards)";
// Lower row
key <AB01> { [ y, Y, ccedilla, Ccedilla ] };
diff --git a/xorg-server/xkeyboard-config/symbols/de b/xorg-server/xkeyboard-config/symbols/de
index 20689af30..adc60ed36 100644
--- a/xorg-server/xkeyboard-config/symbols/de
+++ b/xorg-server/xkeyboard-config/symbols/de
@@ -107,8 +107,6 @@ xkb_symbols "deadacute" {
partial alphanumeric_keys
xkb_symbols "T3" {
- include "latin(type4)"
-
name[Group1]="German (T3)";
key.type[Group1] = "EIGHT_LEVEL";
@@ -151,7 +149,7 @@ xkb_symbols "T3" {
key <AC05> { [ g, G, seconds, NoSymbol, eng, ENG, dead_belowmacron, NoSymbol ] };
key <AC06> { [ h, H, U1E9E, NoSymbol, U0272, U019D, U0332, NoSymbol ] };
key <AC07> { [ j, J, dead_cedilla, NoSymbol, U0133, U0132, dead_belowring, NoSymbol ] };
- key <AC08> { [ k, K, dead_belowcomma, NoSymbol, kra, dead_belowcomma, U0335, NoSymbol ] };
+ key <AC08> { [ k, K, dead_belowcomma, NoSymbol, kra, dead_belowcomma, dead_stroke, NoSymbol ] };
key <AC09> { [ l, L, dead_ogonek, NoSymbol, lstroke, Lstroke, U0338, NoSymbol ] };
key <AC10> { [ odiaeresis, Odiaeresis, dead_belowdot, NoSymbol, dead_acute, dead_doubleacute, degree, NoSymbol ] };
key <AC11> { [ adiaeresis, Adiaeresis, dead_stroke, NoSymbol, U019B, U1E9E, minutes, NoSymbol ] };
@@ -176,10 +174,12 @@ xkb_symbols "T3" {
include "kpdl(comma)"
- // We do not support the correct level selection mechanism yet, this is
- //just for testing:
- include "level5(rctrl_switch)"
- include "level3(ralt_switch)"
+ include "level5(modifier_mapping)"
+ include "level3(modifier_mapping)"
+ key.type[Group1] = "THREE_LEVEL";
+ key <LFSH> { [ Shift_L, Shift_L, ISO_Level5_Latch ] };
+ key <RTSH> { [ Shift_R, Shift_R, ISO_Level5_Latch ] };
+ key <RALT> { [ ISO_Level3_Latch, ISO_Level5_Latch, ISO_Level5_Latch ] };
};
partial alphanumeric_keys
diff --git a/xorg-server/xkeyboard-config/symbols/es b/xorg-server/xkeyboard-config/symbols/es
index 5adf1a2bb..ea4a28b1f 100644
--- a/xorg-server/xkeyboard-config/symbols/es
+++ b/xorg-server/xkeyboard-config/symbols/es
@@ -200,7 +200,7 @@ xkb_symbols "olpcm" {
// See: http://wiki.laptop.org/go/OLPC_Spanish_Non-membrane_Keyboard
include "us(basic)"
- name[Group1]="Spain";
+ name[Group1]="Spanish";
key <AE00> { [ questiondown, exclamdown, backslash ] };
key <AE01> { [ 1, exclam, bar ] };
diff --git a/xorg-server/xkeyboard-config/symbols/fr b/xorg-server/xkeyboard-config/symbols/fr
index 0d1d13de8..418ff5200 100644
--- a/xorg-server/xkeyboard-config/symbols/fr
+++ b/xorg-server/xkeyboard-config/symbols/fr
@@ -200,7 +200,7 @@ xkb_symbols "oss_latin9" {
include "fr(oss)"
include "keypad(oss_latin9)"
- name[Group1]="French (alternative, latin-9 only)";
+ name[Group1]="French (alternative, Latin-9 only)";
// First row
key <AE01> { [ ampersand, 1, dead_caron, dead_cedilla ] }; // & 1 ˇ ¸
@@ -547,7 +547,7 @@ xkb_symbols "bepo_latin9" {
include "fr(bepo)"
include "keypad(oss_latin9)"
- name[Group1]="French (Bepo, ergonomic, Dvorak way, latin-9 only)";
+ name[Group1]="French (Bepo, ergonomic, Dvorak way, Latin-9 only)";
key <TLDE> { [ dollar, numbersign, dollar, paragraph ] }; // $ # $ ¶
diff --git a/xorg-server/xkeyboard-config/symbols/in b/xorg-server/xkeyboard-config/symbols/in
index b995fbb98..64c3ea1dd 100644
--- a/xorg-server/xkeyboard-config/symbols/in
+++ b/xorg-server/xkeyboard-config/symbols/in
@@ -1,9 +1,10 @@
// This layout includes all Indian layouts, including:
+// - Devanagari (Hindi, Marathi, Sanskrit)
// - Bengali
-// - Gujarati
-// - Kannada
+// - Gujarati
+// - Kannada
// - Malayalam
-// - Oriya
+// - Oriya
// - Tamil
// - Telugu
// - Urdu
@@ -1753,3 +1754,266 @@ xkb_symbols "mal_enhanced" {
};
+
+// ---- BEGIN Hindi KaGaPa phonetic ----
+// Name: KaGaPa phonetic
+// Brief: Devanagari layout (Hindi, Sanskrit, Nepali, Marathi, etc.)
+// Diagram: (Original)[http://baraha.com/help/Keyboards/dev_brhkbd.htm]
+// (This layout)[http://bdsatish.in/lang/dev-kagapa.png]
+//
+// Description: Based on KaGaPa layout (also called Baraha layout or Nudi layout)
+// which is a modified layout of the specification by Dr. K. P. Rao.
+// This is a phonetic layout with the following features:
+// [1] All letters are mapped to phonetically-similar English keys
+// as much as possible.
+// [2] The independent vowel (svara) and its dependent vowel (maatra)
+// use the same key (depending upon SHIFT, ALTGR or ALTGR + SHIFT).
+// [3] Consonant conjuncts are produced by explicitly invoking the
+// 'viraama' (key f). The 'short a' maatra is implicit in all
+// consonants.
+// [4] Zero width non-joiner and joiner are on keys 6 and 7
+// respectively. These are absolutely essential for alternative
+// glyph renderings of consonant half-forms.
+// [5] Rigvedic accent marks, visarga variants.
+//
+// Author: Satish BD <bdsatish@gmail.com>
+//
+partial alphanumeric_keys
+xkb_symbols "hin-kagapa" {
+ name[Group1] = "Hindi (KaGaPa phonetic)";
+ key.type="FOUR_LEVEL";
+
+ //Top Alphanumeric row
+ // Roman digits
+ key <TLDE> { [ apostrophe, asciitilde, U201C ] }; // U201C: left double quotation mark
+ key <AE01> { [ 1, exclam, U0967 ] };
+ key <AE02> { [ 2, at, U0968, U20A8 ] }; // U20A8: generic rupee sign (Rs)
+ key <AE03> { [ 3, numbersign, U0969 ] };
+ key <AE04> { [ 4, dollar, U096A, U20B9 ] }; // U20B9: new Indian Rupee sign
+ key <AE05> { [ 5, percent, U096B ] };
+ key <AE06> { [ 6, asciicircum, U096C, U200C ] }; // ZWNJ
+ key <AE07> { [ 7, ampersand, U096D, U200D ] }; // ZWJ
+ key <AE08> { [ 8, asterisk, U096E, U0901 ] }; // U0901: Devanagari candrabindu
+ key <AE09> { [ 9, parenleft, U096F ] };
+ key <AE10> { [ 0, parenright, U0966, U0970 ] }; // U0970: Devanagari abbreviation sign
+ key <AE11> { [ minus, underscore, U0952 ] }; // U0952: Devanagari stress sign anudatta
+ key <AE12> { [ equal, plus ] };
+ key <BKSL> { [ U005C, U007C, U0964, U0965 ] }; // backslash, pipe, danda, double danda
+
+ //Q Row
+ key <AD01> { [ U091F, U0920 ] }; // Q: retroflex Ta, Tha
+ key <AD02> { [ U0921, U0922, U095C, U095D ] }; // W: retroflex Da, Dha, Da-nukta, Dha-nukta
+ key <AD03> { [ U0946, U0947, U090E, U090F ] }; // E: matras, short E, long E
+ key <AD04> { [ U0930, U0943, U090B, U0931 ] }; // R: ra, vocalic R matra, vocalic R, ra-nukta
+ key <AD05> { [ U0924, U0925 ] }; // T: dental ta, tha
+ key <AD06> { [ U092F, U0948, U0910, U095F ] }; // Y: ya, ai matra, ai, ya-nukta
+ key <AD07> { [ U0941, U0942, U0909, U090A ] }; // U: matras, u, uu
+ key <AD08> { [ U093F, U0940, U0907, U0908 ] }; // I: matras, i, ii
+ key <AD09> { [ U094A, U094B, U0912, U0913 ] }; // O: matras, short o, long o
+ key <AD10> { [ U092A, U092B, U095E ] }; // P: pa, pha, pha-nukta
+ key <AD11> { [ bracketleft, braceleft ] };
+ key <AD12> { [ bracketright, braceright ] };
+
+ //A Row
+ key <AC01> { [ U093E, U0906, U0905, U0972 ] }; // A: aa matra, aa, short a, candra a
+ key <AC02> { [ U0938, U0936 ] }; // S: sa, sha
+ key <AC03> { [ U0926, U0927 ] }; // D: dental da, dha
+ key <AC04> { [ U094D, U0944, U0960 ] }; // F: virama, vocalic RR matra, vocalic RR
+ key <AC05> { [ U0917, U0918, U095A ] }; // G: ga, gha, ga-nukta
+ key <AC06> { [ U0939, U0903, U1CF5, U1CF6 ] }; // H: ha, visarga, jihvamuliya, upadhmaniya
+ key <AC07> { [ U091C, U091D, U095B ] }; // J: ja, jha, ja-nukta
+ key <AC08> { [ U0915, U0916, U0958, U0959 ] }; // K: ka, kha, ka-nukta, kha-nukta
+ key <AC09> { [ U0932, U0933, U0962, U090C ] }; // L: la, lla, vocalic L matra, vocalic L
+ key <AC10> { [ semicolon, colon, U1CF2, U1CF3 ] }; // U1CF2/3: ardhavisarga/rotated ardhavisarga
+ key <AC11> { [ apostrophe, quotedbl, U0951, U201D ] }; // U0951: Devanagari stress sign udatta
+ // U201D: Right double quotation mark
+
+ //Z Row
+ key <AB01> { [ U091E, U0919 ] }; // Z: nya, nga
+ key <AB02> { [ U0937, U093C, U0934 ] }; // X: ssa, nukta below, lla-nukta
+ key <AB03> { [ U091A, U091B ] }; // C: ca, cha
+ key <AB04> { [ U0935, U094C, U0914 ] }; // V: va, matra au, au
+ key <AB05> { [ U092C, U092D ] }; // B: ba, bha
+ key <AB06> { [ U0928, U0923, U0929 ] }; // N: na, nna, nnna
+ key <AB07> { [ U092E, U0902, U093D, U0950 ] }; // M: ma, anusvara, avagraha, Devanagari OM
+ key <AB08> { [ comma, U003C, U0945, U090D ] }; // comma: comma, less than, matra, candra e
+ key <AB09> { [ period, U003E, U0949, U0911 ] }; // period: period, greater than, matra, candra o
+ key <AB10> { [ slash, question ] };
+
+ include "level3(ralt_switch)"
+};
+// ---- END Hindi KaGaPa ----
+
+// Sanskrit uses Devanagari layout of Hindi
+partial alphanumeric_keys
+xkb_symbols "san-kagapa" {
+ name[Group1] = "Sanskrit (KaGaPa phonetic)";
+ include "in(hin-kagapa)"
+
+};
+
+// Marathi uses Devanagari layout of Hindi
+partial alphanumeric_keys
+xkb_symbols "mar-kagapa" {
+ name[Group1] = "Marathi (KaGaPa phonetic)";
+ include "in(hin-kagapa)"
+
+};
+
+
+// ---- BEGIN Kannada KaGaPa phonetic ----
+// Name: Kannada KaGaPa phonetic
+// Diagram: (Original)[http://www.baraha.com/help/Keyboards/kan_brhkbd.htm]
+// (This layout)[http://bdsatish.in/lang/kan-kagapa.png]
+//
+// Description: Based on KaGaPa layout (also called Baraha layout or Nudi layout).
+// See the description to "hin-kagapa" above.
+// Certain punctuation characters from Devanagari block are
+// retained for compatibility.
+//
+// Author: Satish BD <bdsatish@gmail.com>
+//
+partial alphanumeric_keys
+xkb_symbols "kan-kagapa" {
+ name[Group1] = "Kannada (KaGaPa phonetic)";
+ key.type="FOUR_LEVEL";
+
+ //Top Alphanumeric row
+ // Roman digits
+ key <TLDE> { [ apostrophe, asciitilde, U201C ] }; // U201C: left double quotation mark
+ key <AE01> { [ 1, exclam, U0CE7 ] };
+ key <AE02> { [ 2, at, U0CE8, U20A8 ] }; // U20A8: generic rupee sign (Rs)
+ key <AE03> { [ 3, numbersign, U0CE9 ] };
+ key <AE04> { [ 4, dollar, U0CEA, U20B9 ] }; // U20B9: new Indian Rupee sign
+ key <AE05> { [ 5, percent, U0CEB ] };
+ key <AE06> { [ 6, asciicircum, U0CEC, U200C ] }; // ZWNJ
+ key <AE07> { [ 7, ampersand, U0CED, U200D ] }; // ZWJ
+ key <AE08> { [ 8, asterisk, U0CEE, U0901 ] }; // U0901: Devanagari candrabindu
+ key <AE09> { [ 9, parenleft, U0CEF ] };
+ key <AE10> { [ 0, parenright, U0CE6 ] };
+ key <AE11> { [ minus, underscore, U0952 ] }; // U0952: Devanagari stress sign anudatta
+ key <AE12> { [ equal, plus ] };
+ key <BKSL> { [ U005C, U007C, U0964, U0965 ] }; // backslash, pipe, danda, double danda
+
+ //Q Row
+ key <AD01> { [ U0C9F, U0CA0 ] }; // Q: retroflex Ta, Tha
+ key <AD02> { [ U0CA1, U0CA2 ] }; // W: retroflex Da, Dha
+ key <AD03> { [ U0CC6, U0CC7, U0C8E, U0C8F ] }; // E: matras, short E, long E
+ key <AD04> { [ U0CB0, U0CC3, U0C8B, U0CB1 ] }; // R: ra, vocalic R matra, vocalic R, RRA
+ key <AD05> { [ U0CA4, U0CA5 ] }; // T: dental ta, tha
+ key <AD06> { [ U0CAF, U0CC8, U0C90 ] }; // Y: ya, ai matra, ai
+ key <AD07> { [ U0CC1, U0CC2, U0C89, U0C8A ] }; // U: matras, u, uu
+ key <AD08> { [ U0CBF, U0CC0, U0C87, U0C88 ] }; // I: matras, i, ii
+ key <AD09> { [ U0CCA, U0CCB, U0C92, U0C93 ] }; // O: matras, short o, long o
+ key <AD10> { [ U0CAA, U0CAB ] }; // P: pa, pha
+ key <AD11> { [ bracketleft, braceleft ] };
+ key <AD12> { [ bracketright, braceright ] };
+
+ //A Row
+ key <AC01> { [ U0CBE, U0C86, U0C85 ] }; // A: aa matra, aa, short a
+ key <AC02> { [ U0CB8, U0CB6 ] }; // S: sa, sha
+ key <AC03> { [ U0CA6, U0CA7 ] }; // D: dental da, dha
+ key <AC04> { [ U0CCD, U0CC4, U0CE0 ] }; // F: virama, vocalic RR matra, vocalic RR
+ key <AC05> { [ U0C97, U0C98 ] }; // G: ga, gha
+ key <AC06> { [ U0CB9, U0C83, U0CF1, U0CF2 ] }; // H: ha, visarga, jihvanuliya, upadhmaniya
+ key <AC07> { [ U0C9C, U0C9D ] }; // J: ja, jha
+ key <AC08> { [ U0C95, U0C96 ] }; // K: ka, kha
+ key <AC09> { [ U0CB2, U0CB3, U0CE2, U0C8C ] }; // L: la, lla, vocalic L matra, vocalic L
+ key <AC10> { [ semicolon, colon ] };
+ key <AC11> { [ apostrophe, quotedbl, U0951, U201D ] }; // U0951: Devanagari stress sign udatta
+ // U201D: Right double quotation mark
+
+ //Z Row
+ key <AB01> { [ U0C9E, U0C99 ] }; // Z: nya, nga
+ key <AB02> { [ U0CB7, U0CBC, U0CDE ] }; // X: ssa, nukta below, LLLA
+ key <AB03> { [ U0C9A, U0C9B ] }; // C: ca, cha
+ key <AB04> { [ U0CB5, U0CCC, U0C94 ] }; // V: va, matra au, au
+ key <AB05> { [ U0CAC, U0CAD ] }; // B: ba, bha
+ key <AB06> { [ U0CA8, U0CA3 ] }; // N: na, nna
+ key <AB07> { [ U0CAE, U0C82, U0CBD, U0950 ] }; // M: ma, anusvara, avagraha, Devanagari OM
+ key <AB08> { [ comma, U003C, U0CB1 ] }; // comma: comma, less than, RRA
+ key <AB09> { [ period, U003E, U0CDE ] }; // period: period, greater than, LLLA
+ key <AB10> { [ slash, question ] };
+
+ include "level3(ralt_switch)"
+};
+// ---- END Kannada KaGaPa ----
+
+
+// ---- BEGIN Telugu KaGaPa phonetic ----
+// Name: Telugu KaGaPa phonetic
+// Diagram: (Original)[http://www.baraha.com/help/Keyboards/tel_brhkbd.htm]
+// (This layout)[http://bdsatish.in/lang/tel-kagapa.png]
+//
+// Description: Based on KaGaPa layout (also called Baraha layout or Nudi layout).
+// See the description to "hin-kagapa" above.
+// Certain punctuation characters from Devanagari block are
+// retained for compatibility.
+//
+// Author: Satish BD <bdsatish@gmail.com>
+//
+partial alphanumeric_keys
+xkb_symbols "tel-kagapa" {
+ name[Group1] = "Telugu (KaGaPa phonetic)";
+ key.type="FOUR_LEVEL";
+
+ //Top Alphanumeric row
+ // Roman digits
+ key <TLDE> { [ apostrophe, asciitilde, U201C ] }; // U201C: left double quotation mark
+ key <AE01> { [ 1, exclam, U0C67 ] };
+ key <AE02> { [ 2, at, U0C68, U20A8 ] }; // U20A8: generic rupee sign (Rs)
+ key <AE03> { [ 3, numbersign, U0C69 ] };
+ key <AE04> { [ 4, dollar, U0C6A, U20B9 ] }; // U20B9: new Indian Rupee sign
+ key <AE05> { [ 5, percent, U0C6B ] };
+ key <AE06> { [ 6, asciicircum, U0C6C, U200C ] }; // ZWNJ
+ key <AE07> { [ 7, ampersand, U0C6D, U200D ] }; // ZWJ
+ key <AE08> { [ 8, asterisk, U0C6E, U0C01 ] }; // U0C01: Telugu arasunna
+ key <AE09> { [ 9, parenleft, U0C6F ] };
+ key <AE10> { [ 0, parenright, U0C66 ] };
+ key <AE11> { [ minus, underscore, U0952 ] }; // U0952: Devanagari stress sign anudatta
+ key <AE12> { [ equal, plus ] };
+ key <BKSL> { [ U005C, U007C, U0964, U0965 ] }; // backslash, pipe, danda, double danda
+
+ //Q Row
+ key <AD01> { [ U0C1F, U0C20 ] }; // Q: retroflex Ta, Tha
+ key <AD02> { [ U0C21, U0C22 ] }; // W: retroflex Da, Dha
+ key <AD03> { [ U0C46, U0C47, U0C0E, U0C0F ] }; // E: matras, short E, long E
+ key <AD04> { [ U0C30, U0C43, U0C0B, U0C31 ] }; // R: ra, vocalic R matra, vocalic R, RRA
+ key <AD05> { [ U0C24, U0C25 ] }; // T: dental ta, tha
+ key <AD06> { [ U0C2F, U0C48, U0C10 ] }; // Y: ya, ai matra, ai
+ key <AD07> { [ U0C41, U0C42, U0C09, U0C0A ] }; // U: matras, u, uu
+ key <AD08> { [ U0C3F, U0C40, U0C07, U0C08 ] }; // I: matras, i, ii
+ key <AD09> { [ U0C4A, U0C4B, U0C12, U0C13 ] }; // O: matras, short o, long o
+ key <AD10> { [ U0C2A, U0C2B ] }; // P: pa, pha
+ key <AD11> { [ bracketleft, braceleft ] };
+ key <AD12> { [ bracketright, braceright ] };
+
+ //A Row
+ key <AC01> { [ U0C3E, U0C06, U0C05 ] }; // A: aa matra, aa, short a
+ key <AC02> { [ U0C38, U0C36 ] }; // S: sa, sha
+ key <AC03> { [ U0C26, U0C27 ] }; // D: dental da, dha
+ key <AC04> { [ U0C4D, U0C44, U0C60 ] }; // F: virama, vocalic RR matra, vocalic RR
+ key <AC05> { [ U0C17, U0C18 ] }; // G: ga, gha
+ key <AC06> { [ U0C39, U0C03 ] }; // H: ha, visarga
+ key <AC07> { [ U0C1C, U0C1D ] }; // J: ja, jha
+ key <AC08> { [ U0C15, U0C16 ] }; // K: ka, kha
+ key <AC09> { [ U0C32, U0C33, U0C62, U0C0C ] }; // L: la, lla, vocalic L matra, vocalic L
+ key <AC10> { [ semicolon, colon ] };
+ key <AC11> { [ apostrophe, quotedbl, U0951, U201D ] }; // U0951: Devanagari stress sign udatta
+ // U201D: Right double quotation mark
+
+ //Z Row
+ key <AB01> { [ U0C1E, U0C19 ] }; // Z: nya, nga
+ key <AB02> { [ U0C37 ] }; // X: ssa
+ key <AB03> { [ U0C1A, U0C1B ] }; // C: ca, cha
+ key <AB04> { [ U0C35, U0C4C, U0C14 ] }; // V: va, matra au, au
+ key <AB05> { [ U0C2C, U0C2D ] }; // B: ba, bha
+ key <AB06> { [ U0C28, U0C23 ] }; // N: na, nna
+ key <AB07> { [ U0C2E, U0C02, U0C3D, U0950 ] }; // M: ma, anusvara, avagraha, Devanagari OM
+ key <AB08> { [ comma, U003C, U0C58 ] }; // comma: comma, less than, TSA
+ key <AB09> { [ period, U003E, U0C59 ] }; // period: period, greater than, DZA
+ key <AB10> { [ slash, question ] };
+
+ include "level3(ralt_switch)"
+};
+// ---- END Telugu KaGaPa ----
diff --git a/xorg-server/xkeyboard-config/symbols/latin b/xorg-server/xkeyboard-config/symbols/latin
index 424768ead..8cabe73e3 100644
--- a/xorg-server/xkeyboard-config/symbols/latin
+++ b/xorg-server/xkeyboard-config/symbols/latin
@@ -105,7 +105,7 @@ xkb_symbols "type3" {
key <AC05> { [ g, G, bracketright, ENG ] };
key <AC08> { [ k, K, lstroke, ampersand ] };
- key <AB01> { [ y, Y, guillemotleft, less ] };
+ key <AB01> { [ y, Y, guillemotleft, less ] };
key <AB04> { [ v, V, at, grave ] };
key <AB05> { [ b, B, braceleft, apostrophe ] };
key <AB06> { [ n, N, braceright, braceright ] };
@@ -114,9 +114,9 @@ xkb_symbols "type3" {
key <AB09> { [ period, colon, greater, division ] };
};
-// Another one Latin common layout
+// Another common Latin layout
// (German, Estonian, Spanish, Icelandic, Italian, Latin American, Portuguese)
-
+
partial
xkb_symbols "type4" {
@@ -150,7 +150,7 @@ xkb_symbols "nodeadkeys" {
partial
xkb_symbols "type2_nodeadkeys" {
-
+
include "latin(nodeadkeys)"
key <AD11> { [ aring, Aring, diaeresis, degree ] };
@@ -162,13 +162,13 @@ xkb_symbols "type2_nodeadkeys" {
partial
xkb_symbols "type3_nodeadkeys" {
-
+
include "latin(nodeadkeys)"
};
partial
xkb_symbols "type4_nodeadkeys" {
-
+
include "latin(nodeadkeys)"
key <AB10> { [ minus, underscore, dead_belowdot, abovedot ] };
@@ -178,12 +178,12 @@ xkb_symbols "type4_nodeadkeys" {
// See http://marcinwolinski.pl/keyboard/ for a description.
// Used by pl(intl)
//
-// ┌────┐
-// │ 2 4│ 2 = Shift, 4 = Level3 + Shift
-// │ 1 3│ 1 = Normal, 3 = Level3
-// └────┘
+// ┌─────┐
+// │ 2 4 │ 2 = Shift, 4 = Level3 + Shift
+// │ 1 3 │ 1 = Normal, 3 = Level3
+// └─────┘
// ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┲━━━━━━━━━┓
-// │ ~ ~ │ ! ' │ @ " │ # ˝ │ $ ¸ │ % ˇ │ ^ ^ │ & ˘ │ * ˙ │ ( ̣ │ ) ° │ _ ¯ │ + ˛ ┃ ⌫ Back ┃
+// │ ~ ~ │ ! ' │ @ " │ # ˝ │ $ ¸ │ % ˇ │ ^ ^ │ & ˘ │ * ̇ │ ( ̣ │ ) ° │ _ ¯ │ + ˛ ┃ ⌫ Back- ┃
// │ ` ` │ 1 ¡ │ 2 © │ 3 • │ 4 § │ 5 € │ 6 ¢ │ 7 − │ 8 × │ 9 ÷ │ 0 ° │ - – │ = — ┃ space ┃
// ┢━━━━━┷━┱───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┺━┳━━━━━━━┫
// ┃ ┃ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { « │ } » ┃ Enter ┃
@@ -198,7 +198,7 @@ xkb_symbols "type4_nodeadkeys" {
// ┃ ┃ ┃ ┃ ␣ ⍽ ┃ ┃ ┃ ┃
// ┃Ctrl ┃Meta ┃Alt ┃ ␣ Space ⍽ ┃AltGr ⇮┃Menu ┃Ctrl ┃
// ┗━━━━━━━┻━━━━━━━┻━━━━━━━┹───────────────────────────────────┺━━━━━━━┻━━━━━━━┻━━━━━━━┛
-
+
partial
xkb_symbols "intl" {
diff --git a/xorg-server/xkeyboard-config/symbols/pt b/xorg-server/xkeyboard-config/symbols/pt
index e42b40808..b2e0b1255 100644
--- a/xorg-server/xkeyboard-config/symbols/pt
+++ b/xorg-server/xkeyboard-config/symbols/pt
@@ -186,7 +186,7 @@ partial alphanumeric_keys
xkb_symbols "nativo-us" {
include "pt(nativo)"
- name[Group1]="Portuguese (Nativo for USA keyboards)";
+ name[Group1]="Portuguese (Nativo for US keyboards)";
// Lower row
key <AB01> { [ y, Y, ccedilla, Ccedilla ] };
diff --git a/xorg-server/xkeyboard-config/symbols/us b/xorg-server/xkeyboard-config/symbols/us
index b34bedc0f..5ad2ae072 100644
--- a/xorg-server/xkeyboard-config/symbols/us
+++ b/xorg-server/xkeyboard-config/symbols/us
@@ -853,7 +853,7 @@ xkb_symbols "altgr-intl" {
partial alphanumeric_keys
xkb_symbols "classmate" {
include "us(basic)"
- name[Group1]= "USA - ClassmatePC";
+ name[Group1]= "English (US)";
key <LSGT> { [ backslash, bar, backslash, bar ] };
@@ -1052,14 +1052,14 @@ xkb_symbols "olpc" {
partial alphanumeric_keys
xkb_symbols "olpc2" {
include "us(olpc)"
- name[Group1]= "English (layout toggle on multiply/divide key)";
+ name[Group1]= "English (the divide/multiply keys toggle the layout)";
include "group(olpc)"
};
xkb_symbols "olpcm" {
include "us(basic)"
- name[Group1]= "USA";
+ name[Group1]= "English (US)";
// Mechanical (non-membrane) OLPC int'l US English keyboard layout.
// See: http://wiki.laptop.org/go/OLPC_English_Non-membrane_Keyboard
diff --git a/xorg-server/xkeyboard-config/tests/genLists4Comparizon.sh b/xorg-server/xkeyboard-config/tests/genLists4Comparizon.sh
index 90981a939..5756d3ff2 100644
--- a/xorg-server/xkeyboard-config/tests/genLists4Comparizon.sh
+++ b/xorg-server/xkeyboard-config/tests/genLists4Comparizon.sh
@@ -13,7 +13,9 @@ F1b=${F1}base
F1e=${F1}extras
xsltproc $ROOT/xslt/reg2ll.xsl $ROOT/rules/base.xml > $F1b
-xsltproc $ROOT/xslt/reg2ll.xsl $ROOT/rules/base.extras.xml > $F1e
+xsltproc $ROOT/xslt/reg2ll.xsl $ROOT/rules/base.extras.xml | \
+ grep -v "sun_type" > $F1e
+
cat $F1b $F1e | sort | uniq > $F1
rm -f $F1e $F1e
@@ -39,7 +41,7 @@ for i in $ROOT/symbols/*; do
} else
{
name=$2;
- if (variant == "olpc" || variant == "htcdream")
+ if (variant == "olpc" || variant == "htcdream" || variant == "olpcm" || variant == "classmate")
printf "%s:\"%s\"\n", id, name;
else
printf "%s(%s):\"%s\"\n", id, variant, name;