aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2013-11-08 11:09:17 +0100
committermarha <marha@users.sourceforge.net>2013-11-08 11:09:17 +0100
commit401eb04e4dfb179291befb19d74e2e3148c4e268 (patch)
treebb9056b67a7bdf37cba96fecc69ce81b1809fb03
parentf7050e0ff2d1dd147ff5ef45f8ff7d8d7833db48 (diff)
downloadvcxsrv-401eb04e4dfb179291befb19d74e2e3148c4e268.tar.gz
vcxsrv-401eb04e4dfb179291befb19d74e2e3148c4e268.tar.bz2
vcxsrv-401eb04e4dfb179291befb19d74e2e3148c4e268.zip
libxtrans libxcb xcb-proto mesa git update 8 nov 2013
libxcb commit e8663a935890ff366f49e356211049dfd0d9756a libxcb/xcb-proto commit 29beba6bf02bda86a5b163ace63e1d0a4d3eee5b libxtrans commit 0153d1670e4a1883e1bb6dd971435d6268eac5ba mesa commit 035cce83f7b3d9a037c9e7cc17a212d6cf7e927f
-rw-r--r--X11/xtrans/Xtrans.c9
-rw-r--r--X11/xtrans/Xtrans.h6
-rw-r--r--X11/xtrans/Xtransint.h6
-rw-r--r--X11/xtrans/Xtranslcl.c35
-rw-r--r--X11/xtrans/Xtranssock.c110
-rw-r--r--X11/xtrans/configure.ac2
-rw-r--r--X11/xtrans/xtrans.m435
-rw-r--r--libxcb/Makefile.am6
-rw-r--r--libxcb/configure.ac59
-rw-r--r--libxcb/src/.gitignore2
-rw-r--r--libxcb/src/Makefile.am18
-rw-r--r--libxcb/src/c_client.py69
-rw-r--r--libxcb/src/xcb.h58
-rw-r--r--libxcb/src/xcb_conn.c36
-rw-r--r--libxcb/src/xcb_in.c290
-rw-r--r--libxcb/src/xcb_out.c18
-rw-r--r--libxcb/src/xcbext.h6
-rw-r--r--libxcb/src/xcbint.h17
-rw-r--r--libxcb/xcb-dri3.pc.in11
-rw-r--r--libxcb/xcb-present.pc.in11
-rw-r--r--libxcb/xcb-proto/configure.ac2
-rw-r--r--libxcb/xcb-proto/src/present.xml2
-rw-r--r--libxcb/xcb-proto/src/xcb.xsd4
-rw-r--r--libxcb/xcb-proto/xcbgen/xtypes.py38
-rw-r--r--mesalib/configure.ac82
-rw-r--r--mesalib/docs/GL3.txt12
-rw-r--r--mesalib/docs/relnotes/10.0.html3
-rw-r--r--mesalib/docs/specs/MESA_query_renderer.spec405
-rw-r--r--mesalib/include/GL/glx.h27
-rw-r--r--mesalib/include/GL/internal/dri_interface.h167
-rw-r--r--mesalib/src/gallium/SConscript8
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_format.c16
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_format.h18
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_math.h13
-rw-r--r--mesalib/src/glsl/Makefile.sources1
-rw-r--r--mesalib/src/glsl/ast.h15
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp63
-rw-r--r--mesalib/src/glsl/ast_type.cpp13
-rw-r--r--mesalib/src/glsl/builtin_functions.cpp3
-rw-r--r--mesalib/src/glsl/glsl_lexer.ll2
-rw-r--r--mesalib/src/glsl/glsl_parser.yy13
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h3
-rw-r--r--mesalib/src/glsl/link_atomics.cpp277
-rw-r--r--mesalib/src/glsl/linker.cpp21
-rw-r--r--mesalib/src/glsl/linker.h8
-rw-r--r--mesalib/src/mapi/glapi/Makefile.am5
-rw-r--r--mesalib/src/mapi/glapi/gen/ARB_vertex_attrib_binding.xml58
-rw-r--r--mesalib/src/mapi/glapi/gen/Makefile.am7
-rw-r--r--mesalib/src/mapi/glapi/gen/gl_API.xml6
-rw-r--r--mesalib/src/mesa/.gitignore (renamed from mesalib/src/mesa/x86/.gitignore)0
-rw-r--r--mesalib/src/mesa/Makefile.am33
-rw-r--r--mesalib/src/mesa/drivers/dri/common/dri_util.c156
-rw-r--r--mesalib/src/mesa/drivers/dri/common/dri_util.h14
-rw-r--r--mesalib/src/mesa/drivers/dri/common/utils.c64
-rw-r--r--mesalib/src/mesa/drivers/dri/common/utils.h3
-rw-r--r--mesalib/src/mesa/main/api_arrayelt.c43
-rw-r--r--mesalib/src/mesa/main/arrayobj.c73
-rw-r--r--mesalib/src/mesa/main/arrayobj.h5
-rw-r--r--mesalib/src/mesa/main/attrib.c7
-rw-r--r--mesalib/src/mesa/main/bufferobj.c28
-rw-r--r--mesalib/src/mesa/main/bufferobj.h9
-rw-r--r--mesalib/src/mesa/main/context.c6
-rw-r--r--mesalib/src/mesa/main/dd.h9
-rw-r--r--mesalib/src/mesa/main/enable.c2
-rw-r--r--mesalib/src/mesa/main/extensions.c2
-rw-r--r--mesalib/src/mesa/main/get.c30
-rw-r--r--mesalib/src/mesa/main/get_hash_params.py18
-rw-r--r--mesalib/src/mesa/main/getstring.c49
-rw-r--r--mesalib/src/mesa/main/glformats.c5
-rw-r--r--mesalib/src/mesa/main/mtypes.h76
-rw-r--r--mesalib/src/mesa/main/state.c4
-rw-r--r--mesalib/src/mesa/main/streaming-load-memcpy.c85
-rw-r--r--mesalib/src/mesa/main/streaming-load-memcpy.h33
-rw-r--r--mesalib/src/mesa/main/varray.c699
-rw-r--r--mesalib/src/mesa/main/varray.h77
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_array.c11
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c2
-rw-r--r--mesalib/src/mesa/vbo/vbo_attrib_tmp.h32
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_array.c12
-rw-r--r--mesalib/src/mesa/x86/Makefile.am49
80 files changed, 3238 insertions, 494 deletions
diff --git a/X11/xtrans/Xtrans.c b/X11/xtrans/Xtrans.c
index 7c7967f5d..735d7b87f 100644
--- a/X11/xtrans/Xtrans.c
+++ b/X11/xtrans/Xtrans.c
@@ -866,12 +866,20 @@ TRANS(Write) (XtransConnInfo ciptr, char *buf, int size)
}
int
+TRANS(Readv) (XtransConnInfo ciptr, struct iovec *buf, int size)
+
+{
+ return ciptr->transptr->Readv (ciptr, buf, size);
+}
+
+int
TRANS(Writev) (XtransConnInfo ciptr, struct iovec *buf, int size)
{
return ciptr->transptr->Writev (ciptr, buf, size);
}
+#if XTRANS_SEND_FDS
int
TRANS(SendFd) (XtransConnInfo ciptr, int fd, int do_close)
{
@@ -883,6 +891,7 @@ TRANS(RecvFd) (XtransConnInfo ciptr)
{
return ciptr->transptr->RecvFd(ciptr);
}
+#endif
int
TRANS(Disconnect) (XtransConnInfo ciptr)
diff --git a/X11/xtrans/Xtrans.h b/X11/xtrans/Xtrans.h
index 53b8b627d..69accd780 100644
--- a/X11/xtrans/Xtrans.h
+++ b/X11/xtrans/Xtrans.h
@@ -344,6 +344,12 @@ int TRANS(Write)(
int /* size */
);
+int TRANS(Readv)(
+ XtransConnInfo, /* ciptr */
+ struct iovec *, /* buf */
+ int /* size */
+);
+
int TRANS(Writev)(
XtransConnInfo, /* ciptr */
struct iovec *, /* buf */
diff --git a/X11/xtrans/Xtransint.h b/X11/xtrans/Xtransint.h
index dd886db87..1f32f0cae 100644
--- a/X11/xtrans/Xtransint.h
+++ b/X11/xtrans/Xtransint.h
@@ -72,7 +72,9 @@ from The Open Group.
# define XTRANSDEBUG 1
#endif
-#define XTRANS_SEND_FDS 1
+#if XTRANS_SEND_FDS && !(defined(linux) || defined(__sun))
+#error "FD passing support only on Linux & Solaris"
+#endif
#ifdef WIN32
# define _WILLWINSOCK_
@@ -289,6 +291,7 @@ typedef struct _Xtransport {
int /* size */
);
+#if XTRANS_SEND_FDS
int (*SendFd)(
XtransConnInfo, /* connection */
int, /* fd */
@@ -298,6 +301,7 @@ typedef struct _Xtransport {
int (*RecvFd)(
XtransConnInfo /* connection */
);
+#endif
int (*Disconnect)(
XtransConnInfo /* connection */
diff --git a/X11/xtrans/Xtranslcl.c b/X11/xtrans/Xtranslcl.c
index 5beef7c98..4deb86c40 100644
--- a/X11/xtrans/Xtranslcl.c
+++ b/X11/xtrans/Xtranslcl.c
@@ -140,6 +140,21 @@ TRANS(ReopenFail)(XtransConnInfo ciptr _X_UNUSED, int fd _X_UNUSED, char *port _
#endif /* TRANS_REOPEN */
+#if XTRANS_SEND_FDS
+static int
+TRANS(LocalRecvFdInvalid)(XtransConnInfo ciptr)
+{
+ errno = EINVAL;
+ return -1;
+}
+
+static int
+TRANS(LocalSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close)
+{
+ errno = EINVAL;
+ return -1;
+}
+#endif
static int
@@ -2368,6 +2383,10 @@ Xtransport TRANS(LocalFuncs) = {
TRANS(LocalWrite),
TRANS(LocalReadv),
TRANS(LocalWritev),
+#if XTRANS_SEND_FDS
+ TRANS(LocalSendFdInvalid),
+ TRANS(LocalRecvFdInvalid),
+#endif
TRANS(LocalDisconnect),
TRANS(LocalClose),
TRANS(LocalCloseForCloning),
@@ -2410,6 +2429,10 @@ Xtransport TRANS(PTSFuncs) = {
TRANS(LocalWrite),
TRANS(LocalReadv),
TRANS(LocalWritev),
+#if XTRANS_SEND_FDS
+ TRANS(LocalSendFdInvalid),
+ TRANS(LocalRecvFdInvalid),
+#endif
TRANS(LocalDisconnect),
TRANS(LocalClose),
TRANS(LocalCloseForCloning),
@@ -2454,6 +2477,10 @@ Xtransport TRANS(NAMEDFuncs) = {
TRANS(LocalWrite),
TRANS(LocalReadv),
TRANS(LocalWritev),
+#if XTRANS_SEND_FDS
+ TRANS(LocalSendFdInvalid),
+ TRANS(LocalRecvFdInvalid),
+#endif
TRANS(LocalDisconnect),
TRANS(LocalClose),
TRANS(LocalCloseForCloning),
@@ -2495,6 +2522,10 @@ Xtransport TRANS(PIPEFuncs) = {
TRANS(LocalWrite),
TRANS(LocalReadv),
TRANS(LocalWritev),
+#if XTRANS_SEND_FDS
+ TRANS(LocalSendFdInvalid),
+ TRANS(LocalRecvFdInvalid),
+#endif
TRANS(LocalDisconnect),
TRANS(LocalClose),
TRANS(LocalCloseForCloning),
@@ -2539,6 +2570,10 @@ Xtransport TRANS(SCOFuncs) = {
TRANS(LocalWrite),
TRANS(LocalReadv),
TRANS(LocalWritev),
+#if XTRANS_SEND_FDS
+ TRANS(LocalSendFdInvalid),
+ TRANS(LocalRecvFdInvalid),
+#endif
TRANS(LocalDisconnect),
TRANS(LocalClose),
TRANS(LocalCloseForCloning),
diff --git a/X11/xtrans/Xtranssock.c b/X11/xtrans/Xtranssock.c
index 23150b259..c9d103352 100644
--- a/X11/xtrans/Xtranssock.c
+++ b/X11/xtrans/Xtranssock.c
@@ -2237,26 +2237,33 @@ TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size)
#else
#if XTRANS_SEND_FDS
{
- struct msghdr msg;
- struct iovec iov;
- struct fd_pass pass;
+ struct iovec iov = {
+ .iov_base = buf,
+ .iov_len = size
+ };
+ char cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
+ struct msghdr msg = {
+ .msg_name = NULL,
+ .msg_namelen = 0,
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = cmsgbuf,
+ .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int))
+ };
- iov.iov_base = buf;
- iov.iov_len = size;
-
- init_msg_recv(&msg, &iov, 1, &pass, MAX_FDS);
size = recvmsg(ciptr->fd, &msg, 0);
- if (size >= 0 && msg.msg_controllen > sizeof (struct cmsghdr)) {
- if (pass.cmsghdr.cmsg_level == SOL_SOCKET &&
- pass.cmsghdr.cmsg_type == SCM_RIGHTS &&
- !((msg.msg_flags & MSG_TRUNC) ||
- (msg.msg_flags & MSG_CTRUNC)))
- {
- int nfd = (msg.msg_controllen - sizeof (struct cmsghdr)) / sizeof (int);
- int *fd = (int *) CMSG_DATA(&pass.cmsghdr);
- int i;
- for (i = 0; i < nfd; i++)
- appendFd(&ciptr->recv_fds, fd[i], 0);
+ if (size >= 0) {
+ struct cmsghdr *hdr;
+
+ for (hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) {
+ if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) {
+ int nfd = (hdr->cmsg_len - CMSG_LEN(0)) / sizeof (int);
+ int i;
+ int *fd = (int *) CMSG_DATA(hdr);
+
+ for (i = 0; i < nfd; i++)
+ appendFd(&ciptr->recv_fds, fd[i], 0);
+ }
}
}
return size;
@@ -2273,7 +2280,38 @@ TRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size)
{
prmsg (2,"SocketReadv(%d,%p,%d)\n", ciptr->fd, buf, size);
+#if XTRANS_SEND_FDS
+ {
+ char cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
+ struct msghdr msg = {
+ .msg_name = NULL,
+ .msg_namelen = 0,
+ .msg_iov = buf,
+ .msg_iovlen = size,
+ .msg_control = cmsgbuf,
+ .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int))
+ };
+
+ size = recvmsg(ciptr->fd, &msg, 0);
+ if (size >= 0) {
+ struct cmsghdr *hdr;
+
+ for (hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) {
+ if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) {
+ int nfd = (hdr->cmsg_len - CMSG_LEN(0)) / sizeof (int);
+ int i;
+ int *fd = (int *) CMSG_DATA(hdr);
+
+ for (i = 0; i < nfd; i++)
+ appendFd(&ciptr->recv_fds, fd[i], 0);
+ }
+ }
+ }
+ return size;
+ }
+#else
return READV (ciptr, buf, size);
+#endif
}
@@ -2286,22 +2324,32 @@ TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size)
#if XTRANS_SEND_FDS
if (ciptr->send_fds)
{
- struct msghdr msg;
- struct fd_pass pass;
- int nfd;
- struct _XtransConnFd *cf;
+ char cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
+ int nfd = nFd(&ciptr->send_fds);
+ struct _XtransConnFd *cf = ciptr->send_fds;
+ struct msghdr msg = {
+ .msg_name = NULL,
+ .msg_namelen = 0,
+ .msg_iov = buf,
+ .msg_iovlen = size,
+ .msg_control = cmsgbuf,
+ .msg_controllen = CMSG_LEN(nfd * sizeof(int))
+ };
+ struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
int i;
+ int *fds;
- nfd = nFd(&ciptr->send_fds);
- cf = ciptr->send_fds;
+ hdr->cmsg_len = msg.msg_controllen;
+ hdr->cmsg_level = SOL_SOCKET;
+ hdr->cmsg_type = SCM_RIGHTS;
+ fds = (int *) CMSG_DATA(hdr);
/* Set up fds */
for (i = 0; i < nfd; i++) {
- pass.fd[i] = cf->fd;
+ fds[i] = cf->fd;
cf = cf->next;
}
- init_msg_send(&msg, buf, size, &pass, nfd);
i = sendmsg(ciptr->fd, &msg, 0);
if (i > 0)
discardFd(&ciptr->send_fds, cf, 0);
@@ -2482,8 +2530,10 @@ Xtransport TRANS(SocketTCPFuncs) = {
TRANS(SocketWrite),
TRANS(SocketReadv),
TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
TRANS(SocketSendFdInvalid),
TRANS(SocketRecvFdInvalid),
+#endif
TRANS(SocketDisconnect),
TRANS(SocketINETClose),
TRANS(SocketINETClose),
@@ -2524,8 +2574,10 @@ Xtransport TRANS(SocketINETFuncs) = {
TRANS(SocketWrite),
TRANS(SocketReadv),
TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
TRANS(SocketSendFdInvalid),
TRANS(SocketRecvFdInvalid),
+#endif
TRANS(SocketDisconnect),
TRANS(SocketINETClose),
TRANS(SocketINETClose),
@@ -2567,8 +2619,10 @@ Xtransport TRANS(SocketINET6Funcs) = {
TRANS(SocketWrite),
TRANS(SocketReadv),
TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
TRANS(SocketSendFdInvalid),
TRANS(SocketRecvFdInvalid),
+#endif
TRANS(SocketDisconnect),
TRANS(SocketINETClose),
TRANS(SocketINETClose),
@@ -2617,8 +2671,10 @@ Xtransport TRANS(SocketLocalFuncs) = {
TRANS(SocketWrite),
TRANS(SocketReadv),
TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
TRANS(SocketSendFd),
TRANS(SocketRecvFd),
+#endif
TRANS(SocketDisconnect),
TRANS(SocketUNIXClose),
TRANS(SocketUNIXCloseForCloning),
@@ -2673,8 +2729,10 @@ Xtransport TRANS(SocketUNIXFuncs) = {
TRANS(SocketWrite),
TRANS(SocketReadv),
TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
TRANS(SocketSendFd),
TRANS(SocketRecvFd),
+#endif
TRANS(SocketDisconnect),
TRANS(SocketUNIXClose),
TRANS(SocketUNIXCloseForCloning),
diff --git a/X11/xtrans/configure.ac b/X11/xtrans/configure.ac
index 8c3aa3ded..998fb06cf 100644
--- a/X11/xtrans/configure.ac
+++ b/X11/xtrans/configure.ac
@@ -21,7 +21,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
-AC_INIT([xtrans], [1.3.0],
+AC_INIT([xtrans], [1.3.2],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xtrans])
AC_CONFIG_SRCDIR([Makefile.am])
diff --git a/X11/xtrans/xtrans.m4 b/X11/xtrans/xtrans.m4
index 91c6f9d2f..d84442e86 100644
--- a/X11/xtrans/xtrans.m4
+++ b/X11/xtrans/xtrans.m4
@@ -57,6 +57,41 @@ AC_DEFUN([XTRANS_TCP_FLAGS],[
AC_INCLUDES_DEFAULT
#include <sys/socket.h>])
+ # XPG4v2/UNIX95 added msg_control - check to see if we need to define
+ # _XOPEN_SOURCE to get it (such as on Solaris)
+ AC_CHECK_MEMBER([struct msghdr.msg_control], [], [],
+ [
+AC_INCLUDES_DEFAULT
+#include <sys/socket.h>
+ ])
+ # First try for Solaris in C99 compliant mode, which requires XPG6/UNIX03
+ if test "x$ac_cv_member_struct_msghdr_msg_control" = xno; then
+ unset ac_cv_member_struct_msghdr_msg_control
+ AC_MSG_NOTICE([trying again with _XOPEN_SOURCE=600])
+ AC_CHECK_MEMBER([struct msghdr.msg_control],
+ [AC_DEFINE([_XOPEN_SOURCE], [600],
+ [Defined if needed to expose struct msghdr.msg_control])
+ ], [], [
+#define _XOPEN_SOURCE 600
+AC_INCLUDES_DEFAULT
+#include <sys/socket.h>
+ ])
+ fi
+ # If that didn't work, fall back to XPG5/UNIX98 with C89
+ if test "x$ac_cv_member_struct_msghdr_msg_control" = xno; then
+ unset ac_cv_member_struct_msghdr_msg_control
+ AC_MSG_NOTICE([trying again with _XOPEN_SOURCE=500])
+ AC_CHECK_MEMBER([struct msghdr.msg_control],
+ [AC_DEFINE([_XOPEN_SOURCE], [500],
+ [Defined if needed to expose struct msghdr.msg_control])
+ ], [], [
+#define _XOPEN_SOURCE 500
+AC_INCLUDES_DEFAULT
+#include <sys/socket.h>
+ ])
+ fi
+
+
]) # XTRANS_TCP_FLAGS
# XTRANS_CONNECTION_FLAGS()
diff --git a/libxcb/Makefile.am b/libxcb/Makefile.am
index 961595ba3..1cb3d9a7b 100644
--- a/libxcb/Makefile.am
+++ b/libxcb/Makefile.am
@@ -18,9 +18,15 @@ endif
if BUILD_DRI2
pkgconfig_DATA += xcb-dri2.pc
endif
+if BUILD_DRI3
+pkgconfig_DATA += xcb-dri3.pc
+endif
if BUILD_GLX
pkgconfig_DATA += xcb-glx.pc
endif
+if BUILD_PRESENT
+pkgconfig_DATA += xcb-present.pc
+endif
if BUILD_RANDR
pkgconfig_DATA += xcb-randr.pc
endif
diff --git a/libxcb/configure.ac b/libxcb/configure.ac
index 6c107bcd0..87804ba26 100644
--- a/libxcb/configure.ac
+++ b/libxcb/configure.ac
@@ -41,7 +41,7 @@ fi
AC_SUBST(HTML_CHECK_RESULT)
# Checks for pkg-config packages
-PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.7)
+PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.9)
NEEDED="pthread-stubs xau >= 0.99.2"
PKG_CHECK_MODULES(NEEDED, $NEEDED)
@@ -81,6 +81,55 @@ AC_HEADER_STDC
AC_SEARCH_LIBS(getaddrinfo, socket)
AC_SEARCH_LIBS(connect, socket)
+AC_ARG_ENABLE(sendfds, AS_HELP_STRING([--disable-sendfds], [Support FD passing (default: auto)]),
+ [sendfds=$enableval], [sendfds=auto])
+
+case x$sendfds in
+xauto)
+ AC_SEARCH_LIBS(sendmsg, socket, [sendfds="yes"], [sendfds="no"])
+ ;;
+esac
+
+# XPG4v2/UNIX95 added msg_control - check to see if we need to define
+# _XOPEN_SOURCE to get it (such as on Solaris)
+AC_CHECK_MEMBER([struct msghdr.msg_control], [], [],
+ [
+AC_INCLUDES_DEFAULT
+#include <sys/socket.h>
+ ])
+# First try for Solaris in C99 compliant mode, which requires XPG6/UNIX03
+if test "x$ac_cv_member_struct_msghdr_msg_control" = xno; then
+ unset ac_cv_member_struct_msghdr_msg_control
+ AC_MSG_NOTICE([trying again with _XOPEN_SOURCE=600])
+ AC_CHECK_MEMBER([struct msghdr.msg_control],
+ [AC_DEFINE([_XOPEN_SOURCE], [600],
+ [Defined if needed to expose struct msghdr.msg_control])
+ ], [], [
+#define _XOPEN_SOURCE 600
+AC_INCLUDES_DEFAULT
+#include <sys/socket.h>
+ ])
+fi
+# If that didn't work, fall back to XPG5/UNIX98 with C89
+if test "x$ac_cv_member_struct_msghdr_msg_control" = xno; then
+ unset ac_cv_member_struct_msghdr_msg_control
+ AC_MSG_NOTICE([trying again with _XOPEN_SOURCE=500])
+ AC_CHECK_MEMBER([struct msghdr.msg_control],
+ [AC_DEFINE([_XOPEN_SOURCE], [500],
+ [Defined if needed to expose struct msghdr.msg_control])
+ ], [sendfds="no"], [
+#define _XOPEN_SOURCE 500
+AC_INCLUDES_DEFAULT
+#include <sys/socket.h>
+ ])
+fi
+
+case x$sendfds in
+xyes)
+ AC_DEFINE([HAVE_SENDMSG],1,[Define if your platform supports sendmsg])
+ ;;
+esac
+
have_win32="no"
lt_enable_auto_import=""
case $host_os in
@@ -128,7 +177,7 @@ xcbincludedir='${includedir}/xcb'
AC_SUBST(xcbincludedir)
if test "x$GCC" = xyes ; then
- CWARNFLAGS="-Wall -pedantic -Wpointer-arith -Wold-style-definition \
+ CWARNFLAGS="-Wall -Wpointer-arith -Wold-style-definition \
-Wstrict-prototypes -Wmissing-declarations -Wnested-externs"
else
AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
@@ -171,7 +220,9 @@ XCB_EXTENSION(Composite, "yes")
XCB_EXTENSION(Damage, "yes")
XCB_EXTENSION(DPMS, "yes")
XCB_EXTENSION(DRI2, "yes")
+XCB_EXTENSION(DRI3, "$sendfds")
XCB_EXTENSION(GLX, "yes")
+XCB_EXTENSION(Present, "yes")
XCB_EXTENSION(RandR, "yes")
XCB_EXTENSION(Record, "yes")
XCB_EXTENSION(Render, "yes")
@@ -215,7 +266,9 @@ xcb-composite.pc
xcb-damage.pc
xcb-dpms.pc
xcb-dri2.pc
+xcb-dri3.pc
xcb-glx.pc
+xcb-present.pc
xcb-randr.pc
xcb-record.pc
xcb-render.pc
@@ -250,6 +303,7 @@ echo " Package: ${PACKAGE_NAME} ${PACKAGE_VERSION}"
echo ""
echo " Configuration"
echo " XDM support.........: ${have_xdmcp}"
+echo " sendmsg fd passing..: ${sendfds}"
echo " Build unit tests....: ${HAVE_CHECK}"
echo " with html results.: ${HTML_CHECK_RESULT}"
echo " XCB buffer size.....: ${xcb_queue_buffer_size}"
@@ -259,6 +313,7 @@ echo " Composite...........: ${BUILD_COMPOSITE}"
echo " Damage..............: ${BUILD_DAMAGE}"
echo " Dpms................: ${BUILD_DPMS}"
echo " Dri2................: ${BUILD_DRI2}"
+echo " Dri3................: ${BUILD_DRI3}"
echo " Glx.................: ${BUILD_GLX}"
echo " Randr...............: ${BUILD_RANDR}"
echo " Record..............: ${BUILD_RECORD}"
diff --git a/libxcb/src/.gitignore b/libxcb/src/.gitignore
index a402afe57..a2a901006 100644
--- a/libxcb/src/.gitignore
+++ b/libxcb/src/.gitignore
@@ -3,7 +3,9 @@ composite.*
damage.*
dpms.*
dri2.*
+dri3.*
glx.*
+present.*
randr.*
record.*
render.*
diff --git a/libxcb/src/Makefile.am b/libxcb/src/Makefile.am
index 6b5a2c3c4..346ee03cc 100644
--- a/libxcb/src/Makefile.am
+++ b/libxcb/src/Makefile.am
@@ -56,6 +56,22 @@ libxcb_dri2_la_LIBADD = $(XCB_LIBS)
nodist_libxcb_dri2_la_SOURCES = dri2.c dri2.h
endif
+EXTSOURCES += dri3.c
+if BUILD_DRI3
+lib_LTLIBRARIES += libxcb-dri3.la
+libxcb_dri3_la_LDFLAGS = -version-info 0:0:0 -no-undefined @lt_enable_auto_import@
+libxcb_dri3_la_LIBADD = $(XCB_LIBS)
+nodist_libxcb_dri3_la_SOURCES = dri3.c dri3.h
+endif
+
+EXTSOURCES += present.c
+if BUILD_PRESENT
+lib_LTLIBRARIES += libxcb-present.la
+libxcb_present_la_LDFLAGS = -version-info 0:0:0 -no-undefined @lt_enable_auto_import@
+libxcb_present_la_LIBADD = $(XCB_LIBS)
+nodist_libxcb_present_la_SOURCES = present.c present.h
+endif
+
EXTSOURCES += glx.c
if BUILD_GLX
lib_LTLIBRARIES += libxcb-glx.la
@@ -233,7 +249,7 @@ EXTRA_DIST = $(STATIC_MANS)
BUILT_SOURCES = $(EXTSOURCES) $(BUILT_MANS)
CLEANFILES = $(EXTSOURCES) $(EXTHEADERS) $(BUILT_MANS)
-$(EXTSOURCES): c_client.py
+$(EXTSOURCES): c_client.py $(XCBPROTO_XCBINCLUDEDIR)/$(@:.c=.xml)
$(PYTHON) $(srcdir)/c_client.py -p $(XCBPROTO_XCBPYTHONDIR) $(XCBPROTO_XCBINCLUDEDIR)/$(@:.c=.xml)
$(man_MANS): $(EXTSOURCES)
diff --git a/libxcb/src/c_client.py b/libxcb/src/c_client.py
index a6f8edd73..72800045e 100644
--- a/libxcb/src/c_client.py
+++ b/libxcb/src/c_client.py
@@ -303,6 +303,7 @@ def _c_type_setup(self, name, postfix):
self.c_reply_name = _n(name + ('reply',))
self.c_reply_type = _t(name + ('reply',))
self.c_cookie_type = _t(name + ('cookie',))
+ self.c_reply_fds_name = _n(name + ('reply_fds',))
self.need_aux = False
self.need_serialize = False
@@ -1835,7 +1836,7 @@ def c_union(self, name):
_c_complex(self)
_c_iterator(self, name)
-def _c_request_helper(self, name, cookie_type, void, regular, aux=False):
+def _c_request_helper(self, name, cookie_type, void, regular, aux=False, reply_fds=False):
'''
Declares a request function.
'''
@@ -1864,6 +1865,12 @@ def _c_request_helper(self, name, cookie_type, void, regular, aux=False):
# What flag is passed to xcb_request
func_flags = '0' if (void and regular) or (not void and not regular) else 'XCB_REQUEST_CHECKED'
+ if reply_fds:
+ if func_flags == '0':
+ func_flags = 'XCB_REQUEST_REPLY_FDS'
+ else:
+ func_flags = func_flags + '|XCB_REQUEST_REPLY_FDS'
+
# Global extension id variable or NULL for xproto
func_ext_global = '&' + _ns.c_ext_global_name if _ns.is_ext else '0'
@@ -2149,6 +2156,10 @@ def _c_request_helper(self, name, cookie_type, void, regular, aux=False):
# no padding necessary - _serialize() keeps track of padding automatically
_c(' ')
+ for field in param_fields:
+ if field.isfd:
+ _c(' xcb_send_fd(c, %s);', field.c_field_name)
+
_c(' xcb_ret.sequence = xcb_send_request(c, %s, xcb_parts + 2, &xcb_req);', func_flags)
# free dyn. all. data, if any
@@ -2252,6 +2263,51 @@ def _c_reply(self, name):
_c('}')
+def _c_reply_has_fds(self):
+ for field in self.fields:
+ if field.isfd:
+ return True
+ return False
+
+def _c_reply_fds(self, name):
+ '''
+ Declares the function that returns fds related to the reply.
+ '''
+ spacing1 = ' ' * (len(self.c_reply_type) - len('xcb_connection_t'))
+ spacing3 = ' ' * (len(self.c_reply_fds_name) + 2)
+ _h('')
+ _h('/**')
+ _h(' * Return the reply fds')
+ _h(' * @param c The connection')
+ _h(' * @param reply The reply')
+ _h(' *')
+ _h(' * Returns the array of reply fds of the request asked by')
+ _h(' * ')
+ _h(' * The returned value must be freed by the caller using free().')
+ _h(' */')
+ _c('')
+ _hc('')
+ _hc('/*****************************************************************************')
+ _hc(' **')
+ _hc(' ** int * %s', self.c_reply_fds_name)
+ _hc(' ** ')
+ _hc(' ** @param xcb_connection_t%s *c', spacing1)
+ _hc(' ** @param %s *reply', self.c_reply_type)
+ _hc(' ** @returns int *')
+ _hc(' **')
+ _hc(' *****************************************************************************/')
+ _hc(' ')
+ _hc('int *')
+ _hc('%s (xcb_connection_t%s *c /**< */,', self.c_reply_fds_name, spacing1)
+ _h('%s%s *reply /**< */);', spacing3, self.c_reply_type)
+ _c('%s%s *reply /**< */)', spacing3, self.c_reply_type)
+ _c('{')
+
+ _c(' return xcb_get_reply_fds(c, reply, sizeof(%s) + 4 * reply->length);', self.c_reply_type)
+
+ _c('}')
+
+
def _c_opcode(name, opcode):
'''
Declares the opcode define for requests, events, and errors.
@@ -2812,14 +2868,17 @@ def c_request(self, name):
# Reply structure definition
_c_complex(self.reply)
# Request prototypes
- _c_request_helper(self, name, self.c_cookie_type, False, True)
- _c_request_helper(self, name, self.c_cookie_type, False, False)
+ has_fds = _c_reply_has_fds(self.reply)
+ _c_request_helper(self, name, self.c_cookie_type, False, True, False, has_fds)
+ _c_request_helper(self, name, self.c_cookie_type, False, False, False, has_fds)
if self.need_aux:
- _c_request_helper(self, name, self.c_cookie_type, False, True, True)
- _c_request_helper(self, name, self.c_cookie_type, False, False, True)
+ _c_request_helper(self, name, self.c_cookie_type, False, True, True, has_fds)
+ _c_request_helper(self, name, self.c_cookie_type, False, False, True, has_fds)
# Reply accessors
_c_accessors(self.reply, name + ('reply',), name)
_c_reply(self, name)
+ if has_fds:
+ _c_reply_fds(self, name)
else:
# Request prototypes
_c_request_helper(self, name, 'xcb_void_cookie_t', True, False)
diff --git a/libxcb/src/xcb.h b/libxcb/src/xcb.h
index 071413077..63864dc37 100644
--- a/libxcb/src/xcb.h
+++ b/libxcb/src/xcb.h
@@ -87,6 +87,9 @@ extern "C" {
/** Connection closed because the server does not have a screen matching the display. */
#define XCB_CONN_CLOSED_INVALID_SCREEN 6
+/** Connection closed because some FD passing operation failed */
+#define XCB_CONN_CLOSED_FDPASSING_FAILED 7
+
#define XCB_TYPE_PAD(T,I) (-(I) & (sizeof(T) > 4 ? 3 : sizeof(T) - 1))
/* Opaque structures */
@@ -138,23 +141,6 @@ typedef struct {
} xcb_generic_event_t;
/**
- * @brief GE event
- *
- * An event as sent by the XGE extension. The length field specifies the
- * number of 4-byte blocks trailing the struct.
- */
-typedef struct {
- uint8_t response_type; /**< Type of the response */
- uint8_t pad0; /**< Padding */
- uint16_t sequence; /**< Sequence number */
- uint32_t length;
- uint16_t event_type;
- uint16_t pad1;
- uint32_t pad[5]; /**< Padding */
- uint32_t full_sequence; /**< full sequence */
-} xcb_ge_event_t;
-
-/**
* @brief Generic error.
*
* A generic error structure.
@@ -304,6 +290,39 @@ xcb_generic_event_t *xcb_poll_for_event(xcb_connection_t *c);
*/
xcb_generic_event_t *xcb_poll_for_queued_event(xcb_connection_t *c);
+typedef struct xcb_special_event xcb_special_event_t;
+
+/**
+ * @brief Returns the next event from a special queue
+ */
+xcb_generic_event_t *xcb_poll_for_special_event(xcb_connection_t *c,
+ xcb_special_event_t *se);
+
+/**
+ * @brief Returns the next event from a special queue, blocking until one arrives
+ */
+xcb_generic_event_t *xcb_wait_for_special_event(xcb_connection_t *c,
+ xcb_special_event_t *se);
+/**
+ * @typedef typedef struct xcb_extension_t xcb_extension_t
+ */
+typedef struct xcb_extension_t xcb_extension_t; /**< Opaque structure used as key for xcb_get_extension_data_t. */
+
+
+/**
+ * @brief Listen for a special event
+ */
+xcb_special_event_t *xcb_register_for_special_xge(xcb_connection_t *c,
+ xcb_extension_t *ext,
+ uint32_t eid,
+ uint32_t *stamp);
+
+/**
+ * @brief Stop listening for a special event
+ */
+void xcb_unregister_for_special_event(xcb_connection_t *c,
+ xcb_special_event_t *se);
+
/**
* @brief Return the error for a request, or NULL if none can ever arrive.
* @param c: The connection to the X server.
@@ -342,11 +361,6 @@ void xcb_discard_reply(xcb_connection_t *c, unsigned int sequence);
/* xcb_ext.c */
/**
- * @typedef typedef struct xcb_extension_t xcb_extension_t
- */
-typedef struct xcb_extension_t xcb_extension_t; /**< Opaque structure used as key for xcb_get_extension_data_t. */
-
-/**
* @brief Caches reply information from QueryExtension requests.
* @param c: The connection.
* @param ext: The extension data.
diff --git a/libxcb/src/xcb_conn.c b/libxcb/src/xcb_conn.c
index 7dd25d373..50e7fb604 100644
--- a/libxcb/src/xcb_conn.c
+++ b/libxcb/src/xcb_conn.c
@@ -214,9 +214,39 @@ static int write_vec(xcb_connection_t *c, struct iovec **vector, int *count)
if (n > IOV_MAX)
n = IOV_MAX;
- n = writev(c->fd, *vector, n);
- if(n < 0 && errno == EAGAIN)
- return 1;
+#if HAVE_SENDMSG
+ if (c->out.out_fd.nfd) {
+ char cmsgbuf[CMSG_SPACE(sizeof(int) * XCB_MAX_PASS_FD)];
+ struct msghdr msg = {
+ .msg_name = NULL,
+ .msg_namelen = 0,
+ .msg_iov = *vector,
+ .msg_iovlen = n,
+ .msg_control = cmsgbuf,
+ .msg_controllen = CMSG_LEN(c->out.out_fd.nfd * sizeof (int)),
+ };
+ int i;
+ struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
+
+ hdr->cmsg_len = msg.msg_controllen;
+ hdr->cmsg_level = SOL_SOCKET;
+ hdr->cmsg_type = SCM_RIGHTS;
+ memcpy(CMSG_DATA(hdr), c->out.out_fd.fd, c->out.out_fd.nfd * sizeof (int));
+
+ n = sendmsg(c->fd, &msg, 0);
+ if(n < 0 && errno == EAGAIN)
+ return 1;
+ for (i = 0; i < c->out.out_fd.nfd; i++)
+ close(c->out.out_fd.fd[i]);
+ c->out.out_fd.nfd = 0;
+ } else
+#endif
+ {
+ n = writev(c->fd, *vector, n);
+ if(n < 0 && errno == EAGAIN)
+ return 1;
+ }
+
#endif /* _WIN32 */
if(n <= 0)
diff --git a/libxcb/src/xcb_in.c b/libxcb/src/xcb_in.c
index 8a7af920b..8c3a58cc3 100644
--- a/libxcb/src/xcb_in.c
+++ b/libxcb/src/xcb_in.c
@@ -60,6 +60,23 @@ struct event_list {
struct event_list *next;
};
+struct xcb_special_event {
+
+ struct xcb_special_event *next;
+
+ /* Match XGE events for the specific extension and event ID (the
+ * first 32 bit word after evtype)
+ */
+ uint8_t extension;
+ uint32_t eid;
+ uint32_t *stamp;
+
+ struct event_list *events;
+ struct event_list **events_tail;
+
+ pthread_cond_t special_event_cond;
+};
+
struct reply_list {
void *reply;
struct reply_list *next;
@@ -90,11 +107,66 @@ static void remove_finished_readers(reader_list **prev_reader, uint64_t complete
}
}
+#if HAVE_SENDMSG
+static int read_fds(xcb_connection_t *c, int *fds, int nfd)
+{
+ int *ifds = &c->in.in_fd.fd[c->in.in_fd.ifd];
+ int infd = c->in.in_fd.nfd - c->in.in_fd.ifd;
+
+ if (nfd > infd)
+ return 0;
+ memcpy(fds, ifds, nfd * sizeof (int));
+ c->in.in_fd.ifd += nfd;
+ return 1;
+}
+#endif
+
+typedef struct xcb_ge_special_event_t {
+ uint8_t response_type; /**< */
+ uint8_t extension; /**< */
+ uint16_t sequence; /**< */
+ uint32_t length; /**< */
+ uint16_t evtype; /**< */
+ uint8_t pad0[2]; /**< */
+ uint32_t eid; /**< */
+ uint8_t pad1[16]; /**< */
+} xcb_ge_special_event_t;
+
+static int event_special(xcb_connection_t *c,
+ struct event_list *event)
+{
+ struct xcb_special_event *special_event;
+ struct xcb_ge_special_event_t *ges = (void *) event->event;
+
+ /* Special events are always XGE events */
+ if ((ges->response_type & 0x7f) != XCB_XGE_EVENT)
+ return 0;
+
+ for (special_event = c->in.special_events;
+ special_event;
+ special_event = special_event->next)
+ {
+ if (ges->extension == special_event->extension &&
+ ges->eid == special_event->eid)
+ {
+ *special_event->events_tail = event;
+ special_event->events_tail = &event->next;
+ if (special_event->stamp)
+ ++(*special_event->stamp);
+ pthread_cond_signal(&special_event->special_event_cond);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
static int read_packet(xcb_connection_t *c)
{
xcb_generic_reply_t genrep;
uint64_t length = 32;
uint64_t eventlength = 0; /* length after first 32 bytes for GenericEvents */
+ int nfd = 0; /* Number of file descriptors attached to the reply */
uint64_t bufsize;
void *buf;
pending_reply *pend = 0;
@@ -164,13 +236,18 @@ static int read_packet(xcb_connection_t *c)
genrep.length = p[2] * p[3] * 2;
}
length += genrep.length * 4;
+
+ /* XXX a bit of a hack -- we "know" that all FD replys place
+ * the number of fds in the pad0 byte */
+ if (pend && pend->flags & XCB_REQUEST_REPLY_FDS)
+ nfd = genrep.pad0;
}
/* XGE events may have sizes > 32 */
if ((genrep.response_type & 0x7f) == XCB_XGE_EVENT)
eventlength = genrep.length * 4;
- bufsize = length + eventlength +
+ bufsize = length + eventlength + nfd * sizeof(int) +
(genrep.response_type == XCB_REPLY ? 0 : sizeof(uint32_t));
if (bufsize < INT32_MAX)
buf = malloc((size_t) bufsize);
@@ -198,6 +275,17 @@ static int read_packet(xcb_connection_t *c)
}
}
+#if HAVE_SENDMSG
+ if (nfd)
+ {
+ if (!read_fds(c, (int *) &((char *) buf)[length], nfd))
+ {
+ free(buf);
+ return 0;
+ }
+ }
+#endif
+
if(pend && (pend->flags & XCB_REQUEST_DISCARD_REPLY))
{
free(buf);
@@ -237,9 +325,12 @@ static int read_packet(xcb_connection_t *c)
}
event->event = buf;
event->next = 0;
- *c->in.events_tail = event;
- c->in.events_tail = &event->next;
- pthread_cond_signal(&c->in.event_cond);
+
+ if (!event_special(c, event)) {
+ *c->in.events_tail = event;
+ c->in.events_tail = &event->next;
+ pthread_cond_signal(&c->in.event_cond);
+ }
return 1; /* I have something for you... */
}
@@ -431,6 +522,11 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_
return ret;
}
+int *xcb_get_reply_fds(xcb_connection_t *c, void *reply, size_t reply_size)
+{
+ return (int *) (&((char *) reply)[reply_size]);
+}
+
static void insert_pending_discard(xcb_connection_t *c, pending_reply **prev_next, uint64_t seq)
{
pending_reply *pend;
@@ -577,6 +673,126 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co
return ret;
}
+static xcb_generic_event_t *get_special_event(xcb_connection_t *c,
+ xcb_special_event_t *se)
+{
+ xcb_generic_event_t *event = NULL;
+ struct event_list *events;
+
+ if ((events = se->events) != NULL) {
+ event = events->event;
+ if (!(se->events = events->next))
+ se->events_tail = &se->events;
+ free (events);
+ }
+ return event;
+}
+
+xcb_generic_event_t *xcb_poll_for_special_event(xcb_connection_t *c,
+ xcb_special_event_t *se)
+{
+ xcb_generic_event_t *event;
+
+ if(c->has_error)
+ return 0;
+ pthread_mutex_lock(&c->iolock);
+ event = get_special_event(c, se);
+ pthread_mutex_unlock(&c->iolock);
+ return event;
+}
+
+xcb_generic_event_t *xcb_wait_for_special_event(xcb_connection_t *c,
+ xcb_special_event_t *se)
+{
+ xcb_generic_event_t *event;
+
+ if(c->has_error)
+ return 0;
+ pthread_mutex_lock(&c->iolock);
+
+ /* get_special_event returns 0 on empty list. */
+ while(!(event = get_special_event(c, se)))
+ if(!_xcb_conn_wait(c, &se->special_event_cond, 0, 0))
+ break;
+
+ pthread_mutex_unlock(&c->iolock);
+ return event;
+}
+
+xcb_special_event_t *
+xcb_register_for_special_xge(xcb_connection_t *c,
+ xcb_extension_t *ext,
+ uint32_t eid,
+ uint32_t *stamp)
+{
+ xcb_special_event_t *se;
+ const xcb_query_extension_reply_t *ext_reply;
+
+ if(c->has_error)
+ return NULL;
+ ext_reply = xcb_get_extension_data(c, ext);
+ if (!ext_reply)
+ return NULL;
+ pthread_mutex_lock(&c->iolock);
+ for (se = c->in.special_events; se; se = se->next) {
+ if (se->extension == ext_reply->major_opcode &&
+ se->eid == eid) {
+ pthread_mutex_unlock(&c->iolock);
+ return NULL;
+ }
+ }
+ se = calloc(1, sizeof(xcb_special_event_t));
+ if (!se) {
+ pthread_mutex_unlock(&c->iolock);
+ return NULL;
+ }
+
+ se->extension = ext_reply->major_opcode;
+ se->eid = eid;
+
+ se->events = NULL;
+ se->events_tail = &se->events;
+ se->stamp = stamp;
+
+ pthread_cond_init(&se->special_event_cond, 0);
+
+ se->next = c->in.special_events;
+ c->in.special_events = se;
+ pthread_mutex_unlock(&c->iolock);
+ return se;
+}
+
+void
+xcb_unregister_for_special_event(xcb_connection_t *c,
+ xcb_special_event_t *se)
+{
+ xcb_special_event_t *s, **prev;
+ struct event_list *events, *next;
+
+ if (!se)
+ return;
+
+ if (c->has_error)
+ return;
+
+ pthread_mutex_lock(&c->iolock);
+
+ for (prev = &c->in.special_events; (s = *prev) != NULL; prev = &(s->next)) {
+ if (s == se) {
+ *prev = se->next;
+ for (events = se->events; events; events = next) {
+ next = events->next;
+ free (events->event);
+ free (events);
+ }
+ pthread_cond_destroy(&se->special_event_cond);
+ free (se);
+ break;
+ }
+ }
+ pthread_mutex_unlock(&c->iolock);
+}
+
/* Private interface */
int _xcb_in_init(_xcb_in *in)
@@ -665,11 +881,73 @@ void _xcb_in_replies_done(xcb_connection_t *c)
int _xcb_in_read(xcb_connection_t *c)
{
- int n = recv(c->fd, c->in.queue + c->in.queue_len, sizeof(c->in.queue) - c->in.queue_len, 0);
- if(n > 0)
+ int n;
+
+#if HAVE_SENDMSG
+ struct iovec iov = {
+ .iov_base = c->in.queue + c->in.queue_len,
+ .iov_len = sizeof(c->in.queue) - c->in.queue_len,
+ };
+ char cmsgbuf[CMSG_SPACE(sizeof(int) * XCB_MAX_PASS_FD)];
+ struct msghdr msg = {
+ .msg_name = NULL,
+ .msg_namelen = 0,
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = cmsgbuf,
+ .msg_controllen = CMSG_SPACE(sizeof(int) * (XCB_MAX_PASS_FD - c->in.in_fd.nfd)),
+ };
+ n = recvmsg(c->fd, &msg, 0);
+
+ /* Check for truncation errors. Only MSG_CTRUNC is
+ * probably possible here, which would indicate that
+ * the sender tried to transmit more than XCB_MAX_PASS_FD
+ * file descriptors.
+ */
+ if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) {
+ _xcb_conn_shutdown(c, XCB_CONN_CLOSED_FDPASSING_FAILED);
+ return 0;
+ }
+#else
+ n = recv(c->fd, c->in.queue + c->in.queue_len, sizeof(c->in.queue) - c->in.queue_len, 0);
+#endif
+ if(n > 0) {
+#if HAVE_SENDMSG
+ struct cmsghdr *hdr;
+
+ for (hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) {
+ if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) {
+ int nfd = (hdr->cmsg_len - CMSG_LEN(0)) / sizeof (int);
+ memcpy(&c->in.in_fd.fd[c->in.in_fd.nfd], CMSG_DATA(hdr), nfd * sizeof (int));
+ c->in.in_fd.nfd += nfd;
+ }
+ }
+#endif
c->in.queue_len += n;
+ }
while(read_packet(c))
/* empty */;
+#if HAVE_SENDMSG
+ if (c->in.in_fd.nfd) {
+ c->in.in_fd.nfd -= c->in.in_fd.ifd;
+ memmove(&c->in.in_fd.fd[0],
+ &c->in.in_fd.fd[c->in.in_fd.ifd],
+ c->in.in_fd.nfd * sizeof (int));
+ c->in.in_fd.ifd = 0;
+
+ /* If we have any left-over file descriptors after emptying
+ * the input buffer, then the server sent some that we weren't
+ * expecting. Close them and mark the connection as broken;
+ */
+ if (c->in.queue_len == 0 && c->in.in_fd.nfd != 0) {
+ int i;
+ for (i = 0; i < c->in.in_fd.nfd; i++)
+ close(c->in.in_fd.fd[i]);
+ _xcb_conn_shutdown(c, XCB_CONN_CLOSED_FDPASSING_FAILED);
+ return 0;
+ }
+ }
+#endif
#ifndef _WIN32
if((n > 0) || (n < 0 && errno == EAGAIN))
#else
diff --git a/libxcb/src/xcb_out.c b/libxcb/src/xcb_out.c
index 429fa99d3..1a3aca515 100644
--- a/libxcb/src/xcb_out.c
+++ b/libxcb/src/xcb_out.c
@@ -263,6 +263,24 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
return request;
}
+void
+xcb_send_fd(xcb_connection_t *c, int fd)
+{
+#if HAVE_SENDMSG
+ if (c->has_error)
+ return;
+ pthread_mutex_lock(&c->iolock);
+ while (c->out.out_fd.nfd == XCB_MAX_PASS_FD) {
+ _xcb_out_flush_to(c, c->out.request);
+ if (c->has_error)
+ break;
+ }
+ if (!c->has_error)
+ c->out.out_fd.fd[c->out.out_fd.nfd++] = fd;
+ pthread_mutex_unlock(&c->iolock);
+#endif
+}
+
int xcb_take_socket(xcb_connection_t *c, void (*return_socket)(void *closure), void *closure, int flags, uint64_t *sent)
{
int ret;
diff --git a/libxcb/src/xcbext.h b/libxcb/src/xcbext.h
index 4e1f2f73d..1eb1be77f 100644
--- a/libxcb/src/xcbext.h
+++ b/libxcb/src/xcbext.h
@@ -54,11 +54,14 @@ typedef struct {
enum xcb_send_request_flags_t {
XCB_REQUEST_CHECKED = 1 << 0,
XCB_REQUEST_RAW = 1 << 1,
- XCB_REQUEST_DISCARD_REPLY = 1 << 2
+ XCB_REQUEST_DISCARD_REPLY = 1 << 2,
+ XCB_REQUEST_REPLY_FDS = 1 << 3
};
unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request);
+void xcb_send_fd(xcb_connection_t *c, int fd);
+
/* xcb_take_socket allows external code to ask XCB for permission to
* take over the write side of the socket and send raw data with
* xcb_writev. xcb_take_socket provides the sequence number of the last
@@ -89,6 +92,7 @@ int xcb_writev(xcb_connection_t *c, struct iovec *vector, int count, uint64_t re
void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_error_t **e);
int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply, xcb_generic_error_t **error);
+int *xcb_get_reply_fds(xcb_connection_t *c, void *reply, size_t replylen);
/* xcb_util.c */
diff --git a/libxcb/src/xcbint.h b/libxcb/src/xcbint.h
index 7f9ab2838..5c904fbb7 100644
--- a/libxcb/src/xcbint.h
+++ b/libxcb/src/xcbint.h
@@ -81,6 +81,16 @@ void *_xcb_map_remove(_xcb_map *q, unsigned int key);
typedef void (*xcb_return_socket_func_t)(void *closure);
+#if HAVE_SENDMSG
+#define XCB_MAX_PASS_FD 16
+
+typedef struct _xcb_fd {
+ int fd[XCB_MAX_PASS_FD];
+ int nfd;
+ int ifd;
+} _xcb_fd;
+#endif
+
typedef struct _xcb_out {
pthread_cond_t cond;
int writing;
@@ -101,6 +111,9 @@ typedef struct _xcb_out {
xcb_big_requests_enable_cookie_t cookie;
uint32_t value;
} maximum_request_length;
+#if HAVE_SENDMSG
+ _xcb_fd out_fd;
+#endif
} _xcb_out;
int _xcb_out_init(_xcb_out *out);
@@ -133,6 +146,10 @@ typedef struct _xcb_in {
struct pending_reply *pending_replies;
struct pending_reply **pending_replies_tail;
+#if HAVE_SENDMSG
+ _xcb_fd in_fd;
+#endif
+ struct xcb_special_event *special_events;
} _xcb_in;
int _xcb_in_init(_xcb_in *in);
diff --git a/libxcb/xcb-dri3.pc.in b/libxcb/xcb-dri3.pc.in
new file mode 100644
index 000000000..0eb73908a
--- /dev/null
+++ b/libxcb/xcb-dri3.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: XCB DRI3
+Description: XCB DRI3 Extension
+Version: @PACKAGE_VERSION@
+Requires: xcb
+Libs: -L${libdir} -lxcb-dri3
+Cflags: -I${includedir}
diff --git a/libxcb/xcb-present.pc.in b/libxcb/xcb-present.pc.in
new file mode 100644
index 000000000..848ac02ef
--- /dev/null
+++ b/libxcb/xcb-present.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: XCB Present
+Description: XCB Present Extension
+Version: @PACKAGE_VERSION@
+Requires: xcb
+Libs: -L${libdir} -lxcb-present
+Cflags: -I${includedir}
diff --git a/libxcb/xcb-proto/configure.ac b/libxcb/xcb-proto/configure.ac
index ba6a90cd8..c82c8c749 100644
--- a/libxcb/xcb-proto/configure.ac
+++ b/libxcb/xcb-proto/configure.ac
@@ -3,7 +3,7 @@
AC_PREREQ(2.57)
AC_INIT([XCB Proto],
- 1.8,
+ 1.9,
[xcb@lists.freedesktop.org])
AC_CONFIG_SRCDIR([xcb-proto.pc.in])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
diff --git a/libxcb/xcb-proto/src/present.xml b/libxcb/xcb-proto/src/present.xml
index d12ae4879..57e7cd364 100644
--- a/libxcb/xcb-proto/src/present.xml
+++ b/libxcb/xcb-proto/src/present.xml
@@ -133,7 +133,7 @@ OF THIS SOFTWARE.
<!-- Events -->
- <event name="Generic">
+ <event name="Generic" number="0">
<field type="CARD8" name="extension" />
<field type="CARD32" name="length" />
<field type="CARD16" name="evtype" enum="EventType" />
diff --git a/libxcb/xcb-proto/src/xcb.xsd b/libxcb/xcb-proto/src/xcb.xsd
index 7a9c80018..73dbf8a77 100644
--- a/libxcb/xcb-proto/src/xcb.xsd
+++ b/libxcb/xcb-proto/src/xcb.xsd
@@ -89,6 +89,9 @@ authorization from the authors.
<!-- field replaces FIELD, PARAM, and REPLY. -->
<xsd:element name="field" type="var" />
+ <!-- fd passing parameter -->
+ <xsd:element name="fd" />
+
<!-- list replaces ARRAYFIELD, LISTPARAM, and ARRAYREPLY. The name and type
are specified as attributes. The content is an expression giving the
length. -->
@@ -185,6 +188,7 @@ authorization from the authors.
<xsd:element ref="pad" />
<xsd:element ref="field" />
<xsd:element ref="list" />
+ <xsd:element ref="fd" />
</xsd:choice>
</xsd:group>
diff --git a/libxcb/xcb-proto/xcbgen/xtypes.py b/libxcb/xcb-proto/xcbgen/xtypes.py
index 6150d1818..951731afc 100644
--- a/libxcb/xcb-proto/xcbgen/xtypes.py
+++ b/libxcb/xcb-proto/xcbgen/xtypes.py
@@ -164,44 +164,6 @@ class Enum(SimpleType):
out = __main__.output['enum']
-class FileDescriptor(SimpleType):
- '''
- Derived class which represents a file descriptor. Passed via magic kernel stuff
-
- Public fields added:
- values contains a list of (name, value) tuples. value is empty, or a number.
- bits contains a list of (name, bitnum) tuples. items only appear if specified as a bit. bitnum is a number.
- '''
- def __init__(self, name, elt):
- SimpleType.__init__(self, name, 4)
- self.values = []
- self.bits = []
- self.doc = None
- for item in list(elt):
- if item.tag == 'doc':
- self.doc = Doc(name, item)
-
- # First check if we're using a default value
- if len(list(item)) == 0:
- self.values.append((item.get('name'), ''))
- continue
-
- # An explicit value or bit was specified.
- value = list(item)[0]
- if value.tag == 'value':
- self.values.append((item.get('name'), value.text))
- elif value.tag == 'bit':
- self.values.append((item.get('name'), '%u' % (1 << int(value.text, 0))))
- self.bits.append((item.get('name'), value.text))
-
- def resolve(self, module):
- self.resolved = True
-
- def fixed_size(self):
- return True
-
- out = __main__.output['enum']
-
class ListType(Type):
'''
Derived class which represents a list of some other datatype. Fixed- or variable-sized.
diff --git a/mesalib/configure.ac b/mesalib/configure.ac
index a8366ee2f..8fb5e0d8b 100644
--- a/mesalib/configure.ac
+++ b/mesalib/configure.ac
@@ -34,9 +34,10 @@ LIBDRM_NVVIEUX_REQUIRED=2.4.33
LIBDRM_NOUVEAU_REQUIRED="2.4.33 libdrm >= 2.4.41"
LIBDRM_FREEDRENO_REQUIRED=2.4.39
DRI2PROTO_REQUIRED=2.6
+DRI3PROTO_REQUIRED=1.0
+PRESENTPROTO_REQUIRED=1.0
+LIBUDEV_REQUIRED=151
GLPROTO_REQUIRED=1.4.14
-LIBDRM_XORG_REQUIRED=2.4.24
-LIBKMS_XORG_REQUIRED=1.0.0
dnl Check for progs
AC_PROG_CPP
@@ -556,11 +557,6 @@ AC_ARG_ENABLE([egl],
[enable_egl="$enableval"],
[enable_egl=yes])
-AC_ARG_ENABLE([xorg],
- [AS_HELP_STRING([--enable-xorg],
- [enable support for X.Org DDX API @<:@default=no@:>@])],
- [enable_xorg="$enableval"],
- [enable_xorg=no])
AC_ARG_ENABLE([xa],
[AS_HELP_STRING([--enable-xa],
[enable build of the XA X Acceleration API @<:@default=no@:>@])],
@@ -651,7 +647,6 @@ if test "x$enable_opengl" = xno -a \
"x$enable_gles1" = xno -a \
"x$enable_gles2" = xno -a \
"x$enable_openvg" = xno -a \
- "x$enable_xorg" = xno -a \
"x$enable_xa" = xno -a \
"x$enable_xvmc" = xno -a \
"x$enable_vdpau" = xno -a \
@@ -816,10 +811,13 @@ xyesno)
fi
PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= $DRI2PROTO_REQUIRED])
GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV libdrm >= $LIBDRM_REQUIRED"
+ PKG_CHECK_MODULES([DRI3PROTO], [dri3proto >= $DRI3PROTO_REQUIRED])
+ PKG_CHECK_MODULES([PRESENTPROTO], [presentproto >= $PRESENTPROTO_REQUIRED])
+ PKG_CHECK_MODULES([LIBUDEV], [libudev >= $LIBUDEV_REQUIRED])
fi
# find the DRI deps for libGL
- dri_modules="x11 xext xdamage xfixes x11-xcb xcb-glx >= 1.8.1 xcb-dri2 >= 1.8"
+ dri_modules="x11 xext xdamage xfixes x11-xcb xcb-glx >= 1.8.1 xcb-dri2 >= 1.8 xcb-dri3 xcb-present xcb-sync xshmfence"
# add xf86vidmode if available
PKG_CHECK_MODULES([XF86VIDMODE], [xxf86vm], HAVE_XF86VIDMODE=yes, HAVE_XF86VIDMODE=no)
@@ -829,8 +827,8 @@ xyesno)
PKG_CHECK_MODULES([DRIGL], [$dri_modules])
GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV $dri_modules"
- X11_INCLUDES="$X11_INCLUDES $DRIGL_CFLAGS"
- GL_LIB_DEPS="$DRIGL_LIBS"
+ X11_INCLUDES="$X11_INCLUDES $DRIGL_CFLAGS $LIBUDEV_CFLAGS"
+ GL_LIB_DEPS="$DRIGL_LIBS $LIBUDEV_LIBS"
# need DRM libs, $PTHREAD_LIBS, etc.
GL_LIB_DEPS="$GL_LIB_DEPS $LIBDRM_LIBS -lm $PTHREAD_LIBS $DLOPEN_LIBS"
@@ -1236,20 +1234,6 @@ fi
AM_CONDITIONAL(HAVE_GALLIUM_GBM, test "x$enable_gallium_gbm" = xyes)
dnl
-dnl X.Org DDX configuration
-dnl
-if test "x$enable_xorg" = xyes; then
- PKG_CHECK_MODULES([XORG], [xorg-server >= 1.6.0])
- PKG_CHECK_MODULES([LIBDRM_XORG], [libdrm >= $LIBDRM_XORG_REQUIRED])
- PKG_CHECK_MODULES([LIBKMS_XORG], [libkms >= $LIBKMS_XORG_REQUIRED])
- PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
- HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71",
- HAVE_XEXTPROTO_71="no")
- GALLIUM_STATE_TRACKERS_DIRS="xorg $GALLIUM_STATE_TRACKERS_DIRS"
-fi
-AM_CONDITIONAL(HAVE_ST_XORG, test "x$enable_xorg" = xyes)
-
-dnl
dnl XA configuration
dnl
if test "x$enable_xa" = xyes; then
@@ -1487,13 +1471,6 @@ AC_ARG_WITH([egl-driver-dir],
[EGL_DRIVER_INSTALL_DIR='${libdir}/egl'])
AC_SUBST([EGL_DRIVER_INSTALL_DIR])
-AC_ARG_WITH([xorg-driver-dir],
- [AS_HELP_STRING([--with-xorg-driver-dir=DIR],
- [Default xorg driver directory[[default=${libdir}/xorg/modules/drivers]]])],
- [XORG_DRIVER_INSTALL_DIR="$withval"],
- [XORG_DRIVER_INSTALL_DIR="${libdir}/xorg/modules/drivers"])
-AC_SUBST([XORG_DRIVER_INSTALL_DIR])
-
AC_ARG_WITH([max-width],
[AS_HELP_STRING([--with-max-width=N],
[Maximum framebuffer width (4096)])],
@@ -1675,18 +1652,15 @@ gallium_check_st() {
if test "x$enable_dri" = xyes && test "x$2" != x; then
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $2"
fi
- if test "x$enable_xorg" = xyes && test "x$3" != x; then
+ if test "x$enable_xa" = xyes && test "x$3" != x; then
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $3"
fi
- if test "x$enable_xa" = xyes && test "x$4" != x; then
+ if test "x$enable_xvmc" = xyes && test "x$4" != x; then
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $4"
fi
- if test "x$enable_xvmc" = xyes && test "x$5" != x; then
+ if test "x$enable_vdpau" = xyes && test "x$5" != x; then
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $5"
fi
- if test "x$enable_vdpau" = xyes && test "x$6" != x; then
- GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $6"
- fi
}
gallium_require_llvm() {
@@ -1726,9 +1700,8 @@ radeon_llvm_check() {
}
dnl Gallium drivers
-if test "x$enable_dri" = xyes -o "x$enable_xorg" = xyes -o \
- "x$enable_xa" = xyes -o "x$enable_xvmc" = xyes -o \
- "x$enable_vdpau" = xyes; then
+if test "x$enable_dri" = xyes -o "x$enable_xa" = xyes -o \
+ "x$enable_xvmc" = xyes -o "x$enable_vdpau" = xyes; then
NEED_NONNULL_WINSYS=yes
fi
AM_CONDITIONAL(NEED_NONNULL_WINSYS, test "x$NEED_NONNULL_WINSYS" = xyes)
@@ -1741,7 +1714,7 @@ if test "x$with_gallium_drivers" != x; then
xsvga)
HAVE_GALLIUM_SVGA=yes
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS svga softpipe"
- gallium_check_st "svga/drm" "dri-vmwgfx" "" "xa-vmwgfx"
+ gallium_check_st "svga/drm" "dri-vmwgfx" "xa-vmwgfx"
;;
xi915)
HAVE_GALLIUM_I915=yes
@@ -1751,7 +1724,7 @@ if test "x$with_gallium_drivers" != x; then
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS llvmpipe"
fi
GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS i915/sw"
- gallium_check_st "i915/drm" "dri-i915" "xorg-i915"
+ gallium_check_st "i915/drm" "dri-i915"
DRICOMMON_NEED_LIBDRM=yes
;;
xilo)
@@ -1767,7 +1740,7 @@ if test "x$with_gallium_drivers" != x; then
PKG_CHECK_MODULES([RADEON], [libdrm_radeon >= $LIBDRM_RADEON_REQUIRED])
gallium_require_llvm "Gallium R300"
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r300"
- gallium_check_st "radeon/drm" "r300/dri" "" "" "" ""
+ gallium_check_st "radeon/drm" "r300/dri" "" "" ""
DRICOMMON_NEED_LIBDRM=yes
;;
xr600)
@@ -1785,7 +1758,7 @@ if test "x$with_gallium_drivers" != x; then
if test "x$enable_opencl" = xyes; then
LLVM_COMPONENTS="${LLVM_COMPONENTS} bitreader asmparser"
fi
- gallium_check_st "radeon/drm" "r600/dri" "" "" "r600/xvmc" "r600/vdpau"
+ gallium_check_st "radeon/drm" "r600/dri" "" "r600/xvmc" "r600/vdpau"
DRICOMMON_NEED_LIBDRM=yes
;;
xradeonsi)
@@ -1794,7 +1767,7 @@ if test "x$with_gallium_drivers" != x; then
gallium_require_drm_loader
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS radeonsi"
radeon_llvm_check
- gallium_check_st "radeon/drm" "radeonsi/dri" "" "" "" "radeonsi/vdpau" ""
+ gallium_check_st "radeon/drm" "radeonsi/dri" "" "" "radeonsi/vdpau"
DRICOMMON_NEED_LIBDRM=yes
;;
xnouveau)
@@ -1802,7 +1775,7 @@ if test "x$with_gallium_drivers" != x; then
PKG_CHECK_MODULES([NOUVEAU], [libdrm_nouveau >= $LIBDRM_NOUVEAU_REQUIRED])
gallium_require_drm_loader
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau"
- gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau" "" "xvmc-nouveau" "vdpau-nouveau"
+ gallium_check_st "nouveau/drm" "dri-nouveau" "" "xvmc-nouveau" "vdpau-nouveau"
DRICOMMON_NEED_LIBDRM=yes
;;
xfreedreno)
@@ -1810,7 +1783,7 @@ if test "x$with_gallium_drivers" != x; then
PKG_CHECK_MODULES([FREEDRENO], [libdrm_freedreno >= $LIBDRM_FREEDRENO_REQUIRED])
gallium_require_drm_loader
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS freedreno"
- gallium_check_st "freedreno/drm" "dri-freedreno" "" "" "" ""
+ gallium_check_st "freedreno/drm" "dri-freedreno" "" "" ""
DRICOMMON_NEED_LIBDRM=yes
;;
xswrast)
@@ -1938,9 +1911,9 @@ AM_CONDITIONAL(HAVE_X11_DRIVER, test "x$enable_xlib_glx" = xyes)
AM_CONDITIONAL(HAVE_OSMESA, test "x$enable_osmesa" = xyes)
AM_CONDITIONAL(HAVE_GALLIUM_OSMESA, test "x$enable_gallium_osmesa" = xyes)
-AM_CONDITIONAL(HAVE_X86_ASM, echo "$DEFINES" | grep 'X86_ASM' >/dev/null 2>&1)
-AM_CONDITIONAL(HAVE_X86_64_ASM, echo "$DEFINES" | grep 'X86_64_ASM' >/dev/null 2>&1)
-AM_CONDITIONAL(HAVE_SPARC_ASM, echo "$DEFINES" | grep 'SPARC_ASM' >/dev/null 2>&1)
+AM_CONDITIONAL(HAVE_X86_ASM, test "x$asm_arch" = xx86 -o "x$asm_arch" = xx86_64)
+AM_CONDITIONAL(HAVE_X86_64_ASM, test "x$asm_arch" = xx86_64)
+AM_CONDITIONAL(HAVE_SPARC_ASM, test "x$asm_arch" = xsparc)
AC_SUBST([VDPAU_MAJOR], 1)
AC_SUBST([VDPAU_MINOR], 0)
@@ -2013,7 +1986,6 @@ AC_CONFIG_FILES([Makefile
src/gallium/state_trackers/vdpau/Makefile
src/gallium/state_trackers/vega/Makefile
src/gallium/state_trackers/xa/Makefile
- src/gallium/state_trackers/xorg/Makefile
src/gallium/state_trackers/xvmc/Makefile
src/gallium/targets/Makefile
src/gallium/targets/dri-freedreno/Makefile
@@ -2038,8 +2010,6 @@ AC_CONFIG_FILES([Makefile
src/gallium/targets/vdpau-nouveau/Makefile
src/gallium/targets/xa-vmwgfx/Makefile
src/gallium/targets/xa-vmwgfx/xatracker.pc
- src/gallium/targets/xorg-i915/Makefile
- src/gallium/targets/xorg-nouveau/Makefile
src/gallium/targets/xvmc-nouveau/Makefile
src/gallium/tests/trivial/Makefile
src/gallium/tests/unit/Makefile
@@ -2091,9 +2061,7 @@ AC_CONFIG_FILES([Makefile
src/mesa/drivers/osmesa/osmesa.pc
src/mesa/drivers/x11/Makefile
src/mesa/main/tests/Makefile
- src/mesa/main/tests/hash_table/Makefile
- src/mesa/x86-64/Makefile
- src/mesa/x86/Makefile])
+ src/mesa/main/tests/hash_table/Makefile])
dnl Sort the dirs alphabetically
GALLIUM_TARGET_DIRS=`echo $GALLIUM_TARGET_DIRS|tr " " "\n"|sort -u|tr "\n" " "`
diff --git a/mesalib/docs/GL3.txt b/mesalib/docs/GL3.txt
index 7d100dff1..a8cffab44 100644
--- a/mesalib/docs/GL3.txt
+++ b/mesalib/docs/GL3.txt
@@ -106,8 +106,8 @@ GL_ARB_tessellation_shader not started
GL_ARB_texture_buffer_object_rgb32 DONE (i965, r600, radeonsi, softpipe)
GL_ARB_texture_cube_map_array DONE (i965, r600, softpipe)
GL_ARB_texture_gather DONE (i965)
-GL_ARB_transform_feedback2 DONE (r600, radeonsi)
-GL_ARB_transform_feedback3 DONE (r600, radeonsi)
+GL_ARB_transform_feedback2 DONE (i965, r600, radeonsi)
+GL_ARB_transform_feedback3 DONE (i965, r600, radeonsi)
GL 4.1:
@@ -126,9 +126,9 @@ GL 4.2:
GLSL 4.2 not started
GL_ARB_texture_compression_bptc not started
GL_ARB_compressed_texture_pixel_storage not started
-GL_ARB_shader_atomic_counters in progress (Curro)
+GL_ARB_shader_atomic_counters DONE (i965)
GL_ARB_texture_storage DONE (all drivers)
-GL_ARB_transform_feedback_instanced DONE (r600, radeonsi)
+GL_ARB_transform_feedback_instanced DONE (i965, r600, radeonsi)
GL_ARB_base_instance DONE (i965, nv50, nvc0, r600, radeonsi)
GL_ARB_shader_image_load_store not started
GL_ARB_conservative_depth DONE (all drivers that support GLSL 1.30)
@@ -161,7 +161,7 @@ GL_ARB_texture_buffer_range DONE (nv50, nvc0, i965, r60
GL_ARB_texture_query_levels DONE (i965)
GL_ARB_texture_storage_multisample DONE (all drivers that support GL_ARB_texture_multisample)
GL_ARB_texture_view not started
-GL_ARB_vertex_attrib_binding started (Fredrik)
+GL_ARB_vertex_attrib_binding DONE (all drivers)
GL 4.4:
@@ -175,7 +175,7 @@ GL_ARB_multi_bind not started
GL_ARB_query_buffer_object not started
GL_ARB_texture_mirror_clamp_to_edge DONE (i965, nv30, nv50, nvc0, r300, r600, radeonsi, swrast)
GL_ARB_texture_stencil8 not started
-GL_ARB_vertex_type_10f_11f_11f_rev not started
+GL_ARB_vertex_type_10f_11f_11f_rev DONE (i965, r600)
More info about these features and the work involved can be found at
diff --git a/mesalib/docs/relnotes/10.0.html b/mesalib/docs/relnotes/10.0.html
index b74d03dc2..eabe77f83 100644
--- a/mesalib/docs/relnotes/10.0.html
+++ b/mesalib/docs/relnotes/10.0.html
@@ -51,6 +51,9 @@ Note: some of the new features are only available with certain drivers.
<li>GL_ARB_texture_mirror_clamp_to_edge.</li>
<li>GL_ARB_transform_feedback2, GL_ARB_transform_feedback3, and GL_ARB_transform_feedback_instanced on i965/Gen7 (with appropriate kernel support).</li>
<li>GL_ARB_sample_shading on i965.</li>
+<li>GL_ARB_shader_atomic_counters on i965.</li>
+<li>GL_ARB_vertex_attrib_binding</li>
+<li>GL_ARB_vertex_type_10f_11f_11f_rev on i965 and r600g</li>
<li>GL_KHR_debug</li>
</ul>
diff --git a/mesalib/docs/specs/MESA_query_renderer.spec b/mesalib/docs/specs/MESA_query_renderer.spec
new file mode 100644
index 000000000..bf0975669
--- /dev/null
+++ b/mesalib/docs/specs/MESA_query_renderer.spec
@@ -0,0 +1,405 @@
+Name
+
+ MESA_query_renderer
+
+Name Strings
+
+ GLX_MESA_query_renderer
+
+Contact
+
+ Ian Romanick <ian.d.romanick@intel.com>
+
+IP Status
+
+ No known IP claims.
+
+Status
+
+ Incomplete. DO NOT SHIP.
+
+Version
+
+ Version 6, 7-November-2013
+
+Number
+
+ TBD.
+
+Dependencies
+
+ GLX 1.4 is required.
+
+ GLX_ARB_create_context and GLX_ARB_create_context_profile are required.
+
+ This extension interacts with GLX_EXT_create_context_es2_profile and
+ GLX_EXT_create_context_es_profile.
+
+Overview
+
+ In many situations, applications want to detect characteristics of a
+ rendering device before creating a context for that device. Information
+ gathered at this stage may guide choices the application makes about
+ color depth, number of samples per-pixel, texture quality, and so on.
+ In addition, versions of supported APIs and implementation API
+ preference may also guide start-up decisions made by the application.
+ For example, one implementation may prefer vertex data be supplied using
+ methods only available in a compatibility profile, but another
+ implementation may only support the desired version in a core profile.
+
+ There are also cases where more than one renderer may be available per
+ display. For example, there is typically a hardware implementation and
+ a software based implementation. There are cases where an application
+ may want to pick one over the other. One such situation is when the
+ software implementation supports more features than the hardware
+ implementation. Another situation is when a particular version of the
+ hardware implementation is blacklisted due to known bugs.
+
+ This extension provides a mechanism for the application to query all of
+ the available renderers for a particular display and screen. In
+ addition, this extension provides a mechanism for applications to create
+ contexts with respect to a specific renderer.
+
+New Procedures and Functions
+
+ Bool glXQueryRendererIntegerMESA(Display *dpy, int screen,
+ int renderer, int attribute,
+ unsigned int *value);
+ Bool glXQueryCurrentRendererIntegerMESA(int attribute, unsigned int *value);
+
+ const char *glXQueryRendererStringMESA(Display *dpy, int screen,
+ int renderer, int attribute);
+
+ const char *glXQueryCurrentRendererStringMESA(int attribute);
+
+New Tokens
+
+ Accepted as an <attribute> in glXQueryRendererIntegerMESA and
+ glXQueryCurrentRendererIntegerMESA:
+
+ GLX_RENDERER_VENDOR_ID_MESA 0x8183
+ GLX_RENDERER_DEVICE_ID_MESA 0x8184
+ GLX_RENDERER_VERSION_MESA 0x8185
+ GLX_RENDERER_ACCELERATED_MESA 0x8186
+ GLX_RENDERER_VIDEO_MEMORY_MESA 0x8187
+ GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA 0x8188
+ GLX_RENDERER_PREFERRED_PROFILE_MESA 0x8189
+ GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA 0x818A
+ GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA 0x818B
+ GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA 0x818C
+ GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA 0x818D
+
+ Accepted as an <attribute> in glXQueryRendererStringMESA and
+ glXQueryCurrentRendererStringMESA:
+
+ GLX_RENDERER_VENDOR_ID_MESA
+ GLX_RENDERER_DEVICE_ID_MESA
+
+ Accepted as an attribute name in <*attrib_list> in
+ glXCreateContextAttribsARB:
+
+ GLX_RENDERER_ID_MESA 0x818E
+
+Additions to the OpenGL / WGL Specifications
+
+ None. This specification is written for GLX.
+
+Additions to the GLX 1.4 Specification
+
+ [Add the following to Section X.Y.Z of the GLX Specification]
+
+ To obtain information about the available renderers for a particular
+ display and screen,
+
+ Bool glXQueryRendererIntegerMESA(Display *dpy, int screen, int renderer,
+ int attribute, unsigned int *value);
+
+ can be used. The value for <attribute> will be returned in one or more
+ integers specified by <value>. The values, data sizes, and descriptions
+ of each renderer attribute are listed in the table below.
+
+ GLX renderer attribute number description
+ of values
+ ---------------------- --------- -----------
+ GLX_RENDERER_VENDOR_ID_MESA 1 PCI ID of the device vendor
+ GLX_RENDERER_DEVICE_ID_MESA 1 PCI ID of the device
+ GLX_RENDERER_VERSION_MESA 3 Major, minor, and patch level of
+ the renderer implementation
+ GLX_RENDERER_ACCELERATED_MESA 1 Boolean indicating whether or
+ not the renderer is hardware
+ accelerated
+ GLX_RENDERER_VIDEO_MEMORY_MESA 1 Number of megabytes of video
+ memory available to the renderer
+ GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA
+ 1 Boolean indicating whether or
+ not the renderer uses a unified
+ memory architecture or has
+ separate "on-card" and GART
+ memory.
+ GLX_RENDERER_PREFERRED_PROFILE_MESA
+ 1 Bitmask of the preferred context
+ profile for this renderer. This
+ value is suitable to be supplied
+ with the
+ GLX_CONTEXT_PROFILE_MASK_ARB
+ attribute to
+ glXCreateContextAttribsARB
+ GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA
+ 2 Maximum core profile major and
+ minor version supported by the
+ renderer
+ GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA
+ 2 Maximum compatibility profile
+ major and minor version
+ supported by the renderer
+ GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA
+ 2 Maximum OpenGL ES 1.x
+ major and minor version
+ supported by the renderer
+ GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA
+ 2 Maximum OpenGL ES 2.x or 3.x
+ major and minor version
+ supported by the renderer
+
+ In the table, boolean attributes will have either the value 0 or 1.
+
+ GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA,
+ GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA,
+ GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA, and
+ GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA each return <0, 0> in
+ *value if no version of that profile is supported.
+
+ GLX_RENDERER_VENDOR_ID_MESA and GLX_RENDERER_DEVICE_ID_MESA may return
+ 0xFFFFFFFF if the device does not have a PCI ID (because it is not a PCI
+ device) or if the PCI ID is not available. In this case the application
+ should rely on the string query instead.
+
+ If <attribute> is not a recognized value, False is returned, but no GLX
+ error is generated. Otherwise, True is returned.
+
+ String versions of some attributes may also be queried using
+
+ const char *glXQueryRendererStringMESA(Display *dpy, int screen,
+ int renderer, int attribute);
+
+ The value for <attribute> will be returned in one or more
+ integers specified by <value>. The values, data sizes, and descriptions
+ of each renderer attribute are listed in the table below.
+
+ GLX renderer attribute description
+ ---------------------- -----------
+ GLX_RENDERER_VENDOR_ID_MESA Name of the renderer provider. This may
+ differ from the vendor name of the
+ underlying hardware.
+ GLX_RENDERER_DEVICE_ID_MESA Name of the renderer. This may differ from
+ the name of the underlying hardware (e.g.,
+ for a software renderer).
+
+ If <attribute> is not a recognized value, NULL is returned, but no GLX
+ error is generated.
+
+ The string returned for GLX_RENDERER_VENDOR_ID_MESA will have the same
+ format as the string that would be returned by glGetString of GL_VENDOR.
+ It may, however, have a different value.
+
+ The string returned for GLX_RENDERER_DEVICE_ID_MESA will have the same
+ format as the string that would be returned by glGetString of GL_RENDERER.
+ It may, however, have a different value.
+
+
+ [Add to section section 3.3.7 "Rendering Contexts"]
+
+ The attribute name GLX_RENDERER_ID_MESA specified the index of the render
+ against which the context should be created. The default value of
+ GLX_RENDER_ID_MESA is 0.
+
+
+ [Add to list of errors for glXCreateContextAttribsARB in section section
+ 3.3.7 "Rendering Contexts"]
+
+ * If the value of GLX_RENDERER_ID_MESA specifies a non-existent
+ renderer, BadMatch is generated.
+
+Dependencies on GLX_EXT_create_context_es_profile and
+GLX_EXT_create_context_es2_profile
+
+ If neither extension is supported, remove all mention of
+ GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA from the spec.
+
+ If GLX_EXT_create_context_es_profile is not supported, remove all mention of
+ GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA from the spec.
+
+Issues
+
+ 1) How should the difference between on-card and GART memory be exposed?
+
+ UNRESOLVED.
+
+ 2) How should memory limitations of unified memory architecture (UMA)
+ systems be exposed?
+
+ UNRESOLVED. Some hardware has different per-process and global
+ limits for memory that can be accessed within a single draw call.
+
+ 3) How should the renderer's API preference be advertised?
+
+ UNRESOLVED. The common case for desktop renderers is to prefer
+ either core or compatibility. However, some renderers may actually
+ prefer an ES context. This leaves the application in a tough spot
+ if it can only support core or compatibility and the renderer says it
+ wants ES.
+
+ 4) Should OpenGL ES 2.0 and OpenGL ES 3.0 be treated separately?
+
+ RESOLVED. No. OpenGL ES 3.0 is backwards compatible with OpenGL ES
+ 2.0. Applications can detect OpenGL ES 3.0 support by querying
+ GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA.
+
+ 5) How can applications tell the difference between different hardware
+ renderers for the same device? For example, whether the renderer is the
+ open-source driver or the closed-source driver.
+
+ RESOLVED. Assuming this extension is ever implemented outside Mesa,
+ applications can query GLX_RENDERER_VENDOR_ID_MESA from
+ glXQueryRendererStringMESA. This will almost certainly return
+ different strings for open-source and closed-source drivers.
+
+ 6) What is the value of GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA for
+ software renderers?
+
+ UNRESOLVED. Video (display) memory and texture memory is not unified
+ for software implementations, so it seems reasonable for this to be
+ False.
+
+ 7) How does an application determine the number of available renderers?
+
+ UNRESOLVED.
+
+ 8) What happens if a fbconfig is used to create context on a renderer
+ that cannot support it? For example, if a multisampled config is used
+ with a software renderer that does not support multisampling.
+
+ RESOLVED. The language for glXCreateContextAttribsARB already covers
+ this case. Context creation will fail, and BadMatch is generated.
+
+ 9) In addition to being able to query the supported versions, should
+ applications also be able to query the supported extensions?
+
+ RESOLVED. No. Desktop OpenGL core profiles and OpenGL ES 3.0 have
+ moved away from the monolithic string returned by glGetString of
+ GL_EXTENSIONS. Providing the newer indexed query would require adding
+ a lot of extra infrastructure, and it would probably provide little
+ benefit to applications.
+
+ 10) What combination of values for GLX_RENDERER_PREFERRED_PROFILE_MESA,
+ GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA, and
+ GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA should be returned
+ for a renderer that only supports OpenGL 3.1 without the
+ GL_ARB_compatibility extension?
+
+ RESOLVED. The renderer will return GLX_CONTEXT_CORE_PROFILE_BIT_ARB
+ for GLX_RENDERER_PREFERRED_PROFILE_MESA.
+
+ Further, the renderer will return <3,0> for
+ GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA because OpenGL
+ 3.1 without GL_ARB_compatibility is not backwards compatible with
+ previous versions of OpenGL. The render will return <3,1> for
+ GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA indicating that support
+ for OpenGL 3.1 is available.
+
+ Even though there is no OpenGL 3.1 core profile, the values
+ returned for GLX_RENDERER_PREFERRED_PROFILE_MESA and
+ GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA can be supplied
+ with the GLX_CONTEXT_PROFILE_MASK_ARB and
+ GLX_CONTEXT_{MAJOR,MINOR}_VERSION_ARB attributes of
+ glXCreateContextAttribsARB without error. If the requested
+ OpenGL version is less than 3.2, the
+ GLX_CONTEXT_PROFILE_MASK_ARB attribute is ignored by
+ glXCreateContextAttribsARB.
+
+ 11) How can application learn about multi-GPU (e.g., SLI, CrossFireX,
+ etc.) configurations?
+
+ UNRESOLVED. Based on ISV feedback, this is important information to
+ provide to the application. Given the variety of possible hardware
+ configurations (e.g., Hybrid CrossFireX) and different rendering
+ modes (e.g., split-frame rendering vs. alternate-frame rendering),
+ it's not clear how this information can be communicated.
+
+ It is likely that this will be left to a layered extension.
+
+ 12) Should capability queries similar to those in
+ GL_ARB_internalformat_query or GL_ARB_internalformat_query2 be added?
+
+ RESOLVED. No. With the possible exception of the texture size
+ queries, it seems unlikely that applications would ever use this
+ information before creating a context.
+
+ 13) Existing GL extensions (e.g., GL_ATI_meminfo and
+ GL_NVX_gpu_memory_info) allow easy queries after context creation. With
+ this extension it is a bit of a pain for a portable application to query
+ the information after context creation.
+
+ RESOLVED. Add versions of the queries that implicitly take the
+ display, screen, and renderer from the currently bound context.
+
+ 14) Why not make the queries from issue #13 GL functions (instead of GLX)?
+
+ RESOLVED. It is fairly compelling for the post-creation queries to
+ just use glGetInteger and glGetString. However, the GL enums and
+ the GLX enums would have different names and would almost certainly
+ have different values. It seems like this would cause more problems
+ than it would solve.
+
+ 15) Should the string queries be required to return the same values as
+ glGetString(GL_VENDOR) and glGetString(GL_RENDERER)?
+
+ UNRESOLVED. This may be useful for applications that already do
+ device detection based on these strings.
+
+ 16) What type should the value parameter of glXQueryRendererIntegerMESA
+ and glXQueryCurrentRendererIntegerMESA be?
+
+ UNRESOLVED. Other similar GLX query functions just use int or
+ unsigned int, so that's what this extension uses for now. However,
+ an expeclitly sized value, such as uint32_t or uint64_t, seems
+ preferable.
+
+ 17) What about SoCs and other systems that don't have PCI?
+
+ RESOLVED. The GLX_RENDERER_VENDOR_ID_MESA and
+ GLX_RENDERER_DEVICE_ID_MESA integer queries may return 0xFFFFFFFF if a
+ PCI ID either does not exist or is not available. Implementations
+ should make every attempt to return as much information as is
+ possible. For example, if the implementation is running on a non-PCI
+ SoC with a Qualcomm GPU, GLX_RENDERER_VENDOR_ID_MESA should return
+ 0x168C, but GLX_RENDERER_DEVICE_ID_MESA will return 0x0000.
+
+Revision History
+
+ Version 1, 2012/08/27 - Initial version
+
+ Version 2, 2012/09/04 - Specify behavior of implementations that
+ do not support certain profiles.
+ Change wording of issue #8 to be more
+ clear.
+ Make some wording changes to issue #10 to
+ clarify the resolution a bit.
+
+ Version 3, 2012/09/23 - Add issue #11 regarding multi-GPU systems.
+
+ Version 4, 2013/02/01 - Add issue #12 regarding texture / renderbuffer
+ format queries.
+
+ Version 5, 2013/02/14 - Add issues #13 and #14 regarding simpler queires
+ after the context is created and made current.
+ Add issue #15 regarding the string query.
+ Add issue #16 regarding the value type returned
+ by the Integer functions.
+
+ Version 6, 2013/10/25 - Fix a typo. Update the list of functions to
+ which the new enums can be passed. The "Current"
+ versions were previously missing.
+
+ Version 7, 2013/11/07 - Fix a couple more typos. Add issue #17 regarding
+ the PCI queries on systems that don't have PCI.
diff --git a/mesalib/include/GL/glx.h b/mesalib/include/GL/glx.h
index fa5a8eda9..62d0ede9e 100644
--- a/mesalib/include/GL/glx.h
+++ b/mesalib/include/GL/glx.h
@@ -467,7 +467,32 @@ extern void glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer
#endif /* GLX_EXT_texture_from_pixmap */
-
+#ifndef GLX_MESA_query_renderer
+#define GLX_MESA_query_renderer 1
+
+#define GLX_RENDERER_VENDOR_ID_MESA 0x8183
+#define GLX_RENDERER_DEVICE_ID_MESA 0x8184
+#define GLX_RENDERER_VERSION_MESA 0x8185
+#define GLX_RENDERER_ACCELERATED_MESA 0x8186
+#define GLX_RENDERER_VIDEO_MEMORY_MESA 0x8187
+#define GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA 0x8188
+#define GLX_RENDERER_PREFERRED_PROFILE_MESA 0x8189
+#define GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA 0x818A
+#define GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA 0x818B
+#define GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA 0x818C
+#define GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA 0x818D
+#define GLX_RENDERER_ID_MESA 0x818E
+
+Bool glXQueryRendererIntegerMESA(Display *dpy, int screen, int renderer, int attribute, unsigned int *value);
+Bool glXQueryCurrentRendererIntegerMESA(int attribute, unsigned int *value);
+const char *glXQueryRendererStringMESA(Display *dpy, int screen, int renderer, int attribute);
+const char *glXQueryCurrentRendererStringMESA(int attribute);
+
+typedef Bool (*PFNGLXQUERYRENDERERINTEGERMESAPROC) (Display *dpy, int screen, int renderer, int attribute, unsigned int *value);
+typedef Bool (*PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) (int attribute, unsigned int *value);
+typedef const char *(*PFNGLXQUERYRENDERERSTRINGMESAPROC) (Display *dpy, int screen, int renderer, int attribute);
+typedef const char *(*PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC) (int attribute);
+#endif /* GLX_MESA_query_renderer */
/*** Should these go here, or in another header? */
/*
diff --git a/mesalib/include/GL/internal/dri_interface.h b/mesalib/include/GL/internal/dri_interface.h
index 48993b939..ed4325764 100644
--- a/mesalib/include/GL/internal/dri_interface.h
+++ b/mesalib/include/GL/internal/dri_interface.h
@@ -86,6 +86,10 @@ typedef struct __DRIdri2LoaderExtensionRec __DRIdri2LoaderExtension;
typedef struct __DRI2flushExtensionRec __DRI2flushExtension;
typedef struct __DRI2throttleExtensionRec __DRI2throttleExtension;
+
+typedef struct __DRIimageLoaderExtensionRec __DRIimageLoaderExtension;
+typedef struct __DRIimageDriverExtensionRec __DRIimageDriverExtension;
+
/*@}*/
@@ -763,6 +767,40 @@ struct __DRIswrastExtensionRec {
};
+/** Common DRI function definitions, shared among DRI2 and Image extensions
+ */
+
+typedef __DRIscreen *
+(*__DRIcreateNewScreen2Func)(int screen, int fd,
+ const __DRIextension **extensions,
+ const __DRIextension **driver_extensions,
+ const __DRIconfig ***driver_configs,
+ void *loaderPrivate);
+
+typedef __DRIdrawable *
+(*__DRIcreateNewDrawableFunc)(__DRIscreen *screen,
+ const __DRIconfig *config,
+ void *loaderPrivate);
+
+typedef __DRIcontext *
+(*__DRIcreateNewContextFunc)(__DRIscreen *screen,
+ const __DRIconfig *config,
+ __DRIcontext *shared,
+ void *loaderPrivate);
+
+typedef __DRIcontext *
+(*__DRIcreateContextAttribsFunc)(__DRIscreen *screen,
+ int api,
+ const __DRIconfig *config,
+ __DRIcontext *shared,
+ unsigned num_attribs,
+ const uint32_t *attribs,
+ unsigned *error,
+ void *loaderPrivate);
+
+typedef unsigned int
+(*__DRIgetAPIMaskFunc)(__DRIscreen *screen);
+
/**
* DRI2 Loader extension.
*/
@@ -910,17 +948,11 @@ struct __DRIdri2ExtensionRec {
const __DRIconfig ***driver_configs,
void *loaderPrivate);
- __DRIdrawable *(*createNewDrawable)(__DRIscreen *screen,
- const __DRIconfig *config,
- void *loaderPrivate);
-
- __DRIcontext *(*createNewContext)(__DRIscreen *screen,
- const __DRIconfig *config,
- __DRIcontext *shared,
- void *loaderPrivate);
+ __DRIcreateNewDrawableFunc createNewDrawable;
+ __DRIcreateNewContextFunc createNewContext;
/* Since version 2 */
- unsigned int (*getAPIMask)(__DRIscreen *screen);
+ __DRIgetAPIMaskFunc getAPIMask;
__DRIcontext *(*createNewContextForAPI)(__DRIscreen *screen,
int api,
@@ -943,25 +975,14 @@ struct __DRIdri2ExtensionRec {
*
* \sa __DRIswrastExtensionRec::createContextAttribs
*/
- __DRIcontext *(*createContextAttribs)(__DRIscreen *screen,
- int api,
- const __DRIconfig *config,
- __DRIcontext *shared,
- unsigned num_attribs,
- const uint32_t *attribs,
- unsigned *error,
- void *loaderPrivate);
+ __DRIcreateContextAttribsFunc createContextAttribs;
/**
* createNewScreen with the driver's extension list passed in.
*
* \since version 4
*/
- __DRIscreen *(*createNewScreen2)(int screen, int fd,
- const __DRIextension **loader_extensions,
- const __DRIextension **driver_extensions,
- const __DRIconfig ***driver_configs,
- void *loaderPrivate);
+ __DRIcreateNewScreen2Func createNewScreen2;
};
@@ -996,6 +1017,7 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_FORMAT_NONE 0x1008
#define __DRI_IMAGE_FORMAT_XRGB2101010 0x1009
#define __DRI_IMAGE_FORMAT_ARGB2101010 0x100a
+#define __DRI_IMAGE_FORMAT_SARGB8 0x100b
#define __DRI_IMAGE_USE_SHARE 0x0001
#define __DRI_IMAGE_USE_SCANOUT 0x0002
@@ -1287,4 +1309,105 @@ typedef struct __DRIDriverVtableExtensionRec {
const struct __DriverAPIRec *vtable;
} __DRIDriverVtableExtension;
+/**
+ * Query renderer driver extension
+ *
+ * This allows the window system layer (either EGL or GLX) to query aspects of
+ * hardware and driver support without creating a context.
+ */
+#define __DRI2_RENDERER_QUERY "DRI_RENDERER_QUERY"
+#define __DRI2_RENDERER_QUERY_VERSION 1
+
+#define __DRI2_RENDERER_VENDOR_ID 0x0000
+#define __DRI2_RENDERER_DEVICE_ID 0x0001
+#define __DRI2_RENDERER_VERSION 0x0002
+#define __DRI2_RENDERER_ACCELERATED 0x0003
+#define __DRI2_RENDERER_VIDEO_MEMORY 0x0004
+#define __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE 0x0005
+#define __DRI2_RENDERER_PREFERRED_PROFILE 0x0006
+#define __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION 0x0007
+#define __DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION 0x0008
+#define __DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION 0x0009
+#define __DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION 0x000a
+
+typedef struct __DRI2rendererQueryExtensionRec __DRI2rendererQueryExtension;
+struct __DRI2rendererQueryExtensionRec {
+ __DRIextension base;
+
+ int (*queryInteger)(__DRIscreen *screen, int attribute, unsigned int *val);
+ int (*queryString)(__DRIscreen *screen, int attribute, const char **val);
+};
+
+/**
+ * Image Loader extension. Drivers use this to allocate color buffers
+ */
+
+enum __DRIimageBufferMask {
+ __DRI_IMAGE_BUFFER_BACK = (1 << 0),
+ __DRI_IMAGE_BUFFER_FRONT = (1 << 1)
+};
+
+struct __DRIimageList {
+ uint32_t image_mask;
+ __DRIimage *back;
+ __DRIimage *front;
+};
+
+#define __DRI_IMAGE_LOADER "DRI_IMAGE_LOADER"
+#define __DRI_IMAGE_LOADER_VERSION 1
+
+struct __DRIimageLoaderExtensionRec {
+ __DRIextension base;
+
+ /**
+ * Allocate color buffers.
+ *
+ * \param driDrawable
+ * \param width Width of allocated buffers
+ * \param height Height of allocated buffers
+ * \param format one of __DRI_IMAGE_FORMAT_*
+ * \param stamp Address of variable to be updated when
+ * getBuffers must be called again
+ * \param loaderPrivate The loaderPrivate for driDrawable
+ * \param buffer_mask Set of buffers to allocate
+ * \param buffers Returned buffers
+ */
+ int (*getBuffers)(__DRIdrawable *driDrawable,
+ unsigned int format,
+ uint32_t *stamp,
+ void *loaderPrivate,
+ uint32_t buffer_mask,
+ struct __DRIimageList *buffers);
+
+ /**
+ * Flush pending front-buffer rendering
+ *
+ * Any rendering that has been performed to the
+ * fake front will be flushed to the front
+ *
+ * \param driDrawable Drawable whose front-buffer is to be flushed
+ * \param loaderPrivate Loader's private data that was previously passed
+ * into __DRIdri2ExtensionRec::createNewDrawable
+ */
+ void (*flushFrontBuffer)(__DRIdrawable *driDrawable, void *loaderPrivate);
+};
+
+/**
+ * DRI extension.
+ */
+
+#define __DRI_IMAGE_DRIVER "DRI_IMAGE_DRIVER"
+#define __DRI_IMAGE_DRIVER_VERSION 1
+
+struct __DRIimageDriverExtensionRec {
+ __DRIextension base;
+
+ /* Common DRI functions, shared with DRI2 */
+ __DRIcreateNewScreen2Func createNewScreen2;
+ __DRIcreateNewDrawableFunc createNewDrawable;
+ __DRIcreateNewContextFunc createNewContext;
+ __DRIcreateContextAttribsFunc createContextAttribs;
+ __DRIgetAPIMaskFunc getAPIMask;
+};
+
#endif
diff --git a/mesalib/src/gallium/SConscript b/mesalib/src/gallium/SConscript
index 9a25ccafb..c68519df0 100644
--- a/mesalib/src/gallium/SConscript
+++ b/mesalib/src/gallium/SConscript
@@ -45,9 +45,6 @@ if not env['embedded']:
if env['dri']:
SConscript('state_trackers/dri/SConscript')
- if env['dri'] and env['xorg']:
- SConscript('state_trackers/xorg/SConscript')
-
if env['platform'] == 'windows':
SConscript('state_trackers/wgl/SConscript')
@@ -136,11 +133,6 @@ if not env['embedded']:
'targets/dri-i915/SConscript',
])
- if env['xorg'] and env['drm']:
- SConscript([
- #'targets/xorg-i915/SConscript',
- ])
-
#
# Unit tests & tools
diff --git a/mesalib/src/gallium/auxiliary/util/u_format.c b/mesalib/src/gallium/auxiliary/util/u_format.c
index 9ef3bb53f..6b602bf32 100644
--- a/mesalib/src/gallium/auxiliary/util/u_format.c
+++ b/mesalib/src/gallium/auxiliary/util/u_format.c
@@ -215,9 +215,8 @@ util_format_is_supported(enum pipe_format format, unsigned bind)
* default MRD will be 1.0 / ((1 << 24) - 1).
*/
double
-util_get_depth_format_mrd(enum pipe_format format)
+util_get_depth_format_mrd(const struct util_format_description *desc)
{
- struct util_format_description *format_desc;
/*
* Depth buffer formats without a depth component OR scenarios
* without a bound depth buffer default to D24.
@@ -225,23 +224,20 @@ util_get_depth_format_mrd(enum pipe_format format)
double mrd = 1.0 / ((1 << 24) - 1);
unsigned depth_channel;
- format_desc = (struct util_format_description *)
- util_format_description(format);
-
- assert(format_desc);
+ assert(desc);
/*
* Some depth formats do not store the depth component in the first
* channel, detect the format and adjust the depth channel. Get the
* swizzled depth component channel.
*/
- depth_channel = format_desc->swizzle[0];
+ depth_channel = desc->swizzle[0];
- if (format_desc->channel[depth_channel].type == UTIL_FORMAT_TYPE_UNSIGNED &&
- format_desc->channel[depth_channel].normalized) {
+ if (desc->channel[depth_channel].type == UTIL_FORMAT_TYPE_UNSIGNED &&
+ desc->channel[depth_channel].normalized) {
int depth_bits;
- depth_bits = format_desc->channel[depth_channel].size;
+ depth_bits = desc->channel[depth_channel].size;
mrd = 1.0 / ((1ULL << depth_bits) - 1);
}
diff --git a/mesalib/src/gallium/auxiliary/util/u_format.h b/mesalib/src/gallium/auxiliary/util/u_format.h
index 369c3994a..0fbaf4cc1 100644
--- a/mesalib/src/gallium/auxiliary/util/u_format.h
+++ b/mesalib/src/gallium/auxiliary/util/u_format.h
@@ -546,13 +546,29 @@ util_format_is_depth_and_stencil(enum pipe_format format)
/**
+ * Calculates the depth format type based upon the incoming format description.
+ */
+static INLINE unsigned
+util_get_depth_format_type(const struct util_format_description *desc)
+{
+ unsigned depth_channel = desc->swizzle[0];
+ if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
+ depth_channel != UTIL_FORMAT_SWIZZLE_NONE) {
+ return desc->channel[depth_channel].type;
+ } else {
+ return UTIL_FORMAT_TYPE_VOID;
+ }
+}
+
+
+/**
* Calculates the MRD for the depth format. MRD is used in depth bias
* for UNORM and unbound depth buffers. When the depth buffer is floating
* point, the depth bias calculation does not use the MRD. However, the
* default MRD will be 1.0 / ((1 << 24) - 1).
*/
double
-util_get_depth_format_mrd(enum pipe_format format);
+util_get_depth_format_mrd(const struct util_format_description *desc);
/**
diff --git a/mesalib/src/gallium/auxiliary/util/u_math.h b/mesalib/src/gallium/auxiliary/util/u_math.h
index f5c14ef8d..426d5daa7 100644
--- a/mesalib/src/gallium/auxiliary/util/u_math.h
+++ b/mesalib/src/gallium/auxiliary/util/u_math.h
@@ -246,6 +246,19 @@ union di {
/**
+ * Extract the IEEE float32 exponent.
+ */
+static INLINE signed
+util_get_float32_exponent(float x) {
+ union fi f;
+
+ f.f = x;
+
+ return ((f.ui >> 23) & 0xff) - 127;
+}
+
+
+/**
* Fast version of 2^x
* Identity: exp2(a + b) = exp2(a) * exp2(b)
* Let ipart = int(x)
diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources
index 2aabc0585..744b0adcf 100644
--- a/mesalib/src/glsl/Makefile.sources
+++ b/mesalib/src/glsl/Makefile.sources
@@ -47,6 +47,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/ir_validate.cpp \
$(GLSL_SRCDIR)/ir_variable_refcount.cpp \
$(GLSL_SRCDIR)/linker.cpp \
+ $(GLSL_SRCDIR)/link_atomics.cpp \
$(GLSL_SRCDIR)/link_functions.cpp \
$(GLSL_SRCDIR)/link_interface_blocks.cpp \
$(GLSL_SRCDIR)/link_uniforms.cpp \
diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h
index 97905c6a6..5c214b604 100644
--- a/mesalib/src/glsl/ast.h
+++ b/mesalib/src/glsl/ast.h
@@ -385,6 +385,12 @@ struct ast_type_qualifier {
*/
unsigned explicit_binding:1;
+ /**
+ * Flag set if GL_ARB_shader_atomic counter "offset" layout
+ * qualifier is used.
+ */
+ unsigned explicit_offset:1;
+
/** \name Layout qualifiers for GL_AMD_conservative_depth */
/** \{ */
unsigned depth_any:1;
@@ -448,6 +454,15 @@ struct ast_type_qualifier {
int binding;
/**
+ * Offset specified via GL_ARB_shader_atomic_counter's "offset"
+ * keyword.
+ *
+ * \note
+ * This field is only valid if \c explicit_offset is set.
+ */
+ int offset;
+
+ /**
* Return true if and only if an interpolation qualifier is present.
*/
bool has_interpolation() const;
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index f75e68ce1..76b256c73 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -1997,10 +1997,20 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state,
return false;
}
+ } else if (var->type->contains_atomic()) {
+ assert(ctx->Const.MaxAtomicBufferBindings <= MAX_COMBINED_ATOMIC_BUFFERS);
+ if (unsigned(qual->binding) >= ctx->Const.MaxAtomicBufferBindings) {
+ _mesa_glsl_error(loc, state, "layout(binding = %d) exceeds the "
+ " maximum number of atomic counter buffer bindings"
+ "(%d)", qual->binding,
+ ctx->Const.MaxAtomicBufferBindings);
+
+ return false;
+ }
} else {
_mesa_glsl_error(loc, state,
"the \"binding\" qualifier only applies to uniform "
- "blocks, samplers, or arrays of samplers");
+ "blocks, samplers, atomic counters, or arrays thereof");
return false;
}
@@ -2300,6 +2310,29 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
var->binding = qual->binding;
}
+ if (var->type->contains_atomic()) {
+ if (var->mode == ir_var_uniform) {
+ if (var->explicit_binding) {
+ unsigned *offset = &state->atomic_counter_offsets[var->binding];
+
+ if (*offset % ATOMIC_COUNTER_SIZE)
+ _mesa_glsl_error(loc, state,
+ "misaligned atomic counter offset");
+
+ var->atomic.offset = *offset;
+ *offset += var->type->atomic_size();
+
+ } else {
+ _mesa_glsl_error(loc, state,
+ "atomic counters require explicit binding point");
+ }
+ } else if (var->mode != ir_var_function_in) {
+ _mesa_glsl_error(loc, state, "atomic counters may only be declared as "
+ "function parameters or uniform-qualified "
+ "global variables");
+ }
+ }
+
/* Does the declaration use the deprecated 'attribute' or 'varying'
* keywords?
*/
@@ -2835,6 +2868,18 @@ ast_declarator_list::hir(exec_list *instructions,
(void) this->type->specifier->hir(instructions, state);
decl_type = this->type->glsl_type(& type_name, state);
+
+ /* An offset-qualified atomic counter declaration sets the default
+ * offset for the next declaration within the same atomic counter
+ * buffer.
+ */
+ if (decl_type && decl_type->contains_atomic()) {
+ if (type->qualifier.flags.q.explicit_binding &&
+ type->qualifier.flags.q.explicit_offset)
+ state->atomic_counter_offsets[type->qualifier.binding] =
+ type->qualifier.offset;
+ }
+
if (this->declarations.is_empty()) {
/* If there is no structure involved in the program text, there are two
* possible scenarios:
@@ -2864,6 +2909,11 @@ ast_declarator_list::hir(exec_list *instructions,
_mesa_glsl_error(&loc, state,
"invalid type `%s' in empty declaration",
type_name);
+ } else if (decl_type->base_type == GLSL_TYPE_ATOMIC_UINT) {
+ /* Empty atomic counter declarations are allowed and useful
+ * to set the default offset qualifier.
+ */
+ return NULL;
} else if (this->type->qualifier.precision != ast_precision_none) {
if (this->type->specifier->structure != NULL) {
_mesa_glsl_error(&loc, state,
@@ -4565,6 +4615,17 @@ ast_process_structure_or_interface_block(exec_list *instructions,
"uniform in non-default uniform block contains sampler");
}
+ if (field_type->contains_atomic()) {
+ /* FINISHME: Add a spec quotation here once updated spec
+ * FINISHME: language is available. See Khronos bug #10903
+ * FINISHME: on whether atomic counters are allowed in
+ * FINISHME: structures.
+ */
+ YYLTYPE loc = decl_list->get_location();
+ _mesa_glsl_error(&loc, state, "atomic counter in structure or "
+ "uniform block");
+ }
+
const struct ast_type_qualifier *const qual =
& decl_list->type->qualifier;
if (qual->flags.q.std140 ||
diff --git a/mesalib/src/glsl/ast_type.cpp b/mesalib/src/glsl/ast_type.cpp
index 8aabd95f9..2b088bf8b 100644
--- a/mesalib/src/glsl/ast_type.cpp
+++ b/mesalib/src/glsl/ast_type.cpp
@@ -72,7 +72,8 @@ ast_type_qualifier::has_layout() const
|| this->flags.q.packed
|| this->flags.q.explicit_location
|| this->flags.q.explicit_index
- || this->flags.q.explicit_binding;
+ || this->flags.q.explicit_binding
+ || this->flags.q.explicit_offset;
}
bool
@@ -121,13 +122,18 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
ubo_layout_mask.flags.q.packed = 1;
ubo_layout_mask.flags.q.shared = 1;
+ ast_type_qualifier ubo_binding_mask;
+ ubo_binding_mask.flags.q.explicit_binding = 1;
+ ubo_binding_mask.flags.q.explicit_offset = 1;
+
/* Uniform block layout qualifiers get to overwrite each
* other (rightmost having priority), while all other
* qualifiers currently don't allow duplicates.
*/
if ((this->flags.i & q.flags.i & ~(ubo_mat_mask.flags.i |
- ubo_layout_mask.flags.i)) != 0) {
+ ubo_layout_mask.flags.i |
+ ubo_binding_mask.flags.i)) != 0) {
_mesa_glsl_error(loc, state,
"duplicate layout qualifiers used");
return false;
@@ -168,6 +174,9 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
if (q.flags.q.explicit_binding)
this->binding = q.binding;
+ if (q.flags.q.explicit_offset)
+ this->offset = q.offset;
+
if (q.precision != ast_precision_none)
this->precision = q.precision;
diff --git a/mesalib/src/glsl/builtin_functions.cpp b/mesalib/src/glsl/builtin_functions.cpp
index 3fa0cb5ad..8cb75e5ad 100644
--- a/mesalib/src/glsl/builtin_functions.cpp
+++ b/mesalib/src/glsl/builtin_functions.cpp
@@ -293,7 +293,8 @@ static bool
fs_oes_derivatives(const _mesa_glsl_parse_state *state)
{
return state->target == fragment_shader &&
- (!state->es_shader || state->OES_standard_derivatives_enable);
+ (state->is_version(110, 300) ||
+ state->OES_standard_derivatives_enable);
}
static bool
diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll
index e24df8096..822d70d6b 100644
--- a/mesalib/src/glsl/glsl_lexer.ll
+++ b/mesalib/src/glsl/glsl_lexer.ll
@@ -337,6 +337,7 @@ samplerExternalOES {
return IDENTIFIER;
}
+atomic_uint KEYWORD_WITH_ALT(420, 300, 420, 0, yyextra->ARB_shader_atomic_counters_enable, ATOMIC_UINT);
struct return STRUCT;
void return VOID_TOK;
@@ -518,7 +519,6 @@ restrict KEYWORD(0, 300, 0, 0, RESTRICT);
readonly KEYWORD(0, 300, 0, 0, READONLY);
writeonly KEYWORD(0, 300, 0, 0, WRITEONLY);
resource KEYWORD(0, 300, 0, 0, RESOURCE);
-atomic_uint KEYWORD(0, 300, 0, 0, ATOMIC_UINT);
patch KEYWORD(0, 300, 0, 0, PATCH);
sample KEYWORD(0, 300, 0, 0, SAMPLE);
subroutine KEYWORD(0, 300, 0, 0, SUBROUTINE);
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index 14420f8a3..ada3690f6 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -144,6 +144,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
%token SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS
%token SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
%token SAMPLEREXTERNALOES
+%token ATOMIC_UINT
%token STRUCT VOID_TOK WHILE
%token <identifier> IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
%type <identifier> any_identifier
@@ -173,7 +174,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
%token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4
%token SAMPLER3DRECT
%token SIZEOF CAST NAMESPACE USING
-%token COHERENT RESTRICT READONLY WRITEONLY RESOURCE ATOMIC_UINT PATCH SAMPLE
+%token COHERENT RESTRICT READONLY WRITEONLY RESOURCE PATCH SAMPLE
%token SUBROUTINE
%token ERROR_TOK
@@ -1324,12 +1325,19 @@ layout_qualifier_id:
}
}
- if (state->ARB_shading_language_420pack_enable &&
+ if ((state->ARB_shading_language_420pack_enable ||
+ state->ARB_shader_atomic_counters_enable) &&
match_layout_qualifier("binding", $1, state) == 0) {
$$.flags.q.explicit_binding = 1;
$$.binding = $3;
}
+ if (state->ARB_shader_atomic_counters_enable &&
+ match_layout_qualifier("offset", $1, state) == 0) {
+ $$.flags.q.explicit_offset = 1;
+ $$.offset = $3;
+ }
+
if (match_layout_qualifier("max_vertices", $1, state) == 0) {
$$.flags.q.max_vertices = 1;
@@ -1703,6 +1711,7 @@ basic_type_specifier_nonarray:
| SAMPLER2DMSARRAY { $$ = "sampler2DMSArray"; }
| ISAMPLER2DMSARRAY { $$ = "isampler2DMSArray"; }
| USAMPLER2DMSARRAY { $$ = "usampler2DMSArray"; }
+ | ATOMIC_UINT { $$ = "atomic_uint"; }
;
precision_qualifier:
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index 345d7a018..d232bb3f6 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -373,6 +373,9 @@ struct _mesa_glsl_parse_state {
* Unused for other shader types.
*/
unsigned gs_input_size;
+
+ /** Atomic counter offsets by binding */
+ unsigned atomic_counter_offsets[MAX_COMBINED_ATOMIC_BUFFERS];
};
# define YYLLOC_DEFAULT(Current, Rhs, N) \
diff --git a/mesalib/src/glsl/link_atomics.cpp b/mesalib/src/glsl/link_atomics.cpp
new file mode 100644
index 000000000..2466bbd79
--- /dev/null
+++ b/mesalib/src/glsl/link_atomics.cpp
@@ -0,0 +1,277 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ir.h"
+#include "ir_uniform.h"
+#include "linker.h"
+#include "program/hash_table.h"
+#include "main/macros.h"
+
+namespace {
+ /*
+ * Atomic counter as seen by the program.
+ */
+ struct active_atomic_counter {
+ unsigned id;
+ ir_variable *var;
+ };
+
+ /*
+ * Atomic counter buffer referenced by the program. There is a one
+ * to one correspondence between these and the objects that can be
+ * queried using glGetActiveAtomicCounterBufferiv().
+ */
+ struct active_atomic_buffer {
+ active_atomic_buffer()
+ : counters(0), num_counters(0), stage_references(), size(0)
+ {}
+
+ ~active_atomic_buffer()
+ {
+ free(counters);
+ }
+
+ void push_back(unsigned id, ir_variable *var)
+ {
+ counters = (active_atomic_counter *)
+ realloc(counters, sizeof(active_atomic_counter) * (num_counters + 1));
+
+ counters[num_counters].id = id;
+ counters[num_counters].var = var;
+ num_counters++;
+ }
+
+ active_atomic_counter *counters;
+ unsigned num_counters;
+ unsigned stage_references[MESA_SHADER_TYPES];
+ unsigned size;
+ };
+
+ int
+ cmp_actives(const void *a, const void *b)
+ {
+ const active_atomic_counter *const first = (active_atomic_counter *) a;
+ const active_atomic_counter *const second = (active_atomic_counter *) b;
+
+ return int(first->var->atomic.offset) - int(second->var->atomic.offset);
+ }
+
+ bool
+ check_atomic_counters_overlap(const ir_variable *x, const ir_variable *y)
+ {
+ return ((x->atomic.offset >= y->atomic.offset &&
+ x->atomic.offset < y->atomic.offset + y->type->atomic_size()) ||
+ (y->atomic.offset >= x->atomic.offset &&
+ y->atomic.offset < x->atomic.offset + x->type->atomic_size()));
+ }
+
+ active_atomic_buffer *
+ find_active_atomic_counters(struct gl_context *ctx,
+ struct gl_shader_program *prog,
+ unsigned *num_buffers)
+ {
+ active_atomic_buffer *const buffers =
+ new active_atomic_buffer[ctx->Const.MaxAtomicBufferBindings];
+
+ *num_buffers = 0;
+
+ for (unsigned i = 0; i < MESA_SHADER_TYPES; ++i) {
+ struct gl_shader *sh = prog->_LinkedShaders[i];
+ if (sh == NULL)
+ continue;
+
+ foreach_list(node, sh->ir) {
+ ir_variable *var = ((ir_instruction *)node)->as_variable();
+
+ if (var && var->type->contains_atomic()) {
+ unsigned id;
+ bool found = prog->UniformHash->get(id, var->name);
+ assert(found);
+ active_atomic_buffer *buf = &buffers[var->binding];
+
+ /* If this is the first time the buffer is used, increment
+ * the counter of buffers used.
+ */
+ if (buf->size == 0)
+ (*num_buffers)++;
+
+ buf->push_back(id, var);
+
+ buf->stage_references[i]++;
+ buf->size = MAX2(buf->size, var->atomic.offset +
+ var->type->atomic_size());
+ }
+ }
+ }
+
+ for (unsigned i = 0; i < ctx->Const.MaxAtomicBufferBindings; i++) {
+ if (buffers[i].size == 0)
+ continue;
+
+ qsort(buffers[i].counters, buffers[i].num_counters,
+ sizeof(active_atomic_counter),
+ cmp_actives);
+
+ for (unsigned j = 1; j < buffers[i].num_counters; j++) {
+ /* If an overlapping counter found, it must be a reference to the
+ * same counter from a different shader stage.
+ */
+ if (check_atomic_counters_overlap(buffers[i].counters[j-1].var,
+ buffers[i].counters[j].var)
+ && strcmp(buffers[i].counters[j-1].var->name,
+ buffers[i].counters[j].var->name) != 0) {
+ linker_error(prog, "Atomic counter %s declared at offset %d "
+ "which is already in use.",
+ buffers[i].counters[j].var->name,
+ buffers[i].counters[j].var->atomic.offset);
+ }
+ }
+ }
+ return buffers;
+ }
+}
+
+void
+link_assign_atomic_counter_resources(struct gl_context *ctx,
+ struct gl_shader_program *prog)
+{
+ unsigned num_buffers;
+ active_atomic_buffer *abs =
+ find_active_atomic_counters(ctx, prog, &num_buffers);
+
+ prog->AtomicBuffers = rzalloc_array(prog, gl_active_atomic_buffer,
+ num_buffers);
+ prog->NumAtomicBuffers = num_buffers;
+
+ unsigned i = 0;
+ for (unsigned binding = 0;
+ binding < ctx->Const.MaxAtomicBufferBindings;
+ binding++) {
+
+ /* If the binding was not used, skip.
+ */
+ if (abs[binding].size == 0)
+ continue;
+
+ active_atomic_buffer &ab = abs[binding];
+ gl_active_atomic_buffer &mab = prog->AtomicBuffers[i];
+
+ /* Assign buffer-specific fields. */
+ mab.Binding = binding;
+ mab.MinimumSize = ab.size;
+ mab.Uniforms = rzalloc_array(prog->AtomicBuffers, GLuint,
+ ab.num_counters);
+ mab.NumUniforms = ab.num_counters;
+
+ /* Assign counter-specific fields. */
+ for (unsigned j = 0; j < ab.num_counters; j++) {
+ ir_variable *const var = ab.counters[j].var;
+ const unsigned id = ab.counters[j].id;
+ gl_uniform_storage *const storage = &prog->UniformStorage[id];
+
+ mab.Uniforms[j] = id;
+ var->atomic.buffer_index = i;
+ storage->atomic_buffer_index = i;
+ storage->offset = var->atomic.offset;
+ storage->array_stride = (var->type->is_array() ?
+ var->type->element_type()->atomic_size() : 0);
+ }
+
+ /* Assign stage-specific fields. */
+ for (unsigned j = 0; j < MESA_SHADER_TYPES; ++j)
+ mab.StageReferences[j] =
+ (ab.stage_references[j] ? GL_TRUE : GL_FALSE);
+
+ i++;
+ }
+
+ delete [] abs;
+ assert(i == num_buffers);
+}
+
+void
+link_check_atomic_counter_resources(struct gl_context *ctx,
+ struct gl_shader_program *prog)
+{
+ STATIC_ASSERT(MESA_SHADER_TYPES == 3);
+ static const char *shader_names[MESA_SHADER_TYPES] = {
+ "vertex", "geometry", "fragment"
+ };
+ const unsigned max_atomic_counters[MESA_SHADER_TYPES] = {
+ ctx->Const.VertexProgram.MaxAtomicCounters,
+ ctx->Const.GeometryProgram.MaxAtomicCounters,
+ ctx->Const.FragmentProgram.MaxAtomicCounters
+ };
+ const unsigned max_atomic_buffers[MESA_SHADER_TYPES] = {
+ ctx->Const.VertexProgram.MaxAtomicBuffers,
+ ctx->Const.GeometryProgram.MaxAtomicBuffers,
+ ctx->Const.FragmentProgram.MaxAtomicBuffers
+ };
+ unsigned num_buffers;
+ active_atomic_buffer *const abs =
+ find_active_atomic_counters(ctx, prog, &num_buffers);
+ unsigned atomic_counters[MESA_SHADER_TYPES] = {};
+ unsigned atomic_buffers[MESA_SHADER_TYPES] = {};
+ unsigned total_atomic_counters = 0;
+ unsigned total_atomic_buffers = 0;
+
+ /* Sum the required resources. Note that this counts buffers and
+ * counters referenced by several shader stages multiple times
+ * against the combined limit -- That's the behavior the spec
+ * requires.
+ */
+ for (unsigned i = 0; i < ctx->Const.MaxAtomicBufferBindings; i++) {
+ if (abs[i].size == 0)
+ continue;
+
+ for (unsigned j = 0; j < MESA_SHADER_TYPES; ++j) {
+ const unsigned n = abs[i].stage_references[j];
+
+ if (n) {
+ atomic_counters[j] += n;
+ total_atomic_counters += n;
+ atomic_buffers[j]++;
+ total_atomic_buffers++;
+ }
+ }
+ }
+
+ /* Check that they are within the supported limits. */
+ for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+ if (atomic_counters[i] > max_atomic_counters[i])
+ linker_error(prog, "Too many %s shader atomic counters",
+ shader_names[i]);
+
+ if (atomic_buffers[i] > max_atomic_buffers[i])
+ linker_error(prog, "Too many %s shader atomic counter buffers",
+ shader_names[i]);
+ }
+
+ if (total_atomic_counters > ctx->Const.MaxCombinedAtomicCounters)
+ linker_error(prog, "Too many combined atomic counters");
+
+ if (total_atomic_buffers > ctx->Const.MaxCombinedAtomicBuffers)
+ linker_error(prog, "Too many combined atomic buffers");
+
+ delete [] abs;
+}
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 49bb142a8..1d53b6599 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -651,6 +651,14 @@ cross_validate_globals(struct gl_shader_program *prog,
existing->explicit_binding = true;
}
+ if (var->type->contains_atomic() &&
+ var->atomic.offset != existing->atomic.offset) {
+ linker_error(prog, "offset specifications for %s "
+ "`%s' have differing values\n",
+ mode_string(var), var->name);
+ return;
+ }
+
/* Validate layout qualifiers for gl_FragDepth.
*
* From the AMD/ARB_conservative_depth specs:
@@ -1485,8 +1493,12 @@ update_array_sizes(struct gl_shader_program *prog)
/* GL_ARB_uniform_buffer_object says that std140 uniforms
* will not be eliminated. Since we always do std140, just
* don't resize arrays in UBOs.
+ *
+ * Atomic counters are supposed to get deterministic
+ * locations assigned based on the declaration ordering and
+ * sizes, array compaction would mess that up.
*/
- if (var->is_in_uniform_block())
+ if (var->is_in_uniform_block() || var->type->contains_atomic())
continue;
unsigned int size = var->max_array_access;
@@ -1991,6 +2003,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
prog->UniformBlockStageIndex[i] = NULL;
}
+ ralloc_free(prog->AtomicBuffers);
+ prog->AtomicBuffers = NULL;
+ prog->NumAtomicBuffers = 0;
+
/* Separate the shaders into groups based on their type.
*/
struct gl_shader **vert_shader_list;
@@ -2342,9 +2358,12 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
update_array_sizes(prog);
link_assign_uniform_locations(prog);
+ link_assign_atomic_counter_resources(ctx, prog);
store_fragdepth_layout(prog);
check_resources(ctx, prog);
+ link_check_atomic_counter_resources(ctx, prog);
+
if (!prog->LinkStatus)
goto done;
diff --git a/mesalib/src/glsl/linker.h b/mesalib/src/glsl/linker.h
index 887cd33d1..7b1f6f9c5 100644
--- a/mesalib/src/glsl/linker.h
+++ b/mesalib/src/glsl/linker.h
@@ -69,6 +69,14 @@ validate_interstage_interface_blocks(struct gl_shader_program *prog,
const gl_shader *producer,
const gl_shader *consumer);
+extern void
+link_assign_atomic_counter_resources(struct gl_context *ctx,
+ struct gl_shader_program *prog);
+
+extern void
+link_check_atomic_counter_resources(struct gl_context *ctx,
+ struct gl_shader_program *prog);
+
/**
* Class for processing all of the leaf fields of a variable that corresponds
* to a program resource.
diff --git a/mesalib/src/mapi/glapi/Makefile.am b/mesalib/src/mapi/glapi/Makefile.am
index 05c67a6d4..bf653a305 100644
--- a/mesalib/src/mapi/glapi/Makefile.am
+++ b/mesalib/src/mapi/glapi/Makefile.am
@@ -33,10 +33,11 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/src/mesa
if HAVE_X86_ASM
-GLAPI_ASM_SOURCES = $(X86_API)
-endif
if HAVE_X86_64_ASM
GLAPI_ASM_SOURCES = $(X86_64_API)
+else
+GLAPI_ASM_SOURCES = $(X86_API)
+endif
endif
if HAVE_SPARC_ASM
GLAPI_ASM_SOURCES = $(SPARC_API)
diff --git a/mesalib/src/mapi/glapi/gen/ARB_vertex_attrib_binding.xml b/mesalib/src/mapi/glapi/gen/ARB_vertex_attrib_binding.xml
new file mode 100644
index 000000000..0ee6a3c00
--- /dev/null
+++ b/mesalib/src/mapi/glapi/gen/ARB_vertex_attrib_binding.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+<OpenGLAPI>
+
+<category name="GL_ARB_vertex_attrib_binding" number="125">
+
+ <function name="BindVertexBuffer" offset="assign">
+ <param name="bindingindex" type="GLuint"/>
+ <param name="buffer" type="GLuint"/>
+ <param name="offset" type="GLintptr"/>
+ <param name="stride" type="GLsizei"/>
+ </function>
+
+ <function name="VertexAttribFormat" offset="assign">
+ <param name="attribindex" type="GLuint"/>
+ <param name="size" type="GLint"/>
+ <param name="type" type="GLenum"/>
+ <param name="normalized" type="GLboolean"/>
+ <param name="relativeoffset" type="GLuint"/>
+ </function>
+
+ <function name="VertexAttribIFormat" offset="assign">
+ <param name="attribindex" type="GLuint"/>
+ <param name="size" type="GLint"/>
+ <param name="type" type="GLenum"/>
+ <param name="relativeoffset" type="GLuint"/>
+ </function>
+
+ <function name="VertexAttribLFormat" offset="assign">
+ <param name="attribindex" type="GLuint"/>
+ <param name="size" type="GLint"/>
+ <param name="type" type="GLenum"/>
+ <param name="relativeoffset" type="GLuint"/>
+ </function>
+
+ <function name="VertexAttribBinding" offset="assign">
+ <param name="attribindex" type="GLuint"/>
+ <param name="bindingindex" type="GLuint"/>
+ </function>
+
+ <function name="VertexBindingDivisor" offset="assign">
+ <param name="attribindex" type="GLuint"/>
+ <param name="divisor" type="GLuint"/>
+ </function>
+
+ <enum name="VERTEX_ATTRIB_BINDING" value="0x82D4"/>
+ <enum name="VERTEX_ATTRIB_RELATIVE_OFFSET" value="0x82D5"/>
+ <enum name="VERTEX_BINDING_DIVISOR" value="0x82D6"/>
+ <enum name="VERTEX_BINDING_OFFSET" value="0x82D7"/>
+ <enum name="VERTEX_BINDING_STRIDE" value="0x82D8"/>
+ <enum name="MAX_VERTEX_ATTRIB_RELATIVE_OFFSET" value="0x82D9"/>
+ <enum name="MAX_VERTEX_ATTRIB_BINDINGS" value="0x82DA"/>
+
+</category>
+</OpenGLAPI>
diff --git a/mesalib/src/mapi/glapi/gen/Makefile.am b/mesalib/src/mapi/glapi/gen/Makefile.am
index cbbf659dd..476d943dd 100644
--- a/mesalib/src/mapi/glapi/gen/Makefile.am
+++ b/mesalib/src/mapi/glapi/gen/Makefile.am
@@ -32,11 +32,11 @@ MESA_GLAPI_OUTPUTS = \
MESA_GLAPI_ASM_OUTPUTS =
if HAVE_X86_ASM
-MESA_GLAPI_ASM_OUTPUTS += $(MESA_GLAPI_DIR)/glapi_x86.S
-endif
-
if HAVE_X86_64_ASM
MESA_GLAPI_ASM_OUTPUTS += $(MESA_GLAPI_DIR)/glapi_x86-64.S
+else
+MESA_GLAPI_ASM_OUTPUTS += $(MESA_GLAPI_DIR)/glapi_x86.S
+endif
endif
if HAVE_SPARC_ASM
@@ -125,6 +125,7 @@ API_XML = \
ARB_texture_storage_multisample.xml \
ARB_texture_storage.xml \
ARB_vertex_array_object.xml \
+ ARB_vertex_attrib_binding.xml \
AMD_draw_buffers_blend.xml \
AMD_performance_monitor.xml \
ARB_vertex_type_2_10_10_10_rev.xml \
diff --git a/mesalib/src/mapi/glapi/gen/gl_API.xml b/mesalib/src/mapi/glapi/gen/gl_API.xml
index 69014c5d2..a2d914ac4 100644
--- a/mesalib/src/mapi/glapi/gen/gl_API.xml
+++ b/mesalib/src/mapi/glapi/gen/gl_API.xml
@@ -8458,7 +8458,11 @@
</category>
-<!-- ARB extensions #120...#126 -->
+<!-- ARB extensions #120...#124 -->
+
+<xi:include href="ARB_vertex_attrib_binding.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+<!-- ARB extension #126 -->
<xi:include href="ARB_ES3_compatibility.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
diff --git a/mesalib/src/mesa/x86/.gitignore b/mesalib/src/mesa/.gitignore
index ca3130d9f..ca3130d9f 100644
--- a/mesalib/src/mesa/x86/.gitignore
+++ b/mesalib/src/mesa/.gitignore
diff --git a/mesalib/src/mesa/Makefile.am b/mesalib/src/mesa/Makefile.am
index a54b8ac1b..a60600e03 100644
--- a/mesalib/src/mesa/Makefile.am
+++ b/mesalib/src/mesa/Makefile.am
@@ -19,7 +19,7 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
-SUBDIRS = x86 x86-64 . main/tests
+SUBDIRS = . main/tests
if HAVE_X11_DRIVER
SUBDIRS += drivers/x11
@@ -81,7 +81,7 @@ main/get_hash.h: $(GLAPI)/gl_and_es_API.xml main/get_hash_params.py \
-f $< > $@.tmp; \
mv $@.tmp $@;
-noinst_LTLIBRARIES =
+noinst_LTLIBRARIES = $(ARCH_LIBS)
if NEED_LIBMESA
noinst_LTLIBRARIES += libmesa.la
else
@@ -98,12 +98,20 @@ AM_CXXFLAGS = $(LLVM_CFLAGS) $(VISIBILITY_CXXFLAGS)
MESA_ASM_FILES_FOR_ARCH =
if HAVE_X86_ASM
-MESA_ASM_FILES_FOR_ARCH += $(X86_FILES)
-AM_CPPFLAGS += -I$(builddir)/x86 -I$(srcdir)/x86
-endif
+noinst_PROGRAMS = gen_matypes
+
+gen_matypes_SOURCES = x86/gen_matypes.c
+BUILT_SOURCES += matypes.h
+
+ARCH_LIBS = libmesa_sse41.la
+
if HAVE_X86_64_ASM
MESA_ASM_FILES_FOR_ARCH += $(X86_64_FILES)
AM_CPPFLAGS += -I$(builddir)/x86-64 -I$(srcdir)/x86-64
+else
+MESA_ASM_FILES_FOR_ARCH += $(X86_FILES)
+AM_CPPFLAGS += -I$(builddir)/x86 -I$(srcdir)/x86
+endif
endif
if HAVE_SPARC_ASM
MESA_ASM_FILES_FOR_ARCH += $(SPARC_FILES)
@@ -117,6 +125,7 @@ libmesa_la_SOURCES = \
libmesa_la_LIBADD = \
$(top_builddir)/src/glsl/libglsl.la \
+ $(ARCH_LIBS) \
$()
libmesagallium_la_SOURCES = \
@@ -126,8 +135,13 @@ libmesagallium_la_SOURCES = \
libmesagallium_la_LIBADD = \
$(top_builddir)/src/glsl/libglsl.la \
+ $(ARCH_LIBS) \
$()
+libmesa_sse41_la_SOURCES = \
+ main/streaming-load-memcpy.c
+libmesa_sse41_la_CFLAGS = $(AM_CFLAGS) -msse4.1
+
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = gl.pc
@@ -139,6 +153,15 @@ $(BUILDDIR)program/program_parse.tab.c $(BUILDDIR)program/program_parse.tab.h: p
$(MKDIR_P) $(builddir)/program
$(AM_V_GEN) $(YACC) -p "_mesa_program_" -v -d --output=$(BUILDDIR)program/program_parse.tab.c $<
+if GEN_ASM_OFFSETS
+matypes.h: $(gen_matypes_SOURCES)
+ $(AM_V_GEN)$(COMPILE) $< -DASM_OFFSETS -S -o - | \
+ sed -n '/^->/{s:^->::;/[$$]/{s:^:#define :;s:[$$]::};p}' > $@
+else
+matypes.h: gen_matypes
+ $(AM_V_GEN)./gen_matypes > $@
+endif
+
# Emacs tags
tags:
etags `find . -name \*.[ch]` $(top_srcdir)/include/GL/*.h
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c
index c28b0fc41..86cf24cb8 100644
--- a/mesalib/src/mesa/drivers/dri/common/dri_util.c
+++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c
@@ -78,6 +78,8 @@ setupLoaderExtensions(__DRIscreen *psp,
psp->dri2.useInvalidate = (__DRIuseInvalidateExtension *) extensions[i];
if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0)
psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i];
+ if (strcmp(extensions[i]->name, __DRI_IMAGE_LOADER) == 0)
+ psp->image.loader = (__DRIimageLoaderExtension *) extensions[i];
}
}
@@ -106,10 +108,10 @@ const struct __DriverAPIRec *globalDriverAPI = &driDriverAPI;
* Display.
*/
static __DRIscreen *
-dri2CreateNewScreen2(int scrn, int fd,
- const __DRIextension **extensions,
- const __DRIextension **driver_extensions,
- const __DRIconfig ***driver_configs, void *data)
+driCreateNewScreen2(int scrn, int fd,
+ const __DRIextension **extensions,
+ const __DRIextension **driver_extensions,
+ const __DRIconfig ***driver_configs, void *data)
{
static const __DRIextension *emptyExtensionList[] = { NULL };
__DRIscreen *psp;
@@ -190,7 +192,7 @@ dri2CreateNewScreen(int scrn, int fd,
const __DRIextension **extensions,
const __DRIconfig ***driver_configs, void *data)
{
- return dri2CreateNewScreen2(scrn, fd, extensions, NULL,
+ return driCreateNewScreen2(scrn, fd, extensions, NULL,
driver_configs, data);
}
@@ -199,7 +201,7 @@ static __DRIscreen *
driSWRastCreateNewScreen(int scrn, const __DRIextension **extensions,
const __DRIconfig ***driver_configs, void *data)
{
- return dri2CreateNewScreen2(scrn, -1, extensions, NULL,
+ return driCreateNewScreen2(scrn, -1, extensions, NULL,
driver_configs, data);
}
@@ -208,7 +210,7 @@ driSWRastCreateNewScreen2(int scrn, const __DRIextension **extensions,
const __DRIextension **driver_extensions,
const __DRIconfig ***driver_configs, void *data)
{
- return dri2CreateNewScreen2(scrn, -1, extensions, driver_extensions,
+ return driCreateNewScreen2(scrn, -1, extensions, driver_extensions,
driver_configs, data);
}
@@ -291,13 +293,13 @@ validate_context_version(__DRIscreen *screen,
/*@{*/
static __DRIcontext *
-dri2CreateContextAttribs(__DRIscreen *screen, int api,
- const __DRIconfig *config,
- __DRIcontext *shared,
- unsigned num_attribs,
- const uint32_t *attribs,
- unsigned *error,
- void *data)
+driCreateContextAttribs(__DRIscreen *screen, int api,
+ const __DRIconfig *config,
+ __DRIcontext *shared,
+ unsigned num_attribs,
+ const uint32_t *attribs,
+ unsigned *error,
+ void *data)
{
__DRIcontext *context;
const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
@@ -306,6 +308,7 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api,
unsigned major_version = 1;
unsigned minor_version = 0;
uint32_t flags = 0;
+ bool notify_reset = false;
assert((num_attribs == 0) || (attribs != NULL));
@@ -344,6 +347,10 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api,
case __DRI_CTX_ATTRIB_FLAGS:
flags = attribs[i * 2 + 1];
break;
+ case __DRI_CTX_ATTRIB_RESET_STRATEGY:
+ notify_reset = (attribs[i * 2 + 1]
+ != __DRI_CTX_RESET_NO_NOTIFICATION);
+ break;
default:
/* We can't create a context that satisfies the requirements of an
* attribute that we don't understand. Return failure.
@@ -424,7 +431,7 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api,
if (!screen->driver->CreateContext(mesa_api, modes, context,
major_version, minor_version,
- flags, error, shareCtx) ) {
+ flags, notify_reset, error, shareCtx)) {
free(context);
return NULL;
}
@@ -442,22 +449,22 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api,
}
static __DRIcontext *
-dri2CreateNewContextForAPI(__DRIscreen *screen, int api,
- const __DRIconfig *config,
- __DRIcontext *shared, void *data)
+driCreateNewContextForAPI(__DRIscreen *screen, int api,
+ const __DRIconfig *config,
+ __DRIcontext *shared, void *data)
{
unsigned error;
- return dri2CreateContextAttribs(screen, api, config, shared, 0, NULL,
- &error, data);
+ return driCreateContextAttribs(screen, api, config, shared, 0, NULL,
+ &error, data);
}
static __DRIcontext *
-dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
- __DRIcontext *shared, void *data)
+driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
+ __DRIcontext *shared, void *data)
{
- return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL,
- config, shared, data);
+ return driCreateNewContextForAPI(screen, __DRI_API_OPENGL,
+ config, shared, data);
}
/**
@@ -609,9 +616,9 @@ static void dri_put_drawable(__DRIdrawable *pdp)
}
static __DRIdrawable *
-dri2CreateNewDrawable(__DRIscreen *screen,
- const __DRIconfig *config,
- void *data)
+driCreateNewDrawable(__DRIscreen *screen,
+ const __DRIconfig *config,
+ void *data)
{
__DRIdrawable *pdraw;
@@ -698,7 +705,7 @@ dri2ConfigQueryf(__DRIscreen *screen, const char *var, GLfloat *val)
}
static unsigned int
-dri2GetAPIMask(__DRIscreen *screen)
+driGetAPIMask(__DRIscreen *screen)
{
return screen->api_mask;
}
@@ -729,7 +736,7 @@ const __DRIcoreExtension driCoreExtension = {
.createNewDrawable = NULL,
.destroyDrawable = driDestroyDrawable,
.swapBuffers = driSwapBuffers, /* swrast */
- .createNewContext = dri2CreateNewContext, /* swrast */
+ .createNewContext = driCreateNewContext, /* swrast */
.copyContext = driCopyContext,
.destroyContext = driDestroyContext,
.bindContext = driBindContext,
@@ -741,22 +748,22 @@ const __DRIdri2Extension driDRI2Extension = {
.base = { __DRI_DRI2, 4 },
.createNewScreen = dri2CreateNewScreen,
- .createNewDrawable = dri2CreateNewDrawable,
- .createNewContext = dri2CreateNewContext,
- .getAPIMask = dri2GetAPIMask,
- .createNewContextForAPI = dri2CreateNewContextForAPI,
+ .createNewDrawable = driCreateNewDrawable,
+ .createNewContext = driCreateNewContext,
+ .getAPIMask = driGetAPIMask,
+ .createNewContextForAPI = driCreateNewContextForAPI,
.allocateBuffer = dri2AllocateBuffer,
.releaseBuffer = dri2ReleaseBuffer,
- .createContextAttribs = dri2CreateContextAttribs,
- .createNewScreen2 = dri2CreateNewScreen2,
+ .createContextAttribs = driCreateContextAttribs,
+ .createNewScreen2 = driCreateNewScreen2,
};
const __DRIswrastExtension driSWRastExtension = {
{ __DRI_SWRAST, 4 },
driSWRastCreateNewScreen,
- dri2CreateNewDrawable,
- dri2CreateNewContextForAPI,
- dri2CreateContextAttribs,
+ driCreateNewDrawable,
+ driCreateNewContextForAPI,
+ driCreateContextAttribs,
driSWRastCreateNewScreen2,
};
@@ -792,3 +799,76 @@ driUpdateFramebufferSize(struct gl_context *ctx, const __DRIdrawable *dPriv)
assert(fb->Height == dPriv->h);
}
}
+
+uint32_t
+driGLFormatToImageFormat(gl_format format)
+{
+ switch (format) {
+ case MESA_FORMAT_RGB565:
+ return __DRI_IMAGE_FORMAT_RGB565;
+ case MESA_FORMAT_XRGB8888:
+ return __DRI_IMAGE_FORMAT_XRGB8888;
+ case MESA_FORMAT_ARGB2101010:
+ return __DRI_IMAGE_FORMAT_ARGB2101010;
+ case MESA_FORMAT_XRGB2101010_UNORM:
+ return __DRI_IMAGE_FORMAT_XRGB2101010;
+ case MESA_FORMAT_ARGB8888:
+ return __DRI_IMAGE_FORMAT_ARGB8888;
+ case MESA_FORMAT_RGBA8888_REV:
+ return __DRI_IMAGE_FORMAT_ABGR8888;
+ case MESA_FORMAT_RGBX8888_REV:
+ return __DRI_IMAGE_FORMAT_XBGR8888;
+ case MESA_FORMAT_R8:
+ return __DRI_IMAGE_FORMAT_R8;
+ case MESA_FORMAT_GR88:
+ return __DRI_IMAGE_FORMAT_GR88;
+ case MESA_FORMAT_NONE:
+ return __DRI_IMAGE_FORMAT_NONE;
+ case MESA_FORMAT_SARGB8:
+ return __DRI_IMAGE_FORMAT_SARGB8;
+ default:
+ return 0;
+ }
+}
+
+gl_format
+driImageFormatToGLFormat(uint32_t image_format)
+{
+ switch (image_format) {
+ case __DRI_IMAGE_FORMAT_RGB565:
+ return MESA_FORMAT_RGB565;
+ case __DRI_IMAGE_FORMAT_XRGB8888:
+ return MESA_FORMAT_XRGB8888;
+ case __DRI_IMAGE_FORMAT_ARGB2101010:
+ return MESA_FORMAT_ARGB2101010;
+ case __DRI_IMAGE_FORMAT_XRGB2101010:
+ return MESA_FORMAT_XRGB2101010_UNORM;
+ case __DRI_IMAGE_FORMAT_ARGB8888:
+ return MESA_FORMAT_ARGB8888;
+ case __DRI_IMAGE_FORMAT_ABGR8888:
+ return MESA_FORMAT_RGBA8888_REV;
+ case __DRI_IMAGE_FORMAT_XBGR8888:
+ return MESA_FORMAT_RGBX8888_REV;
+ case __DRI_IMAGE_FORMAT_R8:
+ return MESA_FORMAT_R8;
+ case __DRI_IMAGE_FORMAT_GR88:
+ return MESA_FORMAT_GR88;
+ case __DRI_IMAGE_FORMAT_SARGB8:
+ return MESA_FORMAT_SARGB8;
+ case __DRI_IMAGE_FORMAT_NONE:
+ return MESA_FORMAT_NONE;
+ default:
+ return MESA_FORMAT_NONE;
+ }
+}
+
+/** Image driver interface */
+const __DRIimageDriverExtension driImageDriverExtension = {
+ .base = { __DRI_IMAGE_DRIVER, __DRI_IMAGE_DRIVER_VERSION },
+
+ .createNewScreen2 = driCreateNewScreen2,
+ .createNewDrawable = driCreateNewDrawable,
+ .createNewContext = driCreateNewContext,
+ .getAPIMask = driGetAPIMask,
+ .createContextAttribs = driCreateContextAttribs,
+};
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.h b/mesalib/src/mesa/drivers/dri/common/dri_util.h
index 5b56061e2..79a8564ad 100644
--- a/mesalib/src/mesa/drivers/dri/common/dri_util.h
+++ b/mesalib/src/mesa/drivers/dri/common/dri_util.h
@@ -57,6 +57,7 @@
#include <GL/internal/dri_interface.h>
#include "main/mtypes.h"
#include "xmlconfig.h"
+#include <stdbool.h>
/**
* Extensions.
@@ -87,6 +88,7 @@ struct __DriverAPIRec {
unsigned major_version,
unsigned minor_version,
uint32_t flags,
+ bool notify_reset,
unsigned *error,
void *sharedContextPrivate);
@@ -174,6 +176,10 @@ struct __DRIscreenRec {
__DRIuseInvalidateExtension *useInvalidate;
} dri2;
+ struct {
+ __DRIimageLoaderExtension *loader;
+ } image;
+
driOptionCache optionInfo;
driOptionCache optionCache;
@@ -271,10 +277,18 @@ struct __DRIdrawableRec {
} dri2;
};
+extern uint32_t
+driGLFormatToImageFormat(gl_format format);
+
+extern gl_format
+driImageFormatToGLFormat(uint32_t image_format);
+
extern void
dri2InvalidateDrawable(__DRIdrawable *drawable);
extern void
driUpdateFramebufferSize(struct gl_context *ctx, const __DRIdrawable *dPriv);
+extern const __DRIimageDriverExtension driImageDriverExtension;
+
#endif /* _DRI_UTIL_H_ */
diff --git a/mesalib/src/mesa/drivers/dri/common/utils.c b/mesalib/src/mesa/drivers/dri/common/utils.c
index f3780d9b6..b30fca903 100644
--- a/mesalib/src/mesa/drivers/dri/common/utils.c
+++ b/mesalib/src/mesa/drivers/dri/common/utils.c
@@ -37,6 +37,7 @@
#include "main/cpuinfo.h"
#include "main/extensions.h"
#include "utils.h"
+#include "dri_util.h"
unsigned
@@ -477,3 +478,66 @@ driIndexConfigAttrib(const __DRIconfig *config, int index,
return GL_FALSE;
}
+
+/**
+ * Implement queries for values that are common across all Mesa drivers
+ *
+ * Currently only the following queries are supported by this function:
+ *
+ * - \c __DRI2_RENDERER_VERSION
+ * - \c __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION
+ * - \c __DRI2_RENDERER_OPENGL_COMPATIBLITY_PROFILE_VERSION
+ * - \c __DRI2_RENDERER_ES_PROFILE_VERSION
+ * - \c __DRI2_RENDERER_ES2_PROFILE_VERSION
+ *
+ * \returns
+ * Zero if a recognized value of \c param is supplied, -1 otherwise.
+ */
+int
+driQueryRendererIntegerCommon(__DRIscreen *psp, int param, int *value)
+{
+ switch (param) {
+ case __DRI2_RENDERER_VERSION: {
+ static const char *const ver = PACKAGE_VERSION;
+ char *endptr;
+ int v[3];
+
+ v[0] = strtol(ver, &endptr, 10);
+ assert(endptr[0] == '.');
+ if (endptr[0] != '.')
+ return -1;
+
+ v[1] = strtol(endptr + 1, &endptr, 10);
+ assert(endptr[0] == '.');
+ if (endptr[0] != '.')
+ return -1;
+
+ v[2] = strtol(endptr + 1, &endptr, 10);
+
+ value[0] = v[0];
+ value[1] = v[1];
+ value[2] = v[2];
+ return 0;
+ }
+ case __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION:
+ value[0] = psp->max_gl_core_version / 10;
+ value[1] = psp->max_gl_core_version % 10;
+ return 0;
+ case __DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION:
+ value[0] = psp->max_gl_compat_version / 10;
+ value[1] = psp->max_gl_compat_version % 10;
+ return 0;
+ case __DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION:
+ value[0] = psp->max_gl_es1_version / 10;
+ value[1] = psp->max_gl_es1_version % 10;
+ return 0;
+ case __DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION:
+ value[0] = psp->max_gl_es2_version / 10;
+ value[1] = psp->max_gl_es2_version % 10;
+ return 0;
+ default:
+ break;
+ }
+
+ return -1;
+}
diff --git a/mesalib/src/mesa/drivers/dri/common/utils.h b/mesalib/src/mesa/drivers/dri/common/utils.h
index e3b3940da..5d6ef879e 100644
--- a/mesalib/src/mesa/drivers/dri/common/utils.h
+++ b/mesalib/src/mesa/drivers/dri/common/utils.h
@@ -65,4 +65,7 @@ int
driIndexConfigAttrib(const __DRIconfig *config, int index,
unsigned int *attrib, unsigned int *value);
+int
+driQueryRendererIntegerCommon(__DRIscreen *psp, int param, int *value);
+
#endif /* DRI_DEBUG_H */
diff --git a/mesalib/src/mesa/main/api_arrayelt.c b/mesalib/src/mesa/main/api_arrayelt.c
index ea0923837..6822465e8 100644
--- a/mesalib/src/mesa/main/api_arrayelt.c
+++ b/mesalib/src/mesa/main/api_arrayelt.c
@@ -35,6 +35,7 @@
*/
#include "glheader.h"
+#include "arrayobj.h"
#include "api_arrayelt.h"
#include "bufferobj.h"
#include "context.h"
@@ -1485,46 +1486,52 @@ _ae_update_state(struct gl_context *ctx)
actx->nr_vbos = 0;
+ if (arrayObj->NewArrays) {
+ /* update the derived client arrays */
+ _mesa_update_array_object_client_arrays(ctx, arrayObj);
+ arrayObj->NewArrays = 0;
+ }
+
/* conventional vertex arrays */
- if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) {
- aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX];
+ if (arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) {
+ aa->array = &arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR_INDEX];
aa->offset = IndexFuncs[TYPE_IDX(aa->array->Type)];
check_vbo(actx, aa->array->BufferObj);
aa++;
}
- if (arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) {
- aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG];
+ if (arrayObj->_VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) {
+ aa->array = &arrayObj->_VertexAttrib[VERT_ATTRIB_EDGEFLAG];
aa->offset = _gloffset_EdgeFlagv;
check_vbo(actx, aa->array->BufferObj);
aa++;
}
- if (arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) {
- aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL];
+ if (arrayObj->_VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) {
+ aa->array = &arrayObj->_VertexAttrib[VERT_ATTRIB_NORMAL];
aa->offset = NormalFuncs[TYPE_IDX(aa->array->Type)];
check_vbo(actx, aa->array->BufferObj);
aa++;
}
- if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) {
- aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0];
+ if (arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) {
+ aa->array = &arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR0];
aa->offset = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
check_vbo(actx, aa->array->BufferObj);
aa++;
}
- if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) {
- aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1];
+ if (arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) {
+ aa->array = &arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR1];
aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)];
check_vbo(actx, aa->array->BufferObj);
aa++;
}
- if (arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) {
- aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_FOG];
+ if (arrayObj->_VertexAttrib[VERT_ATTRIB_FOG].Enabled) {
+ aa->array = &arrayObj->_VertexAttrib[VERT_ATTRIB_FOG];
aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Type)];
check_vbo(actx, aa->array->BufferObj);
aa++;
}
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
struct gl_client_array *attribArray =
- &arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)];
+ &arrayObj->_VertexAttrib[VERT_ATTRIB_TEX(i)];
if (attribArray->Enabled) {
/* NOTE: we use generic glVertexAttribNV functions here.
* If we ever remove GL_NV_vertex_program this will have to change.
@@ -1543,7 +1550,7 @@ _ae_update_state(struct gl_context *ctx)
/* generic vertex attribute arrays */
for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) { /* skip zero! */
struct gl_client_array *attribArray =
- &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)];
+ &arrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC(i)];
if (attribArray->Enabled) {
GLint intOrNorm;
at->array = attribArray;
@@ -1570,18 +1577,18 @@ _ae_update_state(struct gl_context *ctx)
}
/* finally, vertex position */
- if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) {
+ if (arrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) {
/* Use glVertex(v) instead of glVertexAttrib(0, v) to be sure it's
* issued as the last (provoking) attribute).
*/
- aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0];
+ aa->array = &arrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC0];
assert(aa->array->Size >= 2); /* XXX fix someday? */
aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
check_vbo(actx, aa->array->BufferObj);
aa++;
}
- else if (arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) {
- aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_POS];
+ else if (arrayObj->_VertexAttrib[VERT_ATTRIB_POS].Enabled) {
+ aa->array = &arrayObj->_VertexAttrib[VERT_ATTRIB_POS];
aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
check_vbo(actx, aa->array->BufferObj);
aa++;
diff --git a/mesalib/src/mesa/main/arrayobj.c b/mesalib/src/mesa/main/arrayobj.c
index 5d50d29f8..dbf8fdc73 100644
--- a/mesalib/src/mesa/main/arrayobj.c
+++ b/mesalib/src/mesa/main/arrayobj.c
@@ -72,7 +72,7 @@ _mesa_lookup_arrayobj(struct gl_context *ctx, GLuint id)
/**
- * For all the vertex arrays in the array object, unbind any pointers
+ * For all the vertex binding points in the array object, unbind any pointers
* to any buffer objects (VBOs).
* This is done just prior to array object destruction.
*/
@@ -81,8 +81,11 @@ unbind_array_object_vbos(struct gl_context *ctx, struct gl_array_object *obj)
{
GLuint i;
- for (i = 0; i < Elements(obj->VertexAttrib); i++)
- _mesa_reference_buffer_object(ctx, &obj->VertexAttrib[i].BufferObj, NULL);
+ for (i = 0; i < Elements(obj->VertexBinding); i++)
+ _mesa_reference_buffer_object(ctx, &obj->VertexBinding[i].BufferObj, NULL);
+
+ for (i = 0; i < Elements(obj->_VertexAttrib); i++)
+ _mesa_reference_buffer_object(ctx, &obj->_VertexAttrib[i].BufferObj, NULL);
}
@@ -181,20 +184,30 @@ _mesa_reference_array_object_(struct gl_context *ctx,
static void
init_array(struct gl_context *ctx,
- struct gl_client_array *array, GLint size, GLint type)
+ struct gl_array_object *obj, GLuint index, GLint size, GLint type)
{
+ struct gl_vertex_attrib_array *array = &obj->VertexAttrib[index];
+ struct gl_vertex_buffer_binding *binding = &obj->VertexBinding[index];
+
array->Size = size;
array->Type = type;
array->Format = GL_RGBA; /* only significant for GL_EXT_vertex_array_bgra */
array->Stride = 0;
- array->StrideB = 0;
array->Ptr = NULL;
+ array->RelativeOffset = 0;
array->Enabled = GL_FALSE;
array->Normalized = GL_FALSE;
array->Integer = GL_FALSE;
array->_ElementSize = size * _mesa_sizeof_type(type);
+ array->VertexBinding = index;
+
+ binding->Offset = 0;
+ binding->Stride = array->_ElementSize;
+ binding->BufferObj = NULL;
+ binding->_BoundArrays = BITFIELD64_BIT(index);
+
/* Vertex array buffers */
- _mesa_reference_buffer_object(ctx, &array->BufferObj,
+ _mesa_reference_buffer_object(ctx, &binding->BufferObj,
ctx->Shared->NullBufferObj);
}
@@ -215,31 +228,31 @@ _mesa_initialize_array_object( struct gl_context *ctx,
obj->RefCount = 1;
/* Init the individual arrays */
- for (i = 0; i < Elements(obj->VertexAttrib); i++) {
+ for (i = 0; i < Elements(obj->_VertexAttrib); i++) {
switch (i) {
case VERT_ATTRIB_WEIGHT:
- init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_WEIGHT], 1, GL_FLOAT);
+ init_array(ctx, obj, VERT_ATTRIB_WEIGHT, 1, GL_FLOAT);
break;
case VERT_ATTRIB_NORMAL:
- init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_NORMAL], 3, GL_FLOAT);
+ init_array(ctx, obj, VERT_ATTRIB_NORMAL, 3, GL_FLOAT);
break;
case VERT_ATTRIB_COLOR1:
- init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_COLOR1], 3, GL_FLOAT);
+ init_array(ctx, obj, VERT_ATTRIB_COLOR1, 3, GL_FLOAT);
break;
case VERT_ATTRIB_FOG:
- init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_FOG], 1, GL_FLOAT);
+ init_array(ctx, obj, VERT_ATTRIB_FOG, 1, GL_FLOAT);
break;
case VERT_ATTRIB_COLOR_INDEX:
- init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX], 1, GL_FLOAT);
+ init_array(ctx, obj, VERT_ATTRIB_COLOR_INDEX, 1, GL_FLOAT);
break;
case VERT_ATTRIB_EDGEFLAG:
- init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_EDGEFLAG], 1, GL_BOOL);
+ init_array(ctx, obj, VERT_ATTRIB_EDGEFLAG, 1, GL_BOOL);
break;
case VERT_ATTRIB_POINT_SIZE:
- init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_POINT_SIZE], 1, GL_FLOAT);
+ init_array(ctx, obj, VERT_ATTRIB_POINT_SIZE, 1, GL_FLOAT);
break;
default:
- init_array(ctx, &obj->VertexAttrib[i], 4, GL_FLOAT);
+ init_array(ctx, obj, i, 4, GL_FLOAT);
break;
}
}
@@ -279,7 +292,7 @@ remove_array_object( struct gl_context *ctx, struct gl_array_object *obj )
/**
* Helper for _mesa_update_array_object_max_element().
- * \return min(arrayObj->VertexAttrib[*]._MaxElement).
+ * \return min(arrayObj->_VertexAttrib[*]._MaxElement).
*/
static GLuint
compute_max_element(struct gl_array_object *arrayObj, GLbitfield64 enabled)
@@ -291,7 +304,7 @@ compute_max_element(struct gl_array_object *arrayObj, GLbitfield64 enabled)
GLint attrib = ffsll(enabled) - 1;
enabled ^= BITFIELD64_BIT(attrib);
- client_array = &arrayObj->VertexAttrib[attrib];
+ client_array = &arrayObj->_VertexAttrib[attrib];
assert(client_array->Enabled);
_mesa_update_array_max_element(client_array);
min = MIN2(min, client_array->_MaxElement);
@@ -322,6 +335,32 @@ _mesa_update_array_object_max_element(struct gl_context *ctx,
}
+/**
+ * Updates the derived gl_client_arrays when a gl_vertex_attrib_array
+ * or a gl_vertex_buffer_binding has changed.
+ */
+void
+_mesa_update_array_object_client_arrays(struct gl_context *ctx, struct gl_array_object *arrayObj)
+{
+ GLbitfield64 arrays = arrayObj->NewArrays;
+
+ while (arrays) {
+ struct gl_client_array *client_array;
+ struct gl_vertex_attrib_array *attrib_array;
+ struct gl_vertex_buffer_binding *buffer_binding;
+
+ GLint attrib = ffsll(arrays) - 1;
+ arrays ^= BITFIELD64_BIT(attrib);
+
+ attrib_array = &arrayObj->VertexAttrib[attrib];
+ buffer_binding = &arrayObj->VertexBinding[attrib_array->VertexBinding];
+ client_array = &arrayObj->_VertexAttrib[attrib];
+
+ _mesa_update_client_array(ctx, client_array, attrib_array, buffer_binding);
+ }
+}
+
+
/**********************************************************************/
/* API Functions */
/**********************************************************************/
diff --git a/mesalib/src/mesa/main/arrayobj.h b/mesalib/src/mesa/main/arrayobj.h
index 492ef3501..7c3720242 100644
--- a/mesalib/src/mesa/main/arrayobj.h
+++ b/mesalib/src/mesa/main/arrayobj.h
@@ -78,6 +78,11 @@ extern void
_mesa_update_array_object_max_element(struct gl_context *ctx,
struct gl_array_object *arrayObj);
+extern void
+_mesa_update_array_object_client_arrays(struct gl_context *ctx,
+ struct gl_array_object *arrayObj);
+
+
/** Returns the bitmask of all enabled arrays in fixed function mode.
*
* In fixed function mode only the traditional fixed function arrays
diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c
index ca617f744..c9332bd52 100644
--- a/mesalib/src/mesa/main/attrib.c
+++ b/mesalib/src/mesa/main/attrib.c
@@ -1369,8 +1369,11 @@ copy_array_object(struct gl_context *ctx,
/* In theory must be the same anyway, but on recreate make sure it matches */
dest->ARBsemantics = src->ARBsemantics;
- for (i = 0; i < Elements(src->VertexAttrib); i++)
- _mesa_copy_client_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]);
+ for (i = 0; i < Elements(src->_VertexAttrib); i++) {
+ _mesa_copy_client_array(ctx, &dest->_VertexAttrib[i], &src->_VertexAttrib[i]);
+ _mesa_copy_vertex_attrib_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]);
+ _mesa_copy_vertex_buffer_binding(ctx, &dest->VertexBinding[i], &src->VertexBinding[i]);
+ }
/* _Enabled must be the same than on push */
dest->_Enabled = src->_Enabled;
diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c
index 1f5506157..b27f592e8 100644
--- a/mesalib/src/mesa/main/bufferobj.c
+++ b/mesalib/src/mesa/main/bufferobj.c
@@ -655,16 +655,17 @@ _mesa_free_buffer_objects( struct gl_context *ctx )
}
}
-static bool
-handle_bind_buffer_gen(struct gl_context *ctx,
- GLenum target,
- GLuint buffer,
- struct gl_buffer_object **buf_handle)
+bool
+_mesa_handle_bind_buffer_gen(struct gl_context *ctx,
+ GLenum target,
+ GLuint buffer,
+ struct gl_buffer_object **buf_handle,
+ const char *caller)
{
struct gl_buffer_object *buf = *buf_handle;
if (!buf && ctx->API == API_OPENGL_CORE) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBindBuffer(non-gen name)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", caller);
return false;
}
@@ -675,7 +676,7 @@ handle_bind_buffer_gen(struct gl_context *ctx,
ASSERT(ctx->Driver.NewBufferObject);
buf = ctx->Driver.NewBufferObject(ctx, buffer, target);
if (!buf) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
return false;
}
_mesa_HashInsert(ctx->Shared->BufferObjects, buffer, buf);
@@ -719,7 +720,8 @@ bind_buffer_object(struct gl_context *ctx, GLenum target, GLuint buffer)
else {
/* non-default buffer object */
newBufObj = _mesa_lookup_bufferobj(ctx, buffer);
- if (!handle_bind_buffer_gen(ctx, target, buffer, &newBufObj))
+ if (!_mesa_handle_bind_buffer_gen(ctx, target, buffer,
+ &newBufObj, "glBindBuffer"))
return;
}
@@ -862,8 +864,8 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids)
}
/* unbind any vertex pointers bound to this buffer */
- for (j = 0; j < Elements(arrayObj->VertexAttrib); j++) {
- unbind(ctx, &arrayObj->VertexAttrib[j].BufferObj, bufObj);
+ for (j = 0; j < Elements(arrayObj->VertexBinding); j++) {
+ unbind(ctx, &arrayObj->VertexBinding[j].BufferObj, bufObj);
}
if (ctx->Array.ArrayBufferObj == bufObj) {
@@ -2181,7 +2183,8 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
} else {
bufObj = _mesa_lookup_bufferobj(ctx, buffer);
}
- if (!handle_bind_buffer_gen(ctx, target, buffer, &bufObj))
+ if (!_mesa_handle_bind_buffer_gen(ctx, target, buffer,
+ &bufObj, "glBindBufferRange"))
return;
if (!bufObj) {
@@ -2227,7 +2230,8 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
} else {
bufObj = _mesa_lookup_bufferobj(ctx, buffer);
}
- if (!handle_bind_buffer_gen(ctx, target, buffer, &bufObj))
+ if (!_mesa_handle_bind_buffer_gen(ctx, target, buffer,
+ &bufObj, "glBindBufferBase"))
return;
if (!bufObj) {
diff --git a/mesalib/src/mesa/main/bufferobj.h b/mesalib/src/mesa/main/bufferobj.h
index 9b582f8c1..0b898a21b 100644
--- a/mesalib/src/mesa/main/bufferobj.h
+++ b/mesalib/src/mesa/main/bufferobj.h
@@ -28,7 +28,7 @@
#ifndef BUFFEROBJ_H
#define BUFFEROBJ_H
-
+#include <stdbool.h>
#include "mtypes.h"
@@ -62,6 +62,13 @@ _mesa_init_buffer_objects( struct gl_context *ctx );
extern void
_mesa_free_buffer_objects( struct gl_context *ctx );
+extern bool
+_mesa_handle_bind_buffer_gen(struct gl_context *ctx,
+ GLenum target,
+ GLuint buffer,
+ struct gl_buffer_object **buf_handle,
+ const char *caller);
+
extern void
_mesa_update_default_objects_buffer_objects(struct gl_context *ctx);
diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c
index 6cdeed19b..d005d2370 100644
--- a/mesalib/src/mesa/main/context.c
+++ b/mesalib/src/mesa/main/context.c
@@ -678,6 +678,10 @@ _mesa_init_constants(struct gl_context *ctx)
ctx->Const.MaxAtomicBufferSize = MAX_ATOMIC_COUNTERS * ATOMIC_COUNTER_SIZE;
ctx->Const.MaxCombinedAtomicBuffers = MAX_COMBINED_ATOMIC_BUFFERS;
ctx->Const.MaxCombinedAtomicCounters = MAX_ATOMIC_COUNTERS;
+
+ /* GL_ARB_vertex_attrib_binding */
+ ctx->Const.MaxVertexAttribRelativeOffset = 2047;
+ ctx->Const.MaxVertexAttribBindings = MAX_VERTEX_GENERIC_ATTRIBS;
}
@@ -804,7 +808,7 @@ init_attrib_groups(struct gl_context *ctx)
ctx->NewState = _NEW_ALL;
ctx->NewDriverState = ~0;
ctx->ErrorValue = GL_NO_ERROR;
- ctx->ResetStatus = GL_NO_ERROR;
+ ctx->ShareGroupReset = false;
ctx->varying_vp_inputs = VERT_BIT_ALL;
return GL_TRUE;
diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h
index d7c432713..b5b874f47 100644
--- a/mesalib/src/mesa/main/dd.h
+++ b/mesalib/src/mesa/main/dd.h
@@ -890,6 +890,15 @@ struct dd_function_table {
struct gl_texture_object *texObj,
struct gl_texture_image *texImage,
const GLvoid *vdpSurface, GLuint index);
+
+ /**
+ * Query reset status for GL_ARB_robustness
+ *
+ * Per \c glGetGraphicsResetStatusARB, this function should return a
+ * non-zero value once after a reset. If a reset is non-atomic, the
+ * non-zero status should be returned for the duration of the reset.
+ */
+ GLenum (*GetGraphicsResetStatus)(struct gl_context *ctx);
};
diff --git a/mesalib/src/mesa/main/enable.c b/mesalib/src/mesa/main/enable.c
index dd6a772f9..c047f5df2 100644
--- a/mesalib/src/mesa/main/enable.c
+++ b/mesalib/src/mesa/main/enable.c
@@ -135,6 +135,8 @@ client_state(struct gl_context *ctx, GLenum cap, GLboolean state)
else
arrayObj->_Enabled &= ~flag;
+ arrayObj->NewArrays |= flag;
+
if (ctx->Driver.Enable) {
ctx->Driver.Enable( ctx, cap, state );
}
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index 48c4e9f1b..104618c23 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -165,9 +165,11 @@ static const struct extension extension_table[] = {
{ "GL_ARB_uniform_buffer_object", o(ARB_uniform_buffer_object), GL, 2009 },
{ "GL_ARB_vertex_array_bgra", o(EXT_vertex_array_bgra), GL, 2008 },
{ "GL_ARB_vertex_array_object", o(dummy_true), GL, 2006 },
+ { "GL_ARB_vertex_attrib_binding", o(dummy_true), GL, 2012 },
{ "GL_ARB_vertex_buffer_object", o(dummy_true), GLL, 2003 },
{ "GL_ARB_vertex_program", o(ARB_vertex_program), GLL, 2002 },
{ "GL_ARB_vertex_shader", o(ARB_vertex_shader), GL, 2002 },
+ { "GL_ARB_vertex_type_10f_11f_11f_rev", o(ARB_vertex_type_10f_11f_11f_rev), GL, 2013 },
{ "GL_ARB_vertex_type_2_10_10_10_rev", o(ARB_vertex_type_2_10_10_10_rev), GL, 2009 },
{ "GL_ARB_window_pos", o(dummy_true), GLL, 2001 },
/* EXT extensions */
diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c
index 6a0de0c16..eee855007 100644
--- a/mesalib/src/mesa/main/get.c
+++ b/mesalib/src/mesa/main/get.c
@@ -550,7 +550,7 @@ static void
find_custom_value(struct gl_context *ctx, const struct value_desc *d, union value *v)
{
struct gl_buffer_object **buffer_obj;
- struct gl_client_array *array;
+ struct gl_vertex_attrib_array *array;
GLuint unit, *p;
switch (d->pname) {
@@ -775,7 +775,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
break;
case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB:
v->value_int =
- ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].BufferObj->Name;
+ ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].BufferObj->Name;
break;
case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB:
v->value_int = ctx->Array.ArrayObj->ElementArrayBufferObj->Name;
@@ -819,7 +819,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0;
break;
case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
- v->value_int = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POINT_SIZE].BufferObj->Name;
+ v->value_int = ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_POINT_SIZE].BufferObj->Name;
break;
case GL_FOG_COLOR:
@@ -1740,6 +1740,30 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
goto invalid_value;
v->value_int64 = ctx->AtomicBufferBindings[index].Size;
return TYPE_INT64;
+
+ case GL_VERTEX_BINDING_DIVISOR:
+ if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_instanced_arrays)
+ goto invalid_enum;
+ if (index >= ctx->Const.VertexProgram.MaxAttribs)
+ goto invalid_value;
+ v->value_int = ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_GENERIC(index)].InstanceDivisor;
+ return TYPE_INT;
+
+ case GL_VERTEX_BINDING_OFFSET:
+ if (!_mesa_is_desktop_gl(ctx))
+ goto invalid_enum;
+ if (index >= ctx->Const.VertexProgram.MaxAttribs)
+ goto invalid_value;
+ v->value_int = ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_GENERIC(index)].Offset;
+ return TYPE_INT;
+
+ case GL_VERTEX_BINDING_STRIDE:
+ if (!_mesa_is_desktop_gl(ctx))
+ goto invalid_enum;
+ if (index >= ctx->Const.VertexProgram.MaxAttribs)
+ goto invalid_value;
+ v->value_int = ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_GENERIC(index)].Stride;
+ return TYPE_INT;
}
invalid_enum:
diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py
index 0851b7b70..c961feeee 100644
--- a/mesalib/src/mesa/main/get_hash_params.py
+++ b/mesalib/src/mesa/main/get_hash_params.py
@@ -221,9 +221,9 @@ descriptor=[
[ "SAMPLE_ALPHA_TO_ONE_ARB", "CONTEXT_BOOL(Multisample.SampleAlphaToOne), NO_EXTRA" ],
# GL_ARB_vertex_buffer_object
- [ "VERTEX_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexAttrib[VERT_ATTRIB_POS].BufferObj), NO_EXTRA" ],
- [ "NORMAL_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexAttrib[VERT_ATTRIB_NORMAL].BufferObj), NO_EXTRA" ],
- [ "COLOR_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexAttrib[VERT_ATTRIB_COLOR0].BufferObj), NO_EXTRA" ],
+ [ "VERTEX_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexBinding[VERT_ATTRIB_POS].BufferObj), NO_EXTRA" ],
+ [ "NORMAL_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexBinding[VERT_ATTRIB_NORMAL].BufferObj), NO_EXTRA" ],
+ [ "COLOR_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexBinding[VERT_ATTRIB_COLOR0].BufferObj), NO_EXTRA" ],
[ "TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA" ],
# GL_OES_point_sprite
@@ -585,10 +585,10 @@ descriptor=[
[ "PRIMITIVE_RESTART_INDEX_NV", "CONTEXT_INT(Array.RestartIndex), extra_NV_primitive_restart" ],
# GL_ARB_vertex_buffer_object
- [ "INDEX_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexAttrib[VERT_ATTRIB_COLOR_INDEX].BufferObj), NO_EXTRA" ],
- [ "EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexAttrib[VERT_ATTRIB_EDGEFLAG].BufferObj), NO_EXTRA" ],
- [ "SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexAttrib[VERT_ATTRIB_COLOR1].BufferObj), NO_EXTRA" ],
- [ "FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexAttrib[VERT_ATTRIB_FOG].BufferObj), NO_EXTRA" ],
+ [ "INDEX_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexBinding[VERT_ATTRIB_COLOR_INDEX].BufferObj), NO_EXTRA" ],
+ [ "EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexBinding[VERT_ATTRIB_EDGEFLAG].BufferObj), NO_EXTRA" ],
+ [ "SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexBinding[VERT_ATTRIB_COLOR1].BufferObj), NO_EXTRA" ],
+ [ "FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_array_object, VertexBinding[VERT_ATTRIB_FOG].BufferObj), NO_EXTRA" ],
# GL_ARB_vertex_program
# == GL_VERTEX_PROGRAM_NV
@@ -737,6 +737,10 @@ descriptor=[
[ "MAX_GEOMETRY_ATOMIC_COUNTERS", "CONTEXT_INT(Const.GeometryProgram.MaxAtomicCounters), extra_ARB_shader_atomic_counters_and_geometry_shader" ],
[ "MAX_COMBINED_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.MaxCombinedAtomicBuffers), extra_ARB_shader_atomic_counters" ],
[ "MAX_COMBINED_ATOMIC_COUNTERS", "CONTEXT_INT(Const.MaxCombinedAtomicCounters), extra_ARB_shader_atomic_counters" ],
+
+# GL_ARB_vertex_attrib_binding
+ [ "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET", "CONTEXT_ENUM(Const.MaxVertexAttribRelativeOffset), NO_EXTRA" ],
+ [ "MAX_VERTEX_ATTRIB_BINDINGS", "CONTEXT_ENUM(Const.MaxVertexAttribBindings), NO_EXTRA" ],
]},
# Enums restricted to OpenGL Core profile
diff --git a/mesalib/src/mesa/main/getstring.c b/mesalib/src/mesa/main/getstring.c
index 0e075427f..d8189115a 100644
--- a/mesalib/src/mesa/main/getstring.c
+++ b/mesalib/src/mesa/main/getstring.c
@@ -23,7 +23,7 @@
*/
-
+#include <stdbool.h>
#include "glheader.h"
#include "context.h"
#include "get.h"
@@ -305,11 +305,50 @@ GLenum GLAPIENTRY
_mesa_GetGraphicsResetStatusARB( void )
{
GET_CURRENT_CONTEXT(ctx);
- GLenum status = ctx->ResetStatus;
+ GLenum status = GL_NO_ERROR;
+
+ /* The ARB_robustness specification says:
+ *
+ * "If the reset notification behavior is NO_RESET_NOTIFICATION_ARB,
+ * then the implementation will never deliver notification of reset
+ * events, and GetGraphicsResetStatusARB will always return NO_ERROR."
+ */
+ if (ctx->Const.ResetStrategy == GL_NO_RESET_NOTIFICATION_ARB) {
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx,
+ "glGetGraphicsResetStatusARB always returns GL_NO_ERROR "
+ "because reset notifictation was not requested at context "
+ "creation.\n");
+
+ return GL_NO_ERROR;
+ }
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glGetGraphicsResetStatusARB"
- "(always returns GL_NO_ERROR)\n");
+ if (ctx->Driver.GetGraphicsResetStatus) {
+ /* Query the reset status of this context from the driver core.
+ */
+ status = ctx->Driver.GetGraphicsResetStatus(ctx);
+
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+
+ /* If this context has not been affected by a GPU reset, check to see if
+ * some other context in the share group has been affected by a reset.
+ * If another context saw a reset but this context did not, assume that
+ * this context was not guilty.
+ */
+ if (status != GL_NO_ERROR) {
+ ctx->Shared->ShareGroupReset = true;
+ } else if (ctx->Shared->ShareGroupReset && !ctx->ShareGroupReset) {
+ status = GL_INNOCENT_CONTEXT_RESET_ARB;
+ }
+
+ ctx->ShareGroupReset = ctx->Shared->ShareGroupReset;
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ }
+
+ if (!ctx->Driver.GetGraphicsResetStatus && (MESA_VERBOSE & VERBOSE_API))
+ _mesa_debug(ctx,
+ "glGetGraphicsResetStatusARB always returns GL_NO_ERROR "
+ "because the driver doesn't track reset status.\n");
return status;
}
diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c
index dfee6f196..740faa890 100644
--- a/mesalib/src/mesa/main/glformats.c
+++ b/mesalib/src/mesa/main/glformats.c
@@ -345,6 +345,11 @@ _mesa_bytes_per_vertex_attrib(GLint comps, GLenum type)
return sizeof(GLuint);
else
return -1;
+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ if (comps == 3)
+ return sizeof(GLuint);
+ else
+ return -1;
default:
return -1;
}
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index b5c5583d6..ae96e2326 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -35,6 +35,7 @@
#include <stdint.h> /* uint32_t */
+#include <stdbool.h>
#include "main/glheader.h"
#include "main/config.h"
@@ -1474,6 +1475,44 @@ struct gl_client_array
/**
+ * Vertex attribute array as seen by the client.
+ *
+ * Contains the size, type, format and normalization flag,
+ * along with the index of a vertex buffer binding point.
+ *
+ * Note that the Stride field corresponds to VERTEX_ATTRIB_ARRAY_STRIDE
+ * and is only present for backwards compatibility reasons.
+ * Rendering always uses VERTEX_BINDING_STRIDE.
+ * The gl*Pointer() functions will set VERTEX_ATTRIB_ARRAY_STRIDE
+ * and VERTEX_BINDING_STRIDE to the same value, while
+ * glBindVertexBuffer() will only set VERTEX_BINDING_STRIDE.
+ */
+struct gl_vertex_attrib_array
+{
+ GLint Size; /**< Components per element (1,2,3,4) */
+ GLenum Type; /**< Datatype: GL_FLOAT, GL_INT, etc */
+ GLenum Format; /**< Default: GL_RGBA, but may be GL_BGRA */
+ GLsizei Stride; /**< Stride as specified with gl*Pointer() */
+ const GLubyte *Ptr; /**< Points to client array data. Not used when a VBO is bound */
+ GLintptr RelativeOffset; /**< Offset of the first element relative to the binding offset */
+ GLboolean Enabled; /**< Whether the array is enabled */
+ GLboolean Normalized; /**< Fixed-point values are normalized when converted to floats */
+ GLboolean Integer; /**< Fixed-point values are not converted to floats */
+ GLuint _ElementSize; /**< Size of each element in bytes */
+ GLuint VertexBinding; /**< Vertex buffer binding */
+};
+
+struct gl_vertex_buffer_binding
+{
+ GLintptr Offset; /**< User-specified offset */
+ GLsizei Stride; /**< User-specified stride */
+ GLuint InstanceDivisor; /**< GL_ARB_instanced_arrays */
+ struct gl_buffer_object *BufferObj; /**< GL_ARB_vertex_buffer_object */
+ GLbitfield64 _BoundArrays; /**< Arrays bound to this binding point */
+};
+
+
+/**
* Collection of vertex arrays. Defined by the GL_APPLE_vertex_array_object
* extension, but a nice encapsulation in any case.
*/
@@ -1507,12 +1546,21 @@ struct gl_array_object
*/
GLboolean EverBound;
+ /** Derived vertex attribute arrays */
+ struct gl_client_array _VertexAttrib[VERT_ATTRIB_MAX];
+
/** Vertex attribute arrays */
- struct gl_client_array VertexAttrib[VERT_ATTRIB_MAX];
+ struct gl_vertex_attrib_array VertexAttrib[VERT_ATTRIB_MAX];
+
+ /** Vertex buffer bindings */
+ struct gl_vertex_buffer_binding VertexBinding[VERT_ATTRIB_MAX];
/** Mask of VERT_BIT_* values indicating which arrays are enabled */
GLbitfield64 _Enabled;
+ /** Mask of VERT_BIT_* values indicating changed/dirty arrays */
+ GLbitfield64 NewArrays;
+
/**
* Min of all enabled arrays' _MaxElement. When arrays reside inside VBOs
* we can determine the max legal (in bounds) glDrawElements array index.
@@ -2765,6 +2813,17 @@ struct gl_shared_state
/** GL_ARB_sampler_objects */
struct _mesa_HashTable *SamplerObjects;
+
+ /**
+ * Some context in this share group was affected by a GPU reset
+ *
+ * On the next call to \c glGetGraphicsResetStatus, contexts that have not
+ * been affected by a GPU reset must also return
+ * \c GL_INNOCENT_CONTEXT_RESET_ARB.
+ *
+ * Once this field becomes true, it is never reset to false.
+ */
+ bool ShareGroupReset;
};
@@ -3213,6 +3272,10 @@ struct gl_constants
GLuint MaxAtomicBufferSize;
GLuint MaxCombinedAtomicBuffers;
GLuint MaxCombinedAtomicCounters;
+
+ /** GL_ARB_vertex_attrib_binding */
+ GLint MaxVertexAttribRelativeOffset;
+ GLint MaxVertexAttribBindings;
};
@@ -3291,6 +3354,7 @@ struct gl_extensions
GLboolean ARB_uniform_buffer_object;
GLboolean ARB_vertex_program;
GLboolean ARB_vertex_shader;
+ GLboolean ARB_vertex_type_10f_11f_11f_rev;
GLboolean ARB_vertex_type_2_10_10_10_rev;
GLboolean EXT_blend_color;
GLboolean EXT_blend_equation_separate;
@@ -3851,9 +3915,6 @@ struct gl_context
GLenum ErrorValue; /**< Last error code */
- /* GL_ARB_robustness */
- GLenum ResetStatus;
-
/**
* Recognize and silence repeated error debug messages in buggy apps.
*/
@@ -3918,6 +3979,13 @@ struct gl_context
const void *vdpGetProcAddress;
struct set *vdpSurfaces;
/*@}*/
+
+ /**
+ * Has this context observed a GPU reset in any context in the share group?
+ *
+ * Once this field becomes true, it is never reset to false.
+ */
+ GLboolean ShareGroupReset;
};
diff --git a/mesalib/src/mesa/main/state.c b/mesalib/src/mesa/main/state.c
index 23926410b..33070b7e0 100644
--- a/mesalib/src/mesa/main/state.c
+++ b/mesalib/src/mesa/main/state.c
@@ -410,6 +410,9 @@ _mesa_update_state_locked( struct gl_context *ctx )
new_prog_state |= update_program( ctx );
}
+ if (new_state & _NEW_ARRAY)
+ _mesa_update_array_object_client_arrays(ctx, ctx->Array.ArrayObj);
+
if (ctx->Const.CheckArrayBounds &&
new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) {
_mesa_update_array_object_max_element(ctx, ctx->Array.ArrayObj);
@@ -430,6 +433,7 @@ _mesa_update_state_locked( struct gl_context *ctx )
new_state = ctx->NewState | new_prog_state;
ctx->NewState = 0;
ctx->Driver.UpdateState(ctx, new_state);
+ ctx->Array.ArrayObj->NewArrays = 0x0;
}
diff --git a/mesalib/src/mesa/main/streaming-load-memcpy.c b/mesalib/src/mesa/main/streaming-load-memcpy.c
new file mode 100644
index 000000000..d7147afdc
--- /dev/null
+++ b/mesalib/src/mesa/main/streaming-load-memcpy.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ * Matt Turner <mattst88@gmail.com>
+ *
+ */
+
+#include "main/macros.h"
+#include "main/streaming-load-memcpy.h"
+#include <smmintrin.h>
+
+/* Copies memory from src to dst, using SSE 4.1's MOVNTDQA to get streaming
+ * read performance from uncached memory.
+ */
+void
+_mesa_streaming_load_memcpy(void *restrict dst, void *restrict src, size_t len)
+{
+ char *restrict d = dst;
+ char *restrict s = src;
+
+ /* If dst and src are not co-aligned, fallback to memcpy(). */
+ if (((uintptr_t)d & 15) != ((uintptr_t)s & 15)) {
+ memcpy(d, s, len);
+ return;
+ }
+
+ /* memcpy() the misaligned header. At the end of this if block, <d> and <s>
+ * are aligned to a 16-byte boundary or <len> == 0.
+ */
+ if ((uintptr_t)d & 15) {
+ uintptr_t bytes_before_alignment_boundary = 16 - ((uintptr_t)d & 15);
+ assert(bytes_before_alignment_boundary < 16);
+
+ memcpy(d, s, MIN2(bytes_before_alignment_boundary, len));
+
+ d = (char *)ALIGN((uintptr_t)d, 16);
+ s = (char *)ALIGN((uintptr_t)s, 16);
+ len -= MIN2(bytes_before_alignment_boundary, len);
+ }
+
+ while (len >= 64) {
+ __m128i *dst_cacheline = (__m128i *)d;
+ __m128i *src_cacheline = (__m128i *)s;
+
+ __m128i temp1 = _mm_stream_load_si128(src_cacheline + 0);
+ __m128i temp2 = _mm_stream_load_si128(src_cacheline + 1);
+ __m128i temp3 = _mm_stream_load_si128(src_cacheline + 2);
+ __m128i temp4 = _mm_stream_load_si128(src_cacheline + 3);
+
+ _mm_store_si128(dst_cacheline + 0, temp1);
+ _mm_store_si128(dst_cacheline + 1, temp2);
+ _mm_store_si128(dst_cacheline + 2, temp3);
+ _mm_store_si128(dst_cacheline + 3, temp4);
+
+ d += 64;
+ s += 64;
+ len -= 64;
+ }
+
+ /* memcpy() the tail. */
+ if (len) {
+ memcpy(d, s, len);
+ }
+}
diff --git a/mesalib/src/mesa/main/streaming-load-memcpy.h b/mesalib/src/mesa/main/streaming-load-memcpy.h
new file mode 100644
index 000000000..41eeeeca0
--- /dev/null
+++ b/mesalib/src/mesa/main/streaming-load-memcpy.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ * Matt Turner <mattst88@gmail.com>
+ *
+ */
+
+/* Copies memory from src to dst, using SSE 4.1's MOVNTDQA to get streaming
+ * read performance from uncached memory.
+ */
+void
+_mesa_streaming_load_memcpy(void *restrict dst, void *restrict src, size_t len);
diff --git a/mesalib/src/mesa/main/varray.c b/mesalib/src/mesa/main/varray.c
index dee476abb..d17d698d3 100644
--- a/mesalib/src/mesa/main/varray.c
+++ b/mesalib/src/mesa/main/varray.c
@@ -60,6 +60,7 @@
#define FIXED_GL_BIT 0x800
#define UNSIGNED_INT_2_10_10_10_REV_BIT 0x1000
#define INT_2_10_10_10_REV_BIT 0x2000
+#define UNSIGNED_INT_10F_11F_11F_REV_BIT 0x4000
/** Convert GL datatype enum into a <type>_BIT value seen above */
@@ -96,6 +97,8 @@ type_to_bit(const struct gl_context *ctx, GLenum type)
return UNSIGNED_INT_2_10_10_10_REV_BIT;
case GL_INT_2_10_10_10_REV:
return INT_2_10_10_10_REV_BIT;
+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ return UNSIGNED_INT_10F_11F_11F_REV_BIT;
default:
return 0;
}
@@ -103,54 +106,110 @@ type_to_bit(const struct gl_context *ctx, GLenum type)
/**
- * Do error checking and update state for glVertex/Color/TexCoord/...Pointer
- * functions.
- *
- * \param func name of calling function used for error reporting
- * \param attrib the attribute array index to update
- * \param legalTypes bitmask of *_BIT above indicating legal datatypes
- * \param sizeMin min allowable size value
- * \param sizeMax max allowable size value (may also be BGRA_OR_4)
- * \param size components per element (1, 2, 3 or 4)
- * \param type datatype of each component (GL_FLOAT, GL_INT, etc)
- * \param stride stride between elements, in elements
- * \param normalized are integer types converted to floats in [-1, 1]?
- * \param integer integer-valued values (will not be normalized to [-1,1])
- * \param ptr the address (or offset inside VBO) of the array data
+ * Sets the VertexBinding field in the vertex attribute given by attribIndex.
*/
static void
-update_array(struct gl_context *ctx,
- const char *func,
- GLuint attrib, GLbitfield legalTypesMask,
- GLint sizeMin, GLint sizeMax,
- GLint size, GLenum type, GLsizei stride,
- GLboolean normalized, GLboolean integer,
- const GLvoid *ptr)
+vertex_attrib_binding(struct gl_context *ctx, GLuint attribIndex,
+ GLuint bindingIndex)
{
- struct gl_client_array *array;
- GLbitfield typeBit;
- GLsizei elementSize;
- GLenum format = GL_RGBA;
+ struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
+ struct gl_vertex_attrib_array *array = &arrayObj->VertexAttrib[attribIndex];
- /* Page 407 (page 423 of the PDF) of the OpenGL 3.0 spec says:
- *
- * "Client vertex arrays - all vertex array attribute pointers must
- * refer to buffer objects (section 2.9.2). The default vertex array
- * object (the name zero) is also deprecated. Calling
- * VertexAttribPointer when no buffer object or no vertex array object
- * is bound will generate an INVALID_OPERATION error..."
- *
- * The check for VBOs is handled below.
- */
- if (ctx->API == API_OPENGL_CORE
- && (ctx->Array.ArrayObj == ctx->Array.DefaultArrayObj)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no array object bound)",
- func);
- return;
+ if (array->VertexBinding != bindingIndex) {
+ const GLbitfield64 array_bit = VERT_BIT(attribIndex);
+
+ FLUSH_VERTICES(ctx, _NEW_ARRAY);
+
+ arrayObj->VertexBinding[array->VertexBinding]._BoundArrays &= ~array_bit;
+ arrayObj->VertexBinding[bindingIndex]._BoundArrays |= array_bit;
+
+ array->VertexBinding = bindingIndex;
+
+ arrayObj->NewArrays |= array_bit;
}
+}
+
+
+/**
+ * Binds a buffer object to the vertex buffer binding point given by index,
+ * and sets the Offset and Stride fields.
+ */
+static void
+bind_vertex_buffer(struct gl_context *ctx, GLuint index,
+ struct gl_buffer_object *vbo,
+ GLintptr offset, GLsizei stride)
+{
+ struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
+ struct gl_vertex_buffer_binding *binding = &arrayObj->VertexBinding[index];
+
+ if (binding->BufferObj != vbo ||
+ binding->Offset != offset ||
+ binding->Stride != stride) {
+
+ FLUSH_VERTICES(ctx, _NEW_ARRAY);
+
+ _mesa_reference_buffer_object(ctx, &binding->BufferObj, vbo);
+
+ binding->Offset = offset;
+ binding->Stride = stride;
+
+ arrayObj->NewArrays |= binding->_BoundArrays;
+ }
+}
+
+
+/**
+ * Sets the InstanceDivisor field in the vertex buffer binding point
+ * given by bindingIndex.
+ */
+static void
+vertex_binding_divisor(struct gl_context *ctx, GLuint bindingIndex,
+ GLuint divisor)
+{
+ struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
+ struct gl_vertex_buffer_binding *binding =
+ &arrayObj->VertexBinding[bindingIndex];
+
+ if (binding->InstanceDivisor != divisor) {
+ FLUSH_VERTICES(ctx, _NEW_ARRAY);
+ binding->InstanceDivisor = divisor;
+ arrayObj->NewArrays |= binding->_BoundArrays;
+ }
+}
+
+
+/**
+ * Does error checking and updates the format in an attrib array.
+ *
+ * Called by update_array() and VertexAttrib*Format().
+ *
+ * \param func Name of calling function used for error reporting
+ * \param attrib The index of the attribute array
+ * \param legalTypes Bitmask of *_BIT above indicating legal datatypes
+ * \param sizeMin Min allowable size value
+ * \param sizeMax Max allowable size value (may also be BGRA_OR_4)
+ * \param size Components per element (1, 2, 3 or 4)
+ * \param type Datatype of each component (GL_FLOAT, GL_INT, etc)
+ * \param normalized Whether integer types are converted to floats in [-1, 1]
+ * \param integer Integer-valued values (will not be normalized to [-1, 1])
+ * \param relativeOffset Offset of the first element relative to the binding offset.
+ */
+static bool
+update_array_format(struct gl_context *ctx,
+ const char *func,
+ GLuint attrib, GLbitfield legalTypesMask,
+ GLint sizeMin, GLint sizeMax,
+ GLint size, GLenum type,
+ GLboolean normalized, GLboolean integer,
+ GLuint relativeOffset)
+{
+ struct gl_vertex_attrib_array *array;
+ GLbitfield typeBit;
+ GLuint elementSize;
+ GLenum format = GL_RGBA;
if (_mesa_is_gles(ctx)) {
- legalTypesMask &= ~(FIXED_GL_BIT | DOUBLE_BIT);
+ legalTypesMask &= ~(FIXED_GL_BIT | DOUBLE_BIT | UNSIGNED_INT_10F_11F_11F_REV_BIT);
/* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until
* 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or
@@ -180,13 +239,16 @@ update_array(struct gl_context *ctx,
if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev)
legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT |
INT_2_10_10_10_REV_BIT);
+
+ if (!ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev)
+ legalTypesMask &= ~UNSIGNED_INT_10F_11F_11F_REV_BIT;
}
typeBit = type_to_bit(ctx, type);
if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)",
func, _mesa_lookup_enum_by_nr(type));
- return;
+ return false;
}
/* Do size parameter checking.
@@ -206,26 +268,26 @@ update_array(struct gl_context *ctx,
* ...
* • size is BGRA and normalized is FALSE;"
*/
- GLboolean bgra_error = GL_FALSE;
+ bool bgra_error = false;
if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) {
if (type != GL_UNSIGNED_INT_2_10_10_10_REV &&
type != GL_INT_2_10_10_10_REV &&
type != GL_UNSIGNED_BYTE)
- bgra_error = GL_TRUE;
+ bgra_error = true;
} else if (type != GL_UNSIGNED_BYTE)
- bgra_error = GL_TRUE;
+ bgra_error = true;
if (bgra_error) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=GL_BGRA and type=%s)",
func, _mesa_lookup_enum_by_nr(type));
- return;
+ return false;
}
if (!normalized) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(size=GL_BGRA and normalized=GL_FALSE)", func);
- return;
+ return false;
}
format = GL_BGRA;
@@ -233,18 +295,106 @@ update_array(struct gl_context *ctx,
}
else if (size < sizeMin || size > sizeMax || size > 4) {
_mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size);
- return;
+ return false;
}
if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev &&
(type == GL_UNSIGNED_INT_2_10_10_10_REV ||
type == GL_INT_2_10_10_10_REV) && size != 4) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
- return;
+ return false;
+ }
+
+ /* The ARB_vertex_attrib_binding_spec says:
+ *
+ * An INVALID_VALUE error is generated if <relativeoffset> is larger than
+ * the value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.
+ */
+ if (relativeOffset > ctx->Const.MaxVertexAttribRelativeOffset) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(relativeOffset=%d > "
+ "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET)",
+ func, relativeOffset);
+ return false;
+ }
+
+ if (ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev &&
+ type == GL_UNSIGNED_INT_10F_11F_11F_REV && size != 3) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
+ return false;
}
ASSERT(size <= 4);
+ elementSize = _mesa_bytes_per_vertex_attrib(size, type);
+ assert(elementSize != -1);
+
+ array = &ctx->Array.ArrayObj->VertexAttrib[attrib];
+ array->Size = size;
+ array->Type = type;
+ array->Format = format;
+ array->Normalized = normalized;
+ array->Integer = integer;
+ array->RelativeOffset = relativeOffset;
+ array->_ElementSize = elementSize;
+
+ ctx->Array.ArrayObj->NewArrays |= VERT_BIT(attrib);
+ ctx->NewState |= _NEW_ARRAY;
+
+ return true;
+}
+
+
+/**
+ * Do error checking and update state for glVertex/Color/TexCoord/...Pointer
+ * functions.
+ *
+ * \param func name of calling function used for error reporting
+ * \param attrib the attribute array index to update
+ * \param legalTypes bitmask of *_BIT above indicating legal datatypes
+ * \param sizeMin min allowable size value
+ * \param sizeMax max allowable size value (may also be BGRA_OR_4)
+ * \param size components per element (1, 2, 3 or 4)
+ * \param type datatype of each component (GL_FLOAT, GL_INT, etc)
+ * \param stride stride between elements, in elements
+ * \param normalized are integer types converted to floats in [-1, 1]?
+ * \param integer integer-valued values (will not be normalized to [-1,1])
+ * \param ptr the address (or offset inside VBO) of the array data
+ */
+static void
+update_array(struct gl_context *ctx,
+ const char *func,
+ GLuint attrib, GLbitfield legalTypesMask,
+ GLint sizeMin, GLint sizeMax,
+ GLint size, GLenum type, GLsizei stride,
+ GLboolean normalized, GLboolean integer,
+ const GLvoid *ptr)
+{
+ struct gl_vertex_attrib_array *array;
+ GLsizei effectiveStride;
+
+ /* Page 407 (page 423 of the PDF) of the OpenGL 3.0 spec says:
+ *
+ * "Client vertex arrays - all vertex array attribute pointers must
+ * refer to buffer objects (section 2.9.2). The default vertex array
+ * object (the name zero) is also deprecated. Calling
+ * VertexAttribPointer when no buffer object or no vertex array object
+ * is bound will generate an INVALID_OPERATION error..."
+ *
+ * The check for VBOs is handled below.
+ */
+ if (ctx->API == API_OPENGL_CORE
+ && (ctx->Array.ArrayObj == ctx->Array.DefaultArrayObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no array object bound)",
+ func);
+ return;
+ }
+
+ if (!update_array_format(ctx, func, attrib, legalTypesMask, sizeMin, sizeMax,
+ size, type, normalized, integer, 0)) {
+ return;
+ }
+
if (stride < 0) {
_mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride );
return;
@@ -268,24 +418,18 @@ update_array(struct gl_context *ctx,
return;
}
- elementSize = _mesa_bytes_per_vertex_attrib(size, type);
- assert(elementSize != -1);
+ /* Reset the vertex attrib binding */
+ vertex_attrib_binding(ctx, attrib, attrib);
+ /* The Stride and Ptr fields are not set by update_array_format() */
array = &ctx->Array.ArrayObj->VertexAttrib[attrib];
- array->Size = size;
- array->Type = type;
- array->Format = format;
array->Stride = stride;
- array->StrideB = stride ? stride : elementSize;
- array->Normalized = normalized;
- array->Integer = integer;
- array->Ptr = (const GLubyte *) ptr;
- array->_ElementSize = elementSize;
+ array->Ptr = (const GLvoid *) ptr;
- _mesa_reference_buffer_object(ctx, &array->BufferObj,
- ctx->Array.ArrayBufferObj);
-
- ctx->NewState |= _NEW_ARRAY;
+ /* Update the vertex buffer binding */
+ effectiveStride = stride != 0 ? stride : array->_ElementSize;
+ bind_vertex_buffer(ctx, attrib, ctx->Array.ArrayBufferObj,
+ (GLintptr) ptr, effectiveStride);
}
@@ -473,7 +617,8 @@ _mesa_VertexAttribPointer(GLuint index, GLint size, GLenum type,
HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
FIXED_ES_BIT | FIXED_GL_BIT |
UNSIGNED_INT_2_10_10_10_REV_BIT |
- INT_2_10_10_10_REV_BIT);
+ INT_2_10_10_10_REV_BIT |
+ UNSIGNED_INT_10F_11F_11F_REV_BIT);
GET_CURRENT_CONTEXT(ctx);
if (index >= ctx->Const.VertexProgram.MaxAttribs) {
@@ -530,13 +675,14 @@ _mesa_EnableVertexAttribArray(GLuint index)
arrayObj = ctx->Array.ArrayObj;
- ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(arrayObj->VertexAttrib));
+ ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(arrayObj->_VertexAttrib));
if (!arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) {
/* was disabled, now being enabled */
FLUSH_VERTICES(ctx, _NEW_ARRAY);
arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_TRUE;
arrayObj->_Enabled |= VERT_BIT_GENERIC(index);
+ arrayObj->NewArrays |= VERT_BIT_GENERIC(index);
}
}
@@ -555,13 +701,14 @@ _mesa_DisableVertexAttribArray(GLuint index)
arrayObj = ctx->Array.ArrayObj;
- ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(arrayObj->VertexAttrib));
+ ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(arrayObj->_VertexAttrib));
if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) {
/* was enabled, now being disabled */
FLUSH_VERTICES(ctx, _NEW_ARRAY);
arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_FALSE;
arrayObj->_Enabled &= ~VERT_BIT_GENERIC(index);
+ arrayObj->NewArrays |= VERT_BIT_GENERIC(index);
}
}
@@ -575,16 +722,17 @@ static GLuint
get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname,
const char *caller)
{
- const struct gl_client_array *array;
+ const struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
+ const struct gl_vertex_attrib_array *array;
if (index >= ctx->Const.VertexProgram.MaxAttribs) {
_mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index);
return 0;
}
- ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));
+ ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(arrayObj->VertexAttrib));
- array = &ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)];
+ array = &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)];
switch (pname) {
case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
@@ -598,7 +746,7 @@ get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname,
case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
return array->Normalized;
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
- return array->BufferObj->Name;
+ return arrayObj->VertexBinding[array->VertexBinding].BufferObj->Name;
case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
if ((_mesa_is_desktop_gl(ctx)
&& (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))
@@ -609,7 +757,17 @@ get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname,
case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_instanced_arrays)
|| _mesa_is_gles3(ctx)) {
- return array->InstanceDivisor;
+ return arrayObj->VertexBinding[array->VertexBinding].InstanceDivisor;
+ }
+ goto error;
+ case GL_VERTEX_ATTRIB_BINDING:
+ if (_mesa_is_desktop_gl(ctx)) {
+ return array->VertexBinding - VERT_ATTRIB_GENERIC0;
+ }
+ goto error;
+ case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
+ if (_mesa_is_desktop_gl(ctx)) {
+ return array->RelativeOffset;
}
goto error;
default:
@@ -643,7 +801,7 @@ get_current_attrib(struct gl_context *ctx, GLuint index, const char *function)
return NULL;
}
- ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));
+ ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->_VertexAttrib));
FLUSH_CURRENT(ctx, 0);
return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)];
@@ -765,7 +923,7 @@ _mesa_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
return;
}
- ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));
+ ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->_VertexAttrib));
*pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
}
@@ -1141,9 +1299,10 @@ _mesa_PrimitiveRestartIndex(GLuint index)
void GLAPIENTRY
_mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
{
- struct gl_client_array *array;
GET_CURRENT_CONTEXT(ctx);
+ const GLuint genericIndex = VERT_ATTRIB_GENERIC(index);
+
if (!ctx->Extensions.ARB_instanced_arrays) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
return;
@@ -1155,13 +1314,21 @@ _mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
return;
}
- ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));
+ ASSERT(genericIndex < Elements(ctx->Array.ArrayObj->VertexAttrib));
- array = &ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)];
- if (array->InstanceDivisor != divisor) {
- FLUSH_VERTICES(ctx, _NEW_ARRAY);
- array->InstanceDivisor = divisor;
- }
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "The command
+ *
+ * void VertexAttribDivisor(uint index, uint divisor);
+ *
+ * is equivalent to (assuming no errors are generated):
+ *
+ * VertexAttribBinding(index, index);
+ * VertexBindingDivisor(index, divisor);"
+ */
+ vertex_attrib_binding(ctx, genericIndex, genericIndex);
+ vertex_binding_divisor(ctx, genericIndex, divisor);
}
@@ -1191,6 +1358,329 @@ _mesa_primitive_restart_index(const struct gl_context *ctx, GLenum ib_type)
/**
+ * GL_ARB_vertex_attrib_binding
+ */
+void GLAPIENTRY
+_mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset,
+ GLsizei stride)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
+ struct gl_buffer_object *vbo;
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "An INVALID_OPERATION error is generated if no vertex array object
+ * is bound."
+ */
+ if (ctx->API == API_OPENGL_CORE &&
+ ctx->Array.ArrayObj == ctx->Array.DefaultArrayObj) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBindVertexBuffer(No array object bound)");
+ return;
+ }
+
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "An INVALID_VALUE error is generated if <bindingindex> is greater than
+ * the value of MAX_VERTEX_ATTRIB_BINDINGS."
+ */
+ if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glBindVertexBuffer(bindingindex=%u > "
+ "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
+ bindingIndex);
+ return;
+ }
+
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "The error INVALID_VALUE is generated if <stride> or <offset>
+ * are negative."
+ */
+ if (offset < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glBindVertexBuffer(offset=%lld < 0)", (long long)offset);
+ return;
+ }
+
+ if (stride < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glBindVertexBuffer(stride=%d < 0)", stride);
+ return;
+ }
+
+ if (buffer == arrayObj->VertexBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj->Name) {
+ vbo = arrayObj->VertexBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj;
+ } else if (buffer != 0) {
+ vbo = _mesa_lookup_bufferobj(ctx, buffer);
+
+ /* From the GL_ARB_vertex_attrib_array spec:
+ *
+ * "[Core profile only:]
+ * An INVALID_OPERATION error is generated if buffer is not zero or a
+ * name returned from a previous call to GenBuffers, or if such a name
+ * has since been deleted with DeleteBuffers.
+ *
+ * Otherwise, we fall back to the same compat profile behavior as other
+ * object references (automatically gen it).
+ */
+ if (!_mesa_handle_bind_buffer_gen(ctx, GL_ARRAY_BUFFER, buffer,
+ &vbo, "glBindVertexBuffer"))
+ return;
+ } else {
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "If <buffer> is zero, any buffer object attached to this
+ * bindpoint is detached."
+ */
+ vbo = ctx->Shared->NullBufferObj;
+ }
+
+ bind_vertex_buffer(ctx, VERT_ATTRIB_GENERIC(bindingIndex),
+ vbo, offset, stride);
+}
+
+
+void GLAPIENTRY
+_mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type,
+ GLboolean normalized, GLuint relativeOffset)
+{
+ const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
+ SHORT_BIT | UNSIGNED_SHORT_BIT |
+ INT_BIT | UNSIGNED_INT_BIT |
+ HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
+ FIXED_GL_BIT |
+ UNSIGNED_INT_2_10_10_10_REV_BIT |
+ INT_2_10_10_10_REV_BIT |
+ UNSIGNED_INT_10F_11F_11F_REV_BIT);
+
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "An INVALID_OPERATION error is generated under any of the following
+ * conditions:
+ * - if no vertex array object is currently bound (see section 2.10);
+ * - ..."
+ */
+ if (ctx->API == API_OPENGL_CORE &&
+ ctx->Array.ArrayObj == ctx->Array.DefaultArrayObj) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glVertexAttribFormat(No array object bound)");
+ return;
+ }
+
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "The error INVALID_VALUE is generated if index is greater than or equal
+ * to the value of MAX_VERTEX_ATTRIBS."
+ */
+ if (attribIndex >= ctx->Const.VertexProgram.MaxAttribs) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glVertexAttribFormat(attribindex=%u > "
+ "GL_MAX_VERTEX_ATTRIBS)",
+ attribIndex);
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, 0);
+
+ update_array_format(ctx, "glVertexAttribFormat",
+ VERT_ATTRIB_GENERIC(attribIndex),
+ legalTypes, 1, BGRA_OR_4, size, type, normalized,
+ GL_FALSE, relativeOffset);
+}
+
+
+void GLAPIENTRY
+_mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type,
+ GLuint relativeOffset)
+{
+ const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
+ SHORT_BIT | UNSIGNED_SHORT_BIT |
+ INT_BIT | UNSIGNED_INT_BIT);
+
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "An INVALID_OPERATION error is generated under any of the following
+ * conditions:
+ * - if no vertex array object is currently bound (see section 2.10);
+ * - ..."
+ */
+ if (ctx->API == API_OPENGL_CORE &&
+ ctx->Array.ArrayObj == ctx->Array.DefaultArrayObj) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glVertexAttribIFormat(No array object bound)");
+ return;
+ }
+
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "The error INVALID_VALUE is generated if index is greater than
+ * or equal to the value of MAX_VERTEX_ATTRIBS."
+ */
+ if (attribIndex >= ctx->Const.VertexProgram.MaxAttribs) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glVertexAttribIFormat(attribindex=%u > "
+ "GL_MAX_VERTEX_ATTRIBS)",
+ attribIndex);
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, 0);
+
+ update_array_format(ctx, "glVertexAttribIFormat",
+ VERT_ATTRIB_GENERIC(attribIndex),
+ legalTypes, 1, 4, size, type, GL_FALSE, GL_TRUE,
+ relativeOffset);
+}
+
+
+void GLAPIENTRY
+_mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type,
+ GLuint relativeOffset)
+{
+ const GLbitfield legalTypes = DOUBLE_BIT;
+
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ /* 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:
+ * • if no vertex array object is currently bound (see section 10.4);
+ * • ..."
+ *
+ * This language is missing from the extension spec, but we assume
+ * that this is an oversight.
+ */
+ if (ctx->API == API_OPENGL_CORE &&
+ ctx->Array.ArrayObj == ctx->Array.DefaultArrayObj) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glVertexAttribLFormat(No array object bound)");
+ return;
+ }
+
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "The error INVALID_VALUE is generated if <attribindex> is greater than
+ * or equal to the value of MAX_VERTEX_ATTRIBS."
+ */
+ if (attribIndex >= ctx->Const.VertexProgram.MaxAttribs) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glVertexAttribLFormat(attribindex=%u > "
+ "GL_MAX_VERTEX_ATTRIBS)",
+ attribIndex);
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, 0);
+
+ update_array_format(ctx, "glVertexAttribLFormat",
+ VERT_ATTRIB_GENERIC(attribIndex),
+ legalTypes, 1, 4, size, type, GL_FALSE, GL_FALSE,
+ relativeOffset);
+}
+
+
+void GLAPIENTRY
+_mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "An INVALID_OPERATION error is generated if no vertex array object
+ * is bound."
+ */
+ if (ctx->API == API_OPENGL_CORE &&
+ ctx->Array.ArrayObj == ctx->Array.DefaultArrayObj) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glVertexAttribBinding(No array object bound)");
+ return;
+ }
+
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "<attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and
+ * <bindingindex> must be less than the value of
+ * MAX_VERTEX_ATTRIB_BINDINGS, otherwise the error INVALID_VALUE
+ * is generated."
+ */
+ if (attribIndex >= ctx->Const.VertexProgram.MaxAttribs) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glVertexAttribBinding(attribindex=%u >= "
+ "GL_MAX_VERTEX_ATTRIBS)",
+ attribIndex);
+ return;
+ }
+
+ if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glVertexAttribBinding(bindingindex=%u >= "
+ "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
+ bindingIndex);
+ return;
+ }
+
+ ASSERT(VERT_ATTRIB_GENERIC(attribIndex) <
+ Elements(ctx->Array.ArrayObj->VertexAttrib));
+
+ vertex_attrib_binding(ctx, VERT_ATTRIB_GENERIC(attribIndex),
+ VERT_ATTRIB_GENERIC(bindingIndex));
+}
+
+
+void GLAPIENTRY
+_mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.ARB_instanced_arrays) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexBindingDivisor()");
+ return;
+ }
+
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "An INVALID_OPERATION error is generated if no vertex array object
+ * is bound."
+ */
+ if (ctx->API == API_OPENGL_CORE &&
+ ctx->Array.ArrayObj == ctx->Array.DefaultArrayObj) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glVertexBindingDivisor(No array object bound)");
+ return;
+ }
+
+ /* The ARB_vertex_attrib_binding spec says:
+ *
+ * "An INVALID_VALUE error is generated if <bindingindex> is greater
+ * than or equal to the value of MAX_VERTEX_ATTRIB_BINDINGS."
+ */
+ if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glVertexBindingDivisor(bindingindex=%u > "
+ "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
+ bindingIndex);
+ return;
+ }
+
+ vertex_binding_divisor(ctx, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
+}
+
+
+/**
* Copy one client vertex array to another.
*/
void
@@ -1213,7 +1703,36 @@ _mesa_copy_client_array(struct gl_context *ctx,
dst->_MaxElement = src->_MaxElement;
}
+void
+_mesa_copy_vertex_attrib_array(struct gl_context *ctx,
+ struct gl_vertex_attrib_array *dst,
+ const struct gl_vertex_attrib_array *src)
+{
+ dst->Size = src->Size;
+ dst->Type = src->Type;
+ dst->Format = src->Format;
+ dst->VertexBinding = src->VertexBinding;
+ dst->RelativeOffset = src->RelativeOffset;
+ dst->Format = src->Format;
+ dst->Integer = src->Integer;
+ dst->Normalized = src->Normalized;
+ dst->Ptr = src->Ptr;
+ dst->Enabled = src->Enabled;
+ dst->_ElementSize = src->_ElementSize;
+}
+void
+_mesa_copy_vertex_buffer_binding(struct gl_context *ctx,
+ struct gl_vertex_buffer_binding *dst,
+ const struct gl_vertex_buffer_binding *src)
+{
+ dst->Offset = src->Offset;
+ dst->Stride = src->Stride;
+ dst->InstanceDivisor = src->InstanceDivisor;
+ dst->_BoundArrays = src->_BoundArrays;
+
+ _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
+}
/**
* Print vertex array's fields.
@@ -1245,18 +1764,18 @@ _mesa_print_arrays(struct gl_context *ctx)
_mesa_update_array_object_max_element(ctx, arrayObj);
printf("Array Object %u\n", arrayObj->Name);
- if (arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled)
- print_array("Vertex", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]);
- if (arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled)
- print_array("Normal", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]);
- if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled)
- print_array("Color", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]);
+ if (arrayObj->_VertexAttrib[VERT_ATTRIB_POS].Enabled)
+ print_array("Vertex", -1, &arrayObj->_VertexAttrib[VERT_ATTRIB_POS]);
+ if (arrayObj->_VertexAttrib[VERT_ATTRIB_NORMAL].Enabled)
+ print_array("Normal", -1, &arrayObj->_VertexAttrib[VERT_ATTRIB_NORMAL]);
+ if (arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR0].Enabled)
+ print_array("Color", -1, &arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR0]);
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
- if (arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)].Enabled)
- print_array("TexCoord", i, &arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)]);
+ if (arrayObj->_VertexAttrib[VERT_ATTRIB_TEX(i)].Enabled)
+ print_array("TexCoord", i, &arrayObj->_VertexAttrib[VERT_ATTRIB_TEX(i)]);
for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++)
- if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
- print_array("Attrib", i, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)]);
+ if (arrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
+ print_array("Attrib", i, &arrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC(i)]);
printf(" _MaxElement = %u\n", arrayObj->_MaxElement);
}
diff --git a/mesalib/src/mesa/main/varray.h b/mesalib/src/mesa/main/varray.h
index 7e611e8c7..8a9487c6e 100644
--- a/mesalib/src/mesa/main/varray.h
+++ b/mesalib/src/mesa/main/varray.h
@@ -29,6 +29,7 @@
#include "glheader.h"
+#include "bufferobj.h"
struct gl_client_array;
struct gl_context;
@@ -50,8 +51,10 @@ _mesa_update_array_max_element(struct gl_client_array *array)
GLsizeiptrARB bufSize = (GLsizeiptrARB) array->BufferObj->Size;
if (offset < bufSize) {
- array->_MaxElement = (bufSize - offset + array->StrideB
- - array->_ElementSize) / array->StrideB;
+ const GLuint stride = array->StrideB ?
+ array->StrideB : array->_ElementSize;
+ array->_MaxElement = (bufSize - offset + stride
+ - array->_ElementSize) / stride;
}
else {
array->_MaxElement = 0;
@@ -64,6 +67,44 @@ _mesa_update_array_max_element(struct gl_client_array *array)
}
+/**
+ * Returns a pointer to the vertex attribute data in a client array,
+ * or the offset into the vertex buffer for an array that resides in
+ * a vertex buffer.
+ */
+static inline const GLubyte *
+_mesa_vertex_attrib_address(struct gl_vertex_attrib_array *array,
+ struct gl_vertex_buffer_binding *binding)
+{
+ return (binding->BufferObj->Name == 0 ?
+ array->Ptr :
+ (const GLubyte *)(binding->Offset + array->RelativeOffset));
+}
+
+/**
+ * Sets the fields in a gl_client_array to values derived from a
+ * gl_vertex_attrib_array and a gl_vertex_buffer_binding.
+ */
+static inline void
+_mesa_update_client_array(struct gl_context *ctx,
+ struct gl_client_array *dst,
+ struct gl_vertex_attrib_array *src,
+ struct gl_vertex_buffer_binding *binding)
+{
+ dst->Size = src->Size;
+ dst->Type = src->Type;
+ dst->Format = src->Format;
+ dst->Stride = src->Stride;
+ dst->StrideB = binding->Stride;
+ dst->Ptr = _mesa_vertex_attrib_address(src, binding);
+ dst->Enabled = src->Enabled;
+ dst->Normalized = src->Normalized;
+ dst->Integer = src->Integer;
+ dst->InstanceDivisor = binding->InstanceDivisor;
+ dst->_ElementSize = src->_ElementSize;
+ _mesa_reference_buffer_object(ctx, &dst->BufferObj, binding->BufferObj);
+}
+
extern void GLAPIENTRY
_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride,
const GLvoid *ptr);
@@ -250,11 +291,43 @@ _mesa_VertexAttribDivisor(GLuint index, GLuint divisor);
extern unsigned
_mesa_primitive_restart_index(const struct gl_context *ctx, GLenum ib_type);
+extern void GLAPIENTRY
+_mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset,
+ GLsizei stride);
+
+extern void GLAPIENTRY
+_mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type,
+ GLboolean normalized, GLuint relativeOffset);
+
+extern void GLAPIENTRY
+_mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type,
+ GLuint relativeOffset);
+
+extern void GLAPIENTRY
+_mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type,
+ GLuint relativeOffset);
+
+extern void GLAPIENTRY
+_mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex);
+
+extern void GLAPIENTRY
+_mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor);
+
+
extern void
_mesa_copy_client_array(struct gl_context *ctx,
struct gl_client_array *dst,
struct gl_client_array *src);
+extern void
+_mesa_copy_vertex_attrib_array(struct gl_context *ctx,
+ struct gl_vertex_attrib_array *dst,
+ const struct gl_vertex_attrib_array *src);
+
+extern void
+_mesa_copy_vertex_buffer_binding(struct gl_context *ctx,
+ struct gl_vertex_buffer_binding *dst,
+ const struct gl_vertex_buffer_binding *src);
extern void
_mesa_print_arrays(struct gl_context *ctx);
diff --git a/mesalib/src/mesa/state_tracker/st_atom_array.c b/mesalib/src/mesa/state_tracker/st_atom_array.c
index 87a0a17f1..76a94bcf8 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_array.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_array.c
@@ -214,7 +214,8 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
assert((type >= GL_BYTE && type <= GL_DOUBLE) ||
type == GL_FIXED || type == GL_HALF_FLOAT ||
type == GL_INT_2_10_10_10_REV ||
- type == GL_UNSIGNED_INT_2_10_10_10_REV);
+ type == GL_UNSIGNED_INT_2_10_10_10_REV ||
+ type == GL_UNSIGNED_INT_10F_11F_11F_REV);
assert(size >= 1);
assert(size <= 4);
assert(format == GL_RGBA || format == GL_BGRA);
@@ -251,6 +252,14 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
}
}
+ if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) {
+ assert(size == 3);
+ assert(!integer);
+ assert(format == GL_RGBA);
+
+ return PIPE_FORMAT_R11G11B10_FLOAT;
+ }
+
if (format == GL_BGRA) {
/* this is an odd-ball case */
assert(type == GL_UNSIGNED_BYTE);
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index 97c5d55e1..e8d0902d9 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -507,6 +507,8 @@ void st_init_extensions(struct st_context *st)
PIPE_FORMAT_B10G10R10A2_USCALED,
PIPE_FORMAT_R10G10B10A2_SSCALED,
PIPE_FORMAT_B10G10R10A2_SSCALED } },
+ { { o(ARB_vertex_type_10f_11f_11f_rev) },
+ { PIPE_FORMAT_R11G11B10_FLOAT } },
};
static const struct st_extension_format_mapping tbo_rgb32[] = {
diff --git a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h
index bbc020539..358d12d15 100644
--- a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h
+++ b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h
@@ -25,6 +25,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
+#include "util/u_format_r11g11b10f.h"
+
/* float */
#define ATTR1FV( A, V ) ATTR( A, 1, GL_FLOAT, (V)[0], 0, 0, 1 )
#define ATTR2FV( A, V ) ATTR( A, 2, GL_FLOAT, (V)[0], (V)[1], 0, 1 )
@@ -205,6 +207,10 @@ static inline float conv_i2_to_norm_float(const struct gl_context *ctx, int i2)
} else { \
ATTRI10_##val((attr), (arg)); \
} \
+ } else if ((type) == GL_UNSIGNED_INT_10F_11F_11F_REV) { \
+ float res[4]; \
+ r11g11b10f_to_float3((arg), res); \
+ ATTR##val##FV((attr), res); \
} else \
ERROR(GL_INVALID_VALUE); \
} while(0)
@@ -835,12 +841,26 @@ TAG(VertexAttrib4fvNV)(GLuint index, const GLfloat * v)
ATTR4FV(index, v);
}
+
#define ERROR_IF_NOT_PACKED_TYPE(ctx, type, func) \
if (type != GL_INT_2_10_10_10_REV && type != GL_UNSIGNED_INT_2_10_10_10_REV) { \
_mesa_error(ctx, GL_INVALID_ENUM, "%s(type)", func); \
return; \
}
+/* Extended version of ERROR_IF_NOT_PACKED_TYPE which also
+ * accepts GL_UNSIGNED_INT_10F_11F_11F_REV.
+ *
+ * Only used for VertexAttribP[123]ui[v]; VertexAttribP4* cannot use this type,
+ * and neither can legacy vertex attribs.
+ */
+#define ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, func) \
+ if (type != GL_INT_2_10_10_10_REV && type != GL_UNSIGNED_INT_2_10_10_10_REV && \
+ type != GL_UNSIGNED_INT_10F_11F_11F_REV) { \
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(type)", func); \
+ return; \
+ }
+
static void GLAPIENTRY
TAG(VertexP2ui)(GLenum type, GLuint value)
{
@@ -1094,7 +1114,7 @@ TAG(VertexAttribP1ui)(GLuint index, GLenum type, GLboolean normalized,
GLuint value)
{
GET_CURRENT_CONTEXT(ctx);
- ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP1ui");
+ ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, "glVertexAttribP1ui");
ATTR_UI_INDEX(ctx, 1, type, normalized, index, value);
}
@@ -1103,7 +1123,7 @@ TAG(VertexAttribP2ui)(GLuint index, GLenum type, GLboolean normalized,
GLuint value)
{
GET_CURRENT_CONTEXT(ctx);
- ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP2ui");
+ ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, "glVertexAttribP2ui");
ATTR_UI_INDEX(ctx, 2, type, normalized, index, value);
}
@@ -1112,7 +1132,7 @@ TAG(VertexAttribP3ui)(GLuint index, GLenum type, GLboolean normalized,
GLuint value)
{
GET_CURRENT_CONTEXT(ctx);
- ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP3ui");
+ ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, "glVertexAttribP3ui");
ATTR_UI_INDEX(ctx, 3, type, normalized, index, value);
}
@@ -1130,7 +1150,7 @@ TAG(VertexAttribP1uiv)(GLuint index, GLenum type, GLboolean normalized,
const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
- ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP1uiv");
+ ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, "glVertexAttribP1uiv");
ATTR_UI_INDEX(ctx, 1, type, normalized, index, *value);
}
@@ -1139,7 +1159,7 @@ TAG(VertexAttribP2uiv)(GLuint index, GLenum type, GLboolean normalized,
const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
- ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP2uiv");
+ ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, "glVertexAttribP2uiv");
ATTR_UI_INDEX(ctx, 2, type, normalized, index, *value);
}
@@ -1148,7 +1168,7 @@ TAG(VertexAttribP3uiv)(GLuint index, GLenum type, GLboolean normalized,
const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
- ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP3uiv");
+ ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, "glVertexAttribP3uiv");
ATTR_UI_INDEX(ctx, 3, type, normalized, index, *value);
}
diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c
index f25a9dec3..d72382376 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_array.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_array.c
@@ -318,8 +318,8 @@ check_draw_elements_data(struct gl_context *ctx, GLsizei count, GLenum elemType,
}
/* check element j of each enabled array */
- for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) {
- check_array_data(ctx, &arrayObj->VertexAttrib[k], k, j);
+ for (k = 0; k < Elements(arrayObj->_VertexAttrib); k++) {
+ check_array_data(ctx, &arrayObj->_VertexAttrib[k], k, j);
}
}
@@ -327,8 +327,8 @@ check_draw_elements_data(struct gl_context *ctx, GLsizei count, GLenum elemType,
ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj);
}
- for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) {
- unmap_array_buffer(ctx, &arrayObj->VertexAttrib[k]);
+ for (k = 0; k < Elements(arrayObj->_VertexAttrib); k++) {
+ unmap_array_buffer(ctx, &arrayObj->_VertexAttrib[k]);
}
}
@@ -368,7 +368,7 @@ print_draw_arrays(struct gl_context *ctx,
exec->array.inputs[i]->Size,
stride,
/*exec->array.inputs[i]->Enabled,*/
- arrayObj->VertexAttrib[VERT_ATTRIB_FF(i)].Enabled,
+ arrayObj->_VertexAttrib[VERT_ATTRIB_FF(i)].Enabled,
exec->array.inputs[i]->Ptr,
bufName);
@@ -405,7 +405,7 @@ recalculate_input_bindings(struct gl_context *ctx)
{
struct vbo_context *vbo = vbo_context(ctx);
struct vbo_exec_context *exec = &vbo->exec;
- struct gl_client_array *vertexAttrib = ctx->Array.ArrayObj->VertexAttrib;
+ struct gl_client_array *vertexAttrib = ctx->Array.ArrayObj->_VertexAttrib;
const struct gl_client_array **inputs = &exec->array.inputs[0];
GLbitfield64 const_inputs = 0x0;
GLuint i;
diff --git a/mesalib/src/mesa/x86/Makefile.am b/mesalib/src/mesa/x86/Makefile.am
deleted file mode 100644
index 167857684..000000000
--- a/mesalib/src/mesa/x86/Makefile.am
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright © 2012 Intel Corporation
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the "Software"),
-# to deal in the Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish, distribute, sublicense,
-# and/or sell copies of the Software, and to permit persons to whom the
-# Software is furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice (including the next
-# paragraph) shall be included in all copies or substantial portions of the
-# Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-if HAVE_X86_ASM
-
-AM_CPPFLAGS = \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/src/mesa \
- -I$(top_srcdir)/src/mapi \
- $(DEFINES)
-
-noinst_PROGRAMS = gen_matypes
-
-gen_matypes_SOURCES = gen_matypes.c
-BUILT_SOURCES = matypes.h
-CLEANFILES = matypes.h
-
-if GEN_ASM_OFFSETS
-
-matypes.h: $(gen_matypes_SOURCES)
- $(AM_V_GEN)$(COMPILE) $< -DASM_OFFSETS -S -o - | \
- sed -n '/^->/{s:^->::;/[$$]/{s:^:#define :;s:[$$]::};p}' > $@
-
-else
-
-matypes.h: gen_matypes
- $(AM_V_GEN)./gen_matypes > $@
-
-endif
-
-endif